The problem is that once you delete hundreds or thousands of posts in WordPress, it’s basically impossible to empty the trash using the interface — it’ll take a few minutes and then time out without successfully emptying the trash.

Luckily there is always a better way… and in this case, it’s as simple as running a database script. You can launch a MySQL console by running this command from the terminal, using the values from your wp-config.php file to connect to the database.

Once there, paste in the following, and promise not to get mad if your whole site breaks. Maybe you should have a full backup of your website, right?

What this will do is not only delete the post record itself from wp_posts, but also the extra metadata from wp_postmeta, wp_term_relationships, and wp_term_taxonomy — the latter two are for category and tag assignments, and the former is obviously for metadata about the post itself.

The DELETE part of the statement lists out the tables that we want to delete data from, and MySQL will delete all records in those tables that are matched by this query. So, obviously, if you’re going to tweak this technique you should be realllllllly careful.

You could, of course, only delete the posts by using delete from wp_posts where post_status=‘trash’ but that would leave all the meta around, which can be a ton of extra data.

I would highly recommend running this script on your local development or QA site first to make sure it does what you’re expecting. You wouldn’t run random SQL on production in the middle of the day would you?