没有不值得去解决的问题,也没有不值得去学习的技术!

Disable WordPress Revisions and Clear 7,085 Historical Revisions: Also Remove 2,495 wp_sync_storage Entries

[Figure 2: Setting WP_POST_REVISIONS to false in wp-config.php]

作者:

While organizing my WordPress blog recently, I noticed an issue again that had bothered me before: post IDs seem to grow a bit too fast.

This time, a new post happened to serve as a good sample.

The ID of the Chinese post is:

Plaintext
27442

The ID of the corresponding English translation is:

Plaintext
27455

There is a difference of 13 between the two.

This post only added 1 new tag; even counting the corresponding English tag, that is only 2. So from the start, I wondered what content was actually consuming these IDs.

Following this thread, I ended up not only disabling WordPress Revisions entirely but also cleaning up:

Plaintext
7085 revisions
2495 wp_sync_storage records

I also confirmed that no orphaned postmeta were left behind.

This article documents the entire process.


1. First, confirm what exactly exists between 27442 and 27455

First, I queried this ID range in wp_posts:

Bash
wp eval --allow-root '
global $wpdb;

$rows = $wpdb->get_results("
    SELECT
        ID,
        post_parent,
        post_type,
        post_status,
        post_title,
        post_date
    FROM {$wpdb->posts}
    WHERE ID BETWEEN 27442 AND 27455
    ORDER BY ID
");

foreach ($rows as $row) {
    printf(
        "%s\t%s\t%s\t%s\t%s\t%s\n",
        $row->ID,
        $row->post_parent,
        $row->post_type,
        $row->post_status,
        $row->post_title,
        $row->post_date
    );
}
'

The main records found before cleanup were:

Plaintext
27442  Chinese post
27443  attachment
27444  attachment
27445  attachment
27446  attachment
27447  attachment
27448  attachment
27449  attachment
27450  attachment
27451  revision
27452  revision
27454  revision
27455  English post

In other words, the growth across these 13 IDs primarily came from:

TypeCount
Image attachments8
Revisions3
Non-existent ID 274531
English post1

This also confirmed one thing along the way:

Tags do not consume wp_posts.ID.

What actually causes wp_posts.ID to grow are posts, attachments, Revisions, and other data stored using the wp_posts table.

After cleaning up the Revisions, querying the same range again shows that the original 27451, 27452, and 27454 no longer exist.

[Figure 1: Querying 27442–27455 again after cleaning Revisions; the original Revision records are gone]
[Figure 1: Querying 27442–27455 again after cleaning Revisions; the original Revision records are gone]

It is worth noting that once records are deleted, the already used IDs will not be reused.

So even though 27451 has been deleted, future new posts will not start from this ID again.


2. Historical Revisions had accumulated to 7085

Since this single new post left behind 3 Revisions, I went ahead and counted the entire site:

Bash
wp eval --allow-root '
global $wpdb;

$count = (int) $wpdb->get_var(
    "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = '\''revision'\''"
);

echo "revision_count={$count}\n";
'

Result:

Plaintext
revision_count=7085

7085 records.

My blog has been running for many years and is now bilingual in Chinese and English, so having a certain number of Revisions is normal.

But the problem is: I actually almost never use WordPress’s “restore to previous version” feature.

Since this feature goes unused for long periods, keeping thousands of historical versions—or even more in the future—has little practical value for me.


3. The vast majority of Revisions come from blog posts

To avoid simply treating all Revisions as post history, I also broke them down by parent content type:

Bash
wp eval --allow-root '
global $wpdb;

$rows = $wpdb->get_results("
    SELECT
        p.post_type AS parent_type,
        COUNT(*) AS revision_count
    FROM {$wpdb->posts} r
    LEFT JOIN {$wpdb->posts} p
        ON p.ID = r.post_parent
    WHERE r.post_type = '\''revision'\''
    GROUP BY p.post_type
    ORDER BY revision_count DESC
");

foreach ($rows as $row) {
    printf(
        "%-25s %d\n",
        $row->parent_type ?: "(missing parent)",
        $row->revision_count
    );
}
'

Result:

Plaintext
post                      7024
wp_template               19
page                      13
wp_navigation             9
nimble_post_type          6
wp_template_part          6
wp_global_styles          3
custom_css                3
contx_post_type           2

Out of the 7085 Revisions:

Plaintext
7024 come from posts

Accounting for the vast majority.

Here, post includes both Chinese and English posts. Under Polylang, Chinese and English posts are essentially still two independent WordPress post.

The rest come from:

  • Pages
  • Templates
  • Navigation
  • Template parts
  • Global styles
  • Custom CSS
  • Custom content types from some plugins

These quantities are all quite small.

Since I already decided not to use the Revision rollback feature going forward, I ultimately decided: delete all of them, rather than just deleting Revisions for blog posts.


4. Completely disabling WordPress Revisions

The original configuration was:

PHP
define( 'WP_POST_REVISIONS', 3 );

Meaning each piece of content kept at most 3 Revisions.

I changed it directly to:

PHP
define( 'WP_POST_REVISIONS', false );
[Figure 2: Setting WP_POST_REVISIONS to false in wp-config.php]
[Figure 2: Setting WP_POST_REVISIONS to false in wp-config.php]

After making the change, I verified it via WP-CLI:

Bash
wp eval --allow-root '
echo "WP_POST_REVISIONS=";
var_export(WP_POST_REVISIONS);
echo PHP_EOL;

echo "AUTOSAVE_INTERVAL=" . AUTOSAVE_INTERVAL . PHP_EOL;
'

Result:

Plaintext
WP_POST_REVISIONS=false
AUTOSAVE_INTERVAL=60

There is an important distinction here:

Disabling Revisions does not mean disabling Autosave.

I did not separately configure AUTOSAVE_INTERVAL in wp-config.php, so WordPress still uses the default:

Plaintext
60 seconds

That means my current strategy is:

Do not keep historical Revisions long-term, but retain autosave during editing.

This suits my needs much better.


5. Back up the database before deleting

Because I was about to delete thousands of database records this time, I used UpdraftPlus to perform a database backup before the actual operation.

This only involved the database, so I only checked:

Include the database in the backup

There was no need to back up all uploaded files again.

[Figure 3: Backing up the WordPress database separately with UpdraftPlus before cleanup]
[Figure 3: Backing up the WordPress database separately with UpdraftPlus before cleanup]

Although I was only deleting Revisions, given that the database has accumulated over many years, I still preferred to have a complete restore point first.


6. Cleaning up 7085 Revisions in batches

I did not directly execute something like:

SQL
DELETE FROM wp_posts WHERE post_type = 'revision';

Instead, I continued processing through WordPress’s own deletion interface.

Deleting 500 records per batch:

Bash
while true; do
    IDS=$(wp eval --allow-root '
    global $wpdb;

    $ids = $wpdb->get_col("
        SELECT ID
        FROM {$wpdb->posts}
        WHERE post_type = '\''revision'\''
        ORDER BY ID
        LIMIT 500
    ");

    echo implode(" ", $ids);
    ')

    if [ -z "$IDS" ]; then
        echo "全部 revisions 已清理完成"
        break
    fi

    COUNT=$(echo "$IDS" | wc -w)
    echo "本批删除 ${COUNT} 条 revision"

    wp --allow-root post delete $IDS --force
done

One benefit of handling it this way is that instead of simply deleting rows directly from wp_posts, it goes through WordPress’s deletion workflow.

Finally, I counted again:

Plaintext
revision_count=0

The original:

Plaintext
7085

has been completely cleaned up.


7. After cleaning Revisions, I discovered 2495 wp_sync_storage records

After clearing the Revisions, I recounted the various post_type in wp_posts:

Plaintext
attachment                9678
post                      2999
wp_sync_storage           2495
series_grouping           48
nav_menu_item             34
wpcode                    31
...

At this point, a very conspicuous content type appeared:

Plaintext
wp_sync_storage  2495

The count was surprisingly close to 2500.

I continued to inspect these records:

Bash
wp eval --allow-root '
global $wpdb;

$rows = $wpdb->get_results("
    SELECT
        post_status,
        COUNT(*) AS count,
        MIN(ID) AS min_id,
        MAX(ID) AS max_id,
        MIN(post_date) AS first_date,
        MAX(post_date) AS last_date
    FROM {$wpdb->posts}
    WHERE post_type = '\''wp_sync_storage'\''
    GROUP BY post_status
    ORDER BY count DESC
");

foreach ($rows as $row) {
    printf(
        "status=%-15s count=%-6d ID=%d-%d date=%s -> %s\n",
        $row->post_status,
        $row->count,
        $row->min_id,
        $row->max_id,
        $row->first_date,
        $row->last_date
    );
}
'

Result:

Plaintext
status=publish
count=2495
ID=9453-23604
date=2026-04-09 11:16:45 -> 2026-08-07 19:15:33

The last record stayed at:

Plaintext
2026-08-07 19:15:33

And it is already September 6.

I vaguely remembered that I had previously turned off WordPress’s collaborative editing features, so I continued to verify the current status.


8. Confirming that the collaboration feature is indeed disabled

Execute:

Bash
wp eval --allow-root '
echo "wp_is_collaboration_enabled=";
var_export(
    function_exists("wp_is_collaboration_enabled")
        ? wp_is_collaboration_enabled()
        : "function_missing"
);
echo PHP_EOL;

echo "WP_ALLOW_COLLABORATION=";
if (defined("WP_ALLOW_COLLABORATION")) {
    var_export(WP_ALLOW_COLLABORATION);
} else {
    echo "(not defined)";
}
echo PHP_EOL;

echo "wp_collaboration_enabled option=";
var_export(get_option("wp_collaboration_enabled", "(not set)"));
echo PHP_EOL;
'

Result:

Plaintext
wp_is_collaboration_enabled=false
WP_ALLOW_COLLABORATION=(not defined)
wp_collaboration_enabled option='(not set)'

That means the actual current state is indeed:

Plaintext
wp_is_collaboration_enabled=false

Combined with:

Plaintext
The last wp_sync_storage record stayed at 2026-08-07

It is basically confirmed that these 2495 records are historical data left over from when the related features were in use.


9. The 2495 wp_sync_storage records also had 2682 associated postmeta entries

Before actually deleting them, I checked the postmeta corresponding to these records:

Bash
wp eval --allow-root '
global $wpdb;

$count = (int) $wpdb->get_var("
    SELECT COUNT(*)
    FROM {$wpdb->postmeta} pm
    INNER JOIN {$wpdb->posts} p
        ON p.ID = pm.post_id
    WHERE p.post_type = '\''wp_sync_storage'\''
");

echo "sync_storage_postmeta_count={$count}\n";
'

Result:

Plaintext
sync_storage_postmeta_count=2682

That is:

Plaintext
2495 wp_sync_storage records
2682 associated postmeta entries

So here too, I did not directly use hard SQL deletes.

I continued to use:

Bash
wp post delete --force

to clean them up in batches.


10. Final cleanup results

After everything was complete, I put together several key states for final verification.

[Figure 4: Final verification results after WordPress database cleanup]
[Figure 4: Final verification results after WordPress database cleanup]

Result:

Plaintext
=== WordPress cleanup verification ===
WP_POST_REVISIONS=false
AUTOSAVE_INTERVAL=60
collaboration_enabled=false
revision_count=0
wp_sync_storage_count=0
orphan_postmeta_count=0

The final state is now:

ItemResult
WordPress RevisionsDisabled
Autosave60 seconds, retained
Historical Revisions7085 → 0
Collaborative editingDisabled
wp_sync_storage2495 → 0
wp_sync_storage associated postmetaCleaned up with records
Orphaned postmeta0

This time, just wp_posts deleted:

Plaintext
7085 + 2495 = 9580

That is 9580 historical or internal records.


11. Why I ultimately chose to completely disable Revisions

Initially, I actually considered:

PHP
define( 'WP_POST_REVISIONS', 1 );

Meaning, keeping at least the previous historical version.

But on second thought, I have used WordPress for many years and almost never actually used the Revision restore feature.

For me:

  • Accidental exits during editing can be covered by Autosave;
  • Once a post is officially published, I rarely need to revert to a version from hours or days ago;
  • The database itself is also backed up regularly;
  • The site already has a large number of posts;
  • And it is now bilingual in Chinese and English, so the number of posts will continue to grow.

So I ultimately chose:

PHP
define( 'WP_POST_REVISIONS', false );

Which better fits my actual usage.

Of course, this choice is not necessarily suitable for all websites.

For multi-user editing, newsrooms, or team collaboration sites, the value of Revisions is clearly higher.

But for a personal tech blog mainly maintained by myself, where I almost never roll back post history, disabling it is perfectly acceptable.


12. Do not reset AUTO_INCREMENT just to “reclaim IDs”

There is another point that easily causes confusion.

This time I deleted 9580 wp_posts records, but that does not mean the previously occupied IDs will be reused.

For example:

Plaintext
27451
27452
27454

The original Revisions have been deleted, but these IDs will remain permanently vacant.

This is normal behavior.

Therefore, I did not do this:

Plaintext
Reset AUTO_INCREMENT

Nor did I try to rearrange post IDs.

A large number of internal WordPress relationships depend on IDs; manipulating them just to make the numbers “consecutive and pretty” has no practical meaning and may only increase risk.


13. The biggest takeaway from this investigation

At the very beginning, I simply noticed:

Plaintext
Chinese post ID: 27442
English post ID: 27455

And felt the gap between the two IDs was a bit large.

Following it all the way down, I discovered two long-accumulated data sources:

Plaintext
7085 revisions
2495 wp_sync_storage records

I also confirmed several other easily confused issues:

  • Tags do not consume wp_posts.ID
  • Image attachments consume IDs
  • Revisions consume IDs
  • Deleting Revisions does not reuse IDs
  • Disabling Revisions does not mean disabling Autosave
  • Chinese and English Polylang posts are still independent post in themselves
  • Disabled collaboration features may still leave behind historical wp_sync_storage
  • After deleting associated data, you should also check for orphaned postmeta

Now:

Plaintext
revision_count=0
wp_sync_storage_count=0
orphan_postmeta_count=0

The database state is much cleaner now.

When publishing new Chinese and English posts next, I can continue to observe the ID changes between them.

At that point, the remaining ID consumption should be easier to attribute to image attachments, autosaves, or other internal WordPress records.

需要长期技术维护或远程问题排查?

我是拥有 15+ 年经验的 PHP / Go 后端工程师,长期关注已有系统维护、Bug 修复、性能优化、服务器排查、WordPress 网站维护和小功能迭代。

如果你的项目遇到以下情况,可以先从一次小问题排查开始合作:

  • ✅ PHP / Laravel / Yii2 老项目无人维护
  • ✅ Go / Gin 后端接口需要排查或优化
  • ✅ WordPress 网站访问慢、报错或插件冲突
  • ✅ Nginx / MySQL / Redis / Linux 服务器异常
  • ✅ CDN / Cloudflare / DNS / HTTPS 配置问题
  • ✅ 需要长期远程技术支持或兼职维护

更多介绍请查看:关于我 & 合作

微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan