Disable comments in WordPress with WP-CLI
Disable comments in WordPress with WP-CLI — close new and existing posts from the command line, clear spam safely, and the delete command to avoid on a store.
Turning comments off in the WordPress admin is a settings page, a bulk edit per post type, and a lot of clicking. On one site that is an afternoon’s chore. On twenty client sites, or in a script that builds a new site, it is the wrong tool. WP-CLI does the same job in a handful of commands, and you can run them again next month when someone reopens a thread by accident. This guide covers the commands that close comments properly, the cleanup command that is safe, and the one you should never paste into a store.
If you’d rather do this in the admin, the click-by-click version of this guide covers the same ground.
Step 1: close comments on new posts
The checkbox on Settings → Discussion (“Allow people to submit comments on new posts”) is one option in the database. Set it from the command line:
wp option update default_comment_status closed
wp option update default_ping_status closed
The second line does the same for pingbacks and trackbacks, which are a separate field. Both options only set the default for content you haven’t published yet. Every post already on the site keeps whatever it had, which is why this step alone never finishes the job.
Step 2: close comments on everything you already have
Each post stores its own comment_status. To close them all, list the posts that are still open and update them:
wp post list --post_type=post,page --post_status=any \
--comment_status=open --format=ids
Run that first on its own. It prints the ids it would touch, so you can see the size of the change before making it. Then:
wp post update $(wp post list --post_type=post,page --post_status=any \
--comment_status=open --format=ids) \
--comment_status=closed --ping_status=closed
Two things to know:
- Add your custom post types.
--post_type=post,pagecovers only those two.wp post-type list --fields=name,publicshows the rest; anything public that supports comments belongs in the list. - On a big site, go in batches. Thousands of ids in one command can exceed the shell’s argument limit. Pipe them through
xargsinstead:
wp post list --post_type=post,page --post_status=any \
--comment_status=open --format=ids \
| xargs -n 200 sh -c 'wp post update "$@" --comment_status=closed --ping_status=closed' _
This is the step that matters for spam. Bots never load your comment form; they POST straight to wp-comments-post.php, and WordPress rejects the request only when the post’s own comment_status is closed. Hiding the form in a template does nothing. Closing the post does.
Step 3: check that it worked
wp post list --post_type=post,page --post_status=any \
--comment_status=open --format=count
0 means nothing is open. Keep this line: it is the check to run again later, because a closed site doesn’t always stay closed. An editor can reopen a single post from the editor sidebar, an import can bring posts in with comments open, and a plugin that creates content may not read your default.
What is still there afterwards
Closing comments stops new ones. It doesn’t remove anything that is already on the page:
- Approved comments still show under each post, with a “Comments are closed” line beneath them.
- The admin still has its Comments menu, the dashboard activity box, and the comment bubble in the toolbar.
- The comment feeds still answer, and the REST API still lists existing comments.
None of this is a security problem. It is just not what most people mean by “comments are off”.
Clearing out spam and trash
Once comments are closed, the old spam is dead weight. WP-CLI can remove it, and this version is safe because it only touches what you have already rejected:
wp comment delete $(wp comment list --status=spam --format=ids) --force
wp comment delete $(wp comment list --status=trash --format=ids) --force
--force skips the trash and deletes for good, so count first with wp comment list --status=spam --format=count.
Never run the “delete everything” one-liner on a store
Search for how to delete all WordPress comments and you will find some version of this:
# Do not run this on a WooCommerce site.
wp db query "DELETE FROM wp_comments"
On a blog it removes blog comments. On a store it removes much more. WooCommerce keeps order notes in the same table: payment confirmations, refund records, the “shipped” note a support agent typed into an order. They are rows in wp_comments with a comment_type of order_note. Webhook delivery logs are stored the same way, and product reviews are comments too.
We caught this on a real site. Its front end showed three comments. The wp_comments table held 122 rows, and 118 of them were order notes. WooCommerce hides those rows from normal comment queries, which is why wp comment list and the Comments screen look nearly empty on a store. A raw SQL delete has no such filter. It would have erased the order history of every customer, to remove three comments.
So: close, never bulk-delete. If you do need to delete, select by status or by comment_type, never the whole table, and take a database backup first (wp db export).
The same job with Adminkeep
Adminkeep is a free plugin with a Disable Comments feature, and since 1.5.0 it has its own WP-CLI commands. The whole of this guide becomes:
wp plugin install adminkeep --activate
wp adminkeep feature enable disable_comments
That one switch closes comments on all existing content as well as new posts, rejects direct POST requests to wp-comments-post.php, and hides the comments that were already approved, which closing alone leaves on the page. It writes no changes to your posts. Turn it off and every post has exactly the comment setting it had before:
wp adminkeep feature disable disable_comments
The cleanup has the store problem built in:
wp adminkeep comments count
wp adminkeep comments purge
count prints the number purge would delete. By default that is spam and trash only. WooCommerce order notes, webhook logs and product reviews are left out unless you pass --woo. Comments on trashed posts are skipped, because they come back if you restore the post. Comment types it doesn’t recognise are left alone. purge shows the number and asks before deleting; in a script, --yes answers for you. Deleting is the one thing here that cannot be undone, so the defaults are the cautious ones.
For a fleet of sites, the same two lines run anywhere WP-CLI reaches:
for site in site-a.example site-b.example; do
wp --ssh="deploy@$site" adminkeep feature enable disable_comments
done
Every command is listed in the WP-CLI commands reference, and wp help adminkeep prints the same reference on the site itself.
Adminkeep is a free download, GPL, and every one of its features is fully reversible — switch it off and your site is exactly as it was.