WordPress stores a complete revision history for every post, page, and custom post type by default — automatically saving drafts every 60 seconds and creating a new revision on each manual save. These revisions let you compare, restore, and undo content changes without touching a backup. Snapshots extend this to full-site state capture at a point in time.
How WordPress Revisions Actually Work Under the Hood
Every time you click "Save Draft," "Publish," or "Update" in WordPress, the platform inserts a new row into wp_posts with post_type set to 'revision' and post_parent pointing to the original post ID. The post content, title, excerpt, and custom fields registered via revisions_to_save are all captured. What is not captured natively: widget settings, theme customizer options, plugin configuration, or uploaded media.
The Gutenberg editor also writes an auto-save revision roughly every 60 seconds using the REST API endpoint POST /wp-json/wp/v2/posts/{id}/autosaves. This is separate from your manual saves — if your browser crashes mid-edit, WordPress loads the auto-save on next open and prompts you to restore it. The auto-save only keeps one copy per post per user; each new auto-save overwrites the previous one.
What the Revision Diff Screen Shows (and Doesn't)
The comparison UI at Posts → All Posts → Revisions renders a line-by-line diff of post content using the same algorithm WordPress uses for the REST API. For block editor content, this is the serialized block markup, not a rendered visual diff. If you moved a Gutenberg block from position 3 to position 7, the diff shows that as a deletion and insertion of raw block comment syntax — not a visual "block moved" indicator.
Custom fields stored via the classic meta system appear in the diff only if the field was registered with 'revisions' => true in register_meta(). ACF fields, for instance, require explicit opt-in via the field group's revision setting.
How to Control Revision Storage: wp-config.php and WP_POST_REVISIONS
By default, WP_POST_REVISIONS is true, meaning unlimited revisions. You have three options:
// Option 1: Disable revisions entirely (not recommended — you lose your undo history)
define( 'WP_POST_REVISIONS', false );
// Option 2: Cap at a fixed number per post (recommended)
define( 'WP_POST_REVISIONS', 10 );
// Option 3: Keep the default (unlimited) — only viable with regular DB optimization
// No define needed; WordPress defaults to true
A cap of 10 is the practical sweet spot for most publishing workflows. Editorial teams rarely need to diff changes made more than 10 saves ago, and it keeps the wp_posts table lean. According to a 2023 analysis by Kinsta, sites without revision limits accumulate an average of 28,000 orphaned revision rows per year on active blogs — rows that add no recovery value but inflate every query that touches wp_posts.
You can also control the auto-save interval:
// Change auto-save interval from 60s to 120s
define( 'AUTOSAVE_INTERVAL', 120 );
Reducing this interval is worth considering on sites where the Heartbeat API is causing CPU spikes — though disabling Heartbeat entirely also disables auto-lock on posts being edited by multiple users.
Pruning Existing Revisions Without Losing History You Need
Capping WP_POST_REVISIONS only affects new saves — it does not retroactively prune existing rows. To clean up historical bloat, you have two safe options:
Option A: WP-CLI (preferred for developer workflows):
# See how many revisions exist
wp post list --post_type=revision --format=count
# Delete all revisions (non-destructive to live posts)
wp post delete $(wp post list --post_type=revision --format=ids) --force
# Or delete revisions older than 30 days only
wp post list --post_type=revision --date_query_before="30 days ago" --format=ids \
| xargs wp post delete --force
Option B: Direct SQL (use only with a backup in place — see our WordPress backup strategy guide before running raw queries):
DELETE FROM wp_posts WHERE post_type = 'revision';
DELETE FROM wp_postmeta WHERE post_id NOT IN (SELECT ID FROM wp_posts);
OPTIMIZE TABLE wp_posts;
OPTIMIZE TABLE wp_postmeta;
The OPTIMIZE TABLE call reclaims the freed space on MyISAM tables and rebuilds InnoDB indexes — worth running after any large deletion.
Snapshots vs. Revisions: What's the Difference?
| Feature | WordPress Revisions | Site Snapshots |
|---|---|---|
| Scope | Post/page content only | Full site: files + database |
| Granularity | Per-post, per-save | Per-site, per-scheduled interval |
| Storage location | wp_posts table | Offsite / hosting infrastructure |
| Trigger | Manual save or auto-save | Scheduled or manual trigger |
| Restore UX | WordPress admin UI | Hosting control panel or plugin |
| Theme/plugin changes | ❌ Not captured | ✅ Captured |
| Customizer settings | ❌ Not captured | ✅ Captured |
| Uploaded media | ❌ Not captured | ✅ Captured |
| Granularity of rollback | Individual post, any revision | Whole site to a point in time |
Revisions are surgical. Snapshots are nuclear. Use revisions when an editor accidentally overwrote a paragraph. Use a snapshot when a plugin update broke the entire front-end.
TopSyde's managed WordPress hosting includes automated daily snapshots with 30-day retention and one-click restore from the dashboard — which means you're covered at both layers without installing a dedicated backup plugin.
Plugin-Level Snapshot Tools Worth Knowing
For teams that need more than native revisions but don't have hosting-level snapshot tooling, these plugins fill the gap:
WP Sandbox / WP Rollback handles plugin and theme version rollbacks — not full site snapshots, but useful when a plugin update breaks something. It pulls previous versions directly from the WordPress.org SVN repository.
WPvivid Backup & Migration creates full-site snapshots (files + database) with remote storage support (S3, Google Drive, Dropbox). Restores are handled inside wp-admin. It's one of the more reliable free options for self-hosted recovery workflows.
All-In-One WP Migration is commonly used for migrations but doubles as a snapshot tool — its export bundles everything into a single .wpress file you can restore to any WordPress install.
VersionPress (now community-maintained as ElephantWP) took a git-based approach to WordPress versioning — every database change committed as a git object. It never reached widespread adoption due to complexity, but the concept is architecturally sound for developer-heavy environments.
For a broader look at why plugin selection at the snapshot layer matters, the considerations in our WordPress plugin audit guide apply here too — dormant or unmaintained snapshot plugins are a liability.
How to Restore a Revision: Step-by-Step
- Navigate to Posts → All Posts (or Pages, or CPTs).
- Click the post title to open the editor.
- In the Gutenberg editor, click the three-dot menu (⋮) in the top-right → Revisions. In the classic editor, the "Revisions" metabox appears below the publish controls.
- Use the slider to move between revisions. The left column shows the previous state; the right shows the selected revision.
- Click Restore This Revision to replace the current published content with the selected version.
Critical caveat: Restoring a revision creates a new save event, which itself generates a new revision. Your "restore" is auditable — you can always see what was restored and when.
Restore Order: Why Sequence Matters
If you're recovering from a major incident — say, a failed plugin update corrupted your homepage layout and overwrote content — the restore sequence matters:
- Restore the snapshot first. This rolls back the database and files to the pre-incident state.
- Then check revisions for any content changes that happened between the snapshot timestamp and the incident. If an editor published a new post in that window, the snapshot restore will have removed it. You'll need to find that post in the revision history (it may appear as a draft) and republish.
- Do not restore a content revision before restoring the snapshot. Rolling back a single post to revision #47 and then restoring the snapshot will overwrite your revision restore with the snapshot state — you'll lose the work you just recovered.
This sequencing issue is one reason why sites on managed WordPress hosting with dedicated snapshot tooling handle incidents faster than teams manually coordinating backup restores and revision rollbacks independently.
NGINX and Permalink Stability After Restores
One non-obvious failure mode after a snapshot restore: if your wp-config.php or .htaccess (or NGINX site config) gets restored to a previous state, your permalink structure may break. The symptom is 404 errors on all posts — the WordPress routing rules are missing or mismatched.
The fix is to regenerate rewrite rules: Settings → Permalinks → Save Changes (no actual change needed — just saving flushes and rewrites the rules). If you're on NGINX without .htaccess support, you'll need to update the server config manually — the NGINX WordPress permalinks 404 fix guide covers the exact rewrite block you need.
Revision Storage and Database Performance
According to a 2024 study by Delicious Brains, query time on wp_posts increases roughly linearly with row count — a table with 100,000 revision rows runs post queries approximately 3× slower than the same table with 10,000 rows, assuming no query caching. This matters on pages that call get_posts() or WP_Query without explicitly excluding revisions via 'post_type' => 'post' (the default does exclude them, but custom queries often don't).
The performance hit is compounded on sites running WooCommerce, where order data also lives in wp_posts pre-HPOS. If you're running WooCommerce and haven't migrated to HPOS yet, revision bloat and order bloat stack — a double incentive to cap revisions and run periodic pruning.
Revision Strategies by Site Type
| Site Type | Recommended Cap | Snapshot Frequency | Notes |
|---|---|---|---|
| Blog / editorial | 10–15 | Daily | High revision value; editors need rollback |
| WooCommerce store | 5–10 | Daily + pre-deploy | Product page revisions matter; keep lean |
| Agency client site | 10 | Daily + on-demand | Pre-update snapshots before any maintenance |
| Membership site | 10 | Daily | Content restriction config not in revisions |
| High-traffic news | 15–20 | Hourly | Multiple editors; revision audit trail valuable |
| Developer staging | 3–5 | Manual | Lower stakes; DB size matters more |
For membership sites specifically, remember that your content restriction rules (set in your plugin, not in post meta) are not captured by WordPress revisions — only a full snapshot covers those. The WordPress membership content restriction guide covers why this matters for access control integrity after a restore.
Frequently Asked Questions
How many WordPress revisions should I keep?
A cap of 10 revisions per post is the practical recommendation for most sites. It gives editors enough rollback history for realistic recovery scenarios (the last 10 saves covers days or weeks of editing) while preventing the database bloat that accumulates with unlimited revisions. Set this in wp-config.php with define( 'WP_POST_REVISIONS', 10 );.
Do WordPress revisions capture custom fields and ACF data?
Native WordPress revisions capture post content, title, and excerpt. Custom fields are only included if explicitly registered with 'revisions' => true via register_meta(). ACF has its own revision setting at the field group level — enable "Save post revisions" in the field group options to include ACF data in the diff and restore workflow.
What's the difference between an auto-save and a revision?
An auto-save is a single temporary record created every 60 seconds while you're actively editing — it overwrites itself each interval and is discarded once you manually save. A revision is a permanent snapshot created on each manual save or publish event, stored indefinitely (up to your configured cap). You can restore either, but auto-saves are only surfaced if WordPress detects they're newer than your last manual save.
Can I restore a revision without affecting other posts?
Yes — revision restores are scoped to a single post. Restoring post #42 to revision #5 has no effect on any other post, page, or site configuration. The restored content becomes the current version of that post; all other revisions remain intact and auditable.
Does deleting revisions affect my published content?
No. Revisions are child records that reference the live post — deleting them via WP-CLI or SQL does not alter the published content, just removes the historical snapshots. The only risk is losing rollback capability for those specific saves. Always confirm you have a full-site snapshot before pruning revisions, so you retain at least one recovery path.
Topics

Founder & Lead Developer
20+ years full-stack development, WordPress, AI tools & agents
Colton is the founder of TopSyde with 20+ years of full-stack development experience spanning WordPress, cloud infrastructure, and AI-powered tooling. He specializes in performance optimization, server architecture, and building AI agents for automated site management.



