Post Revisions (changes)
Revisions are versions of content created when updating a post and during auto-saving.
General information
In WP there are Auto-drafts - these are posts that are created automatically when opening the post creation page - at that moment an auto-draft is created - post_status = auto-draft and on the first save it becomes a normal draft - post_status = draft.
Such a draft is not a revision - it is a technical post for temporary data storage until the first save.
There are two types of revisions:
-
Revisions — created when saving a post if there are changes in the content (or other significant fields).
- Auto-saves — created once every 60 seconds in the editor (one per user).
Revisions are stored as separate posts in the wp_posts table with post_type = 'revision' and post_status = inherit.
Revisions are linked to the original post via the post_parent field.
In multisite the constant in wp-config.php applies to the entire network; revisions are stored separately in each site's tables.
There is a myth that disabling revisions speeds up the site. Revisions are not involved in frontend queries - there will be no speed gain. The only increase is in DB size.
Important fields in the wp_posts table
Revisions:
post_type = revision post_status = inherit post_parent = 123 post_name = 123-revision-v1 post_date = 2025-03-13 08:24:05
post_name = {parent_post_id}-revision-v1, where v1 here is the revision system version.
Example:
+-------+-----------+-------------+-------------+-------------+---------------------+ | ID | post_type | post_status | post_parent | post_author | post_date | +-------+-----------+-------------+-------------+-------------+---------------------+ | 14385 | revision | inherit | 14332 | 1 | 2024-08-24 13:00:39 | | 14393 | revision | inherit | 14384 | 1 | 2024-08-24 13:24:23 | | 14394 | revision | inherit | 14384 | 1 | 2024-08-24 13:24:39 | +-------+-----------+-------------+-------------+-------------+---------------------+
Autosaves:
post_type = revision post_status = inherit post_parent = 123 post_name = 123-autosave-v1 post_date = 2025-03-13 08:24:05
post_name = {parent_post_id}-autosave-v1, where v1 is the revision system version.
Example:
+-------+-----------+-------------+-------------+-------------+---------------------+ | ID | post_type | post_status | post_parent | post_author | post_date | +-------+-----------+-------------+-------------+-------------+---------------------+ | 14722 | revision | inherit | 14139 | 11 | 2024-10-16 09:51:11 | | 58093 | revision | inherit | 54997 | 1 | 2025-03-13 08:24:05 | +-------+-----------+-------------+-------------+-------------+---------------------+
Revisions (classic)
A revision is created on save if there are changes in significant fields (post_title, post_content, post_excerpt). Significant fields are defined by the function _wp_post_revision_data() and can be changed via the hook _wp_post_revision_fields.
By default, revisions are created by the function wp_save_post_revision(), which is hooked to post_updated:
add_action( 'post_updated', 'wp_save_post_revision', 10, 1 );
You can adjust the check whether the post has changed (whether to add a revision) with the filter wp_save_post_revision_post_has_changed
Autosaves
Autosaves are a separate kind of revision that core creates/recognizes as an autosave and treats differently.
They differ by the post_name field. Formats of this field:
// autosaves
{parent_post_id}-autosave-v1
// revisions
{parent_post_id}-revision-v1
See more:
The WP_POST_REVISIONS limit does not apply to Autosaves.
Autosave interval
An autosave is created approximately every 60 seconds in the editor. One current autosave per user per post.
In wp-config.php there is a constant AUTOSAVE_INTERVAL:
define( 'AUTOSAVE_INTERVAL', 60 ); // seconds
0 - will disable autosaves.
Comments, taxonomies and meta-fields in revisions
By default revisions do not store any data except some data from the wp_posts table. That is:
- Taxonomies - none.
- Comments - none.
- Meta-fields - none (by default). But technically they can be attached, however core does not create them, copy them from the parent or restore them on rollback. See _wp_post_revision_fields()
How to disable/limit revisions
Globally via wp-config.php:
define( 'WP_POST_REVISIONS', true ); // unlimited define( 'WP_POST_REVISIONS', 10 ); // keep no more than 10 define( 'WP_POST_REVISIONS', false ); // disable revisions (autosave remains)
For a single post type:
Disable revision support in the supports array in register_post_type().
Or after registration:
add_action( 'init', function() {
remove_post_type_support( 'promo', 'revisions' );
} );
Or via filter:
add_filter( 'wp_revisions_to_keep', 'change_revisions_limit', 10, 2 );
function change_revisions_limit( $num, $post ) {
if ( 'news' === $post->post_type ) {
return 0; // disable
}
if ( 'page' === $post->post_type ) {
return 5; // limit
}
return $num;
}
How to enable revisions for post types
Enable support in register_post_type():
register_post_type( 'news', [ 'supports' => [ 'title', 'editor', 'revisions' ], ] );
Or after registration:
add_action( 'init', function() {
add_post_type_support( 'product', 'revisions' );
} );
Functions and hooks
| Function | Description |
|---|---|
| wp_revisions_enabled() | Check if revisions are enabled for the specified post. |
| wp_is_post_autosave() | Determines whether the specified post is an autosave. |
| wp_delete_post_revision() | Deletes a post revision by ID. |
| wp_revisions_to_keep() | Defines how many of the latest revisions (changes) should be stored in the database for a specific post. |
| wp_get_post_revisions() | Gets all revisions (edits, changes) of the specified post. |
| wp_get_post_autosave() | Retrieves the autosaved data of the specified post. |
| wp_restore_post_revision() | Restores a post to the specified revision. |
| wp_is_post_revision() | Determines whether the specified post is a revision. |
| wp_save_post_revision() | Creates a revision (copy) of the specified post. It also deletes excess revisions. |
| wp_list_post_revisions() | Displays a list of a post's revisions. |
| wp_get_revision_ui_diff() | Get the revision UI diff. |
| Hook | Description |
|---|---|
| wp_revisions_to_keep | Filters the number of revisions to save for the given post. |
| wp_save_post_revision_check_for_changes | Filters whether the post has changed since the latest revision. |
| wp_save_post_revision_post_has_changed | Filters whether a post has changed. |
Developer notes
Restore a specific revision
$restored_id = wp_restore_post_revision( $revision_id );
Limit DB growth without disabling revisions
- Set a reasonable limit via WP_POST_REVISIONS or the filter.
- Keep autosave enabled for safety.
Cleaning up old revisions
WP-CLI - safer than direct SQL:
// Delete all revisions wp post delete $(wp post list --post_type=revision --format=ids) --force
By parent post type - with a PHP script with checks so as not to touch current editors' autosaves.
$revs = get_posts( [
'post_type' => "revision",
'numberposts' => -1,
'date_query' => [
[ "before" => "2024-09-01" ],
],
] );
foreach( $revs as $r ){
$p = get_post( $r->post_parent );
if( $p && "news" === $p->post_type ){
wp_delete_post( $r->ID, true );
}
}
echo "Done\n";
REST API
-
List revisions:
GET /wp/v2/posts/{id}/revisions -
Specific revision:
GET /wp/v2/posts/{id}/revisions/{revisionId}