Welcome to my blog. This is where I sometimes share interesting stories, challenges and breakthroughs from my journey in the realm of software development.

How to mass delete thousands of WordPress posts

We recently had to get rid of around 200,000 low quality WordPress posts for a client. The posts were not exposed to the outside world, no longer served a purpose and were thus deemed surplus to requirements.

200,000 posts is quite a number, and I’ll be honest, the thought of deleting such a volume of posts was quite daunting.

Before I get into what we did to complete this task, I’ll quickly outline the different ways you can delete posts in WordPress.

We chose to use WordPress’s CLI to achieve our objective and it did the job wonderfully.

“WP-CLI is the official command line tool for interacting with and managing your WordPress sites.”

There is an easy to follow guide to install the tool that you can find here.

Once you’ve installed the cli and you are ready to get to work, cd into your website’s root directory (the directory where your wp-config.php file is found) and run the following to test WP CLI’s SELECT command:

wp post list --post_type='post' --format=ids --posts_per_page=5 --orderby=post_id --order=ASC

The above command will run if you have installed the WP CLI globally. In case you have installed the WP CLI by simply downloading the phar file to your root directory, you’d run the following instead:

php wp-cli.phar post list --post_type='post' --format=ids --posts_per_page=5 --orderby=post_id --order=ASC

If all is well, the command should return a list of ids like so:

12 13 14 15 16

Once you are certain that your WP CLI is configured and works, you can run your first delete query (keep in mind this delete is permanent!):

wp post delete $(wp post list --post_type='post' --format=ids --posts_per_page=5 --orderby=post_id --order=ASC) --force

As you can see from the command above, we are feeding the result of our SELECT command into the DELETE command thus ‘telling’ the DELETE command the ids of the posts we want to delete. The —force flag at the end is optional and is there to skip Trash and delete the posts permanently.

To check that your posts have indeed been deleted, you can rerun the SELECT command or you can access your WordPress dashboard and check there.

Once you are happy with the process, you can change your command to delete more posts in one go, via the posts_per_page parameter. E.g. we deleted posts in batches of 5000 like so:

wp post delete $(wp post list --post_type='post' --format=ids --posts_per_page=5000 --orderby=post_id --order=ASC) --force