
How to Limit and Manage Post Revisions in WordPress?
Every time you click Save or Update on a WordPress post, the previous version is kept as a revision. That safety net has saved countless articles from accidental deletions and bad edits. On a long-running site, though, it adds up. A post edited two hundred times has two hundred copies of its full content in the database. Multiply that across thousands of posts and pages, and revisions can make up most of the wp_posts table, slowing backups, migrations, and some admin queries.
The answer is not to turn revisions off. It is to keep enough history to recover from mistakes, cap the rest, and clean up what has already piled up.
This article covers how revisions and autosaves work and where they are stored, how to limit them globally with WP_POST_REVISIONS and per post type with filters, how to change the autosave interval, how to compare and restore revisions in the editor, how to delete old revisions with WP-CLI, SQL, or a plugin, and how revisions apply to custom post types, post meta, and the Site Editor.
How Revisions and Autosaves Work
WordPress stores revisions as rows in the wp_posts table with:
post_typeset torevisionpost_statusset toinheritpost_parentset to the ID of the original postpost_nameset to something like123-revision-v1
Each revision stores the title, content, and excerpt at the moment of the save. A new revision is only created when one of those fields has actually changed, so clicking Update without editing does not add a copy.
Autosaves are a special kind of revision. While you edit, WordPress automatically saves your unsaved changes every 60 seconds by default. There is at most one autosave per user per post, with a post_name like 123-autosave-v1, and it is overwritten each time. If your browser crashes, WordPress offers to restore the autosave the next time you open the post.
| Type | Created when | How many kept | Purpose |
|---|---|---|---|
| Revision | You save, update, or publish with changes | Unlimited by default | History and rollback |
| Autosave | Automatically while editing | One per user per post | Crash and tab-close recovery |
Revisions only apply to post types that support them. Posts and pages do by default. Custom post types need revisions in their supports list.
Checking How Many Revisions You Have
Before changing anything, find out whether revisions are actually a problem. With WP-CLI:
# Terminal
wp post list --post_type=revision --format=count
wp post list --post_type=post,page --post_status=publish --format=count
Or with SQL, which also shows the posts with the most revisions. Replace wp_ with your table prefix:
-- Total revisions
SELECT COUNT(*) FROM wp_posts WHERE post_type = 'revision';
-- Posts with the most revisions
SELECT post_parent, COUNT(*) AS revisions
FROM wp_posts
WHERE post_type = 'revision'
GROUP BY post_parent
ORDER BY revisions DESC
LIMIT 20;
A few thousand revisions on a site with a few hundred posts is harmless. Hundreds of thousands, or revisions outnumbering published content by ten to one or more, is worth cleaning up.
Limiting Revisions with WP_POST_REVISIONS
The simplest control is a constant in wp-config.php. Add it above the "That's all, stop editing!" line:
// wp-config.php
define( 'WP_POST_REVISIONS', 10 );
The constant accepts three kinds of value:
| Value | Effect |
|---|---|
true or -1 | Keep unlimited revisions (the default) |
| A positive integer | Keep at most that many revisions per post |
false or 0 | Do not store revisions. Autosaves still work |
Ten to twenty revisions is a reasonable limit for most sites. It covers recent mistakes without storing every typo fix from years ago.
Two details are easy to miss:
- The limit is enforced on the next save. Setting
WP_POST_REVISIONSto 10 does not delete existing revisions. The next time a post is updated, WordPress deletes that post's oldest revisions beyond the limit. Posts that are never edited again keep all their revisions until you clean them up. - Disabling revisions does not disable autosave. Setting the constant to
falsestops new revisions, but autosaves are still created so unsaved work can be recovered.
Limiting Revisions per Post Type with Filters
A single global number does not suit every content type. A legal page might need full history, while a frequently updated product listing needs very little. Two filters override the constant.
The wp_revisions_to_keep filter applies to every post type:
// wp-content/mu-plugins/revision-limits.php
<?php
/**
* Plugin Name: Revision Limits
* Description: Sets revision limits per post type.
*/
add_filter( 'wp_revisions_to_keep', function ( $num, $post ) {
switch ( $post->post_type ) {
case 'page':
return 30;
case 'product':
return 5;
default:
return $num; // Fall back to WP_POST_REVISIONS.
}
}, 10, 2 );
Since WordPress 5.8, a dynamic filter, wp_{$post_type}_revisions_to_keep, targets a single post type and runs after wp_revisions_to_keep, so it takes precedence:
// wp-content/mu-plugins/revision-limits.php
add_filter( 'wp_page_revisions_to_keep', function () {
return 30;
} );
add_filter( 'wp_product_revisions_to_keep', function () {
return 5;
} );
Putting this code in a must-use plugin, rather than the theme's functions.php, means the limits stay in place when you switch themes.
Changing the Autosave Interval
The AUTOSAVE_INTERVAL constant controls how often autosaves run, in seconds. The default is 60:
// wp-config.php
define( 'AUTOSAVE_INTERVAL', 120 );
A longer interval means fewer requests while editing, at the cost of potentially losing more unsaved work after a crash. Since only one autosave per user per post is stored, this setting affects server requests more than database size. Leaving it at 60 seconds is fine for most sites.
Comparing and Restoring Revisions
Revisions are only useful if you know how to get content back.
In the Block Editor
- Open the post or page.
- In the Post tab of the settings sidebar, click Revisions. The number shows how many are stored. If you do not see it, the post has no revisions yet.
- The revisions screen opens. Drag the slider at the top to move through versions. Removed text is highlighted in red and added text in green.
- Tick Compare any two revisions to compare two older versions instead of each version with the one before it.
- Click Restore This Revision to make the selected version the current content.
Restoring does not delete newer revisions. WordPress saves the current content as a new revision before replacing it, so you can undo a restore.
Autosave Recovery
If an autosave is newer than the saved post, the editor displays a notice offering to restore it. Click View the autosave to compare and restore. This happens automatically when you reopen a post after a crash or closed tab.
What Revisions Do Not Cover
By default, revisions store the title, content, and excerpt. They do not store featured images, categories and tags, or most custom fields. If you restore an old revision, those other properties stay as they currently are. To protect everything, rely on full backups as well as revisions. See how to create a backup for a WordPress website.
Revisions for Custom Post Types and Post Meta
Custom post types only get revisions when revisions is in their supports array:
// wp-content/plugins/acme-docs/acme-docs.php
add_action( 'init', function () {
register_post_type( 'acme_doc', array(
'label' => __( 'Docs', 'acme-docs' ),
'public' => true,
'show_in_rest' => true,
'supports' => array( 'title', 'editor', 'excerpt', 'revisions', 'custom-fields' ),
) );
} );
Since WordPress 6.4, individual post meta fields can be revisioned too. Register the meta key with revisions_enabled, and its value is saved with each revision and restored with it:
// wp-content/plugins/acme-docs/acme-docs.php
add_action( 'init', function () {
register_post_meta( 'acme_doc', 'acme_version_note', array(
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'revisions_enabled' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => function () {
return current_user_can( 'edit_posts' );
},
) );
} );
The post type must support revisions for this to work. Building custom post types from scratch is covered in how to create a custom post type in WordPress.
Site Editor Revisions
Block themes keep revisions for content edited in the Site Editor as well. Changes to global styles, templates, and template parts are stored as revisions of their own records, and you can browse and restore them from the Site Editor. Revision limits from the filters above can apply to those post types too, such as wp_template and wp_global_styles, so be careful not to set them to zero.
Cleaning Up Old Revisions
Limiting revisions stops future growth. Cleaning up removes what is already there. Back up the database before deleting anything.
With WP-CLI
WP-CLI does not have a dedicated command for revisions in core, but wp post list and wp post delete handle the job. Revisions cannot be moved to the trash, so --force is required.
Delete every revision on the site:
# Terminal
wp db export before-revision-cleanup.sql
wp post list --post_type=revision --format=ids \
| xargs -r -n 500 wp post delete --force
Piping the IDs through xargs in batches of 500 avoids "argument list too long" errors on large sites. Each deletion goes through wp_delete_post(), which also removes the revision's metadata.
To keep the most recent revisions for each post instead of deleting all of them, loop over the parent posts:
#!/usr/bin/env bash
# scripts/trim-revisions.sh
# Keeps the newest KEEP revisions for every post, page, and custom post type entry.
set -euo pipefail
KEEP=${1:-5}
for parent in $(wp db query \
"SELECT DISTINCT post_parent FROM $(wp db prefix)posts WHERE post_type = 'revision'" \
--skip-column-names); do
ids=$(wp post list --post_type=revision --post_parent="$parent" \
--orderby=date --order=DESC --posts_per_page=-1 --format=ids)
old=$(echo "$ids" | tr ' ' '\n' | tail -n +$((KEEP + 1)) | tr '\n' ' ')
if [ -n "${old// /}" ]; then
wp post delete $old --force --quiet
fi
done
Run it with bash scripts/trim-revisions.sh 5 from the WordPress directory. This approach is slower than SQL but uses WordPress's own deletion functions, so hooks fire and related data is cleaned up correctly. More WP-CLI techniques are in how to use WP-CLI to manage WordPress.
The community package wp-revisions-cli adds a wp revisions command with listing and cleanup options. Install it with wp package install trepmal/wp-revisions-cli if you prefer a ready-made tool, and check its documentation for the current options.
With SQL
On very large sites, SQL is much faster. It bypasses WordPress hooks, so it must also delete the revisions' metadata. Run these statements in order, after a backup, and replace wp_ with your prefix:
-- 1. Remove metadata belonging to revisions
DELETE pm
FROM wp_postmeta pm
INNER JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.post_type = 'revision';
-- 2. Remove term relationships belonging to revisions (normally none)
DELETE tr
FROM wp_term_relationships tr
INNER JOIN wp_posts p ON p.ID = tr.object_id
WHERE p.post_type = 'revision';
-- 3. Remove the revisions themselves
DELETE FROM wp_posts WHERE post_type = 'revision';
This deletes every revision. Autosaves are also stored with post_type = 'revision', so unsaved autosaves are removed too. Ask editors to save their work before you run it. After a large cleanup, OPTIMIZE TABLE wp_posts; can reclaim disk space on some storage engines, but it locks the table while it runs, so schedule it for a quiet period.
With a Plugin
If you are not comfortable with the command line, database cleanup plugins such as WP-Optimize and Advanced Database Cleaner can delete revisions from the dashboard, often with an option to keep the latest few per post. They are convenient for one-off cleanups. Remove or disable scheduled cleanups you do not need, and always back up first. Broader database maintenance is covered in how to clean up and optimize the WordPress database.
Choosing the Right Revision Strategy
| Site type | Suggested limit | Why |
|---|---|---|
| Personal blog | 5–10 | Enough to undo recent mistakes |
| Business site with a few editors | 10–20 | Covers review cycles and accidental overwrites |
| Newsroom or multi-author magazine | 20–50 | Editorial accountability and frequent edits |
| Regulated or legal content | Unlimited for key types | Full audit trail, limited by post type |
| Ecommerce products | 3–5 for products | Frequent automated updates create many copies |
Use the per-post-type filters to combine these. A site can keep unlimited revisions for legal pages and five for products.
Common Problems and Fixes
- The Revisions option does not appear in the editor. The post has no revisions yet, the post type does not support revisions, or
WP_POST_REVISIONSis set tofalseor0. - Old revisions are still there after setting a limit. The limit is applied only when a post is saved. Clean up existing revisions with WP-CLI, SQL, or a plugin.
WP_POST_REVISIONShas no effect. The constant is defined afterwp-settings.phpis loaded, or a plugin or theme uses thewp_revisions_to_keepfilter to override it. Move the constant up and search your code for the filter.- A restored revision is missing its featured image or custom fields. Revisions only store title, content, and excerpt by default. Register important meta with
revisions_enabled, and keep regular backups. - "Argument list too long" when deleting revisions with WP-CLI. Pass IDs in batches with
xargs -n 500.
Post Revisions FAQ
For most visitors, no. Front-end queries ignore revisions. Very large numbers of revisions can slow some admin screens, increase database size, and make backups and migrations take longer, which is why limiting and cleaning them up is worthwhile.
Usually not. Revisions are the quickest way to recover from accidental deletions and bad edits. Limit them to a sensible number instead, such as 10 to 20 per post, so you keep recent history without unlimited growth.
No. The limit is applied when a post is next saved, at which point WordPress removes that post's oldest revisions beyond the limit. Posts that are not edited keep their revisions until you clean them up manually.
Autosaves are stored as revisions in the database but are handled separately. Only one autosave is kept per user per post, it is overwritten each time, and WordPress never deletes it when trimming revisions to the limit.
Not from WordPress itself. Once a revision is deleted it is gone, so the only way to recover it is from a database backup. Always take a backup before bulk-deleting revisions.
Conclusion
Post revisions are one of WordPress's most useful safety features, and one of the easiest to let grow out of control. Set a sensible global limit with WP_POST_REVISIONS, refine it per post type with wp_revisions_to_keep or wp_{$post_type}_revisions_to_keep, and keep autosave running so unsaved work is never lost.
Then clean up the history that has already built up, using WP-CLI when you want WordPress to handle the deletion correctly, SQL when speed matters on a very large site, or a plugin if you prefer the dashboard. Back up first every time. Finally, remember what revisions do not cover, and keep full backups for everything else.
Here are some useful references for going deeper on post revisions:
- WordPress Documentation: Revisions — comparing and restoring revisions in the editor.
- WordPress Developer Docs: Editing wp-config.php —
WP_POST_REVISIONS,AUTOSAVE_INTERVAL, and other constants. - WordPress Developer Docs: wp_revisions_to_keep filter — overriding the revision limit in code.
- WordPress Developer Docs: register_meta() — the
revisions_enabledargument for revisioned post meta. - WP-CLI Docs: wp post delete — deleting posts and revisions from the command line.


