Bulk-delete old posts by date, type, or ID

MaintenanceIntermediate~15 min

Before you start

A connected site with content reads on and the content write abilities enabled. A clear rule for what should go, like a date cutoff, a post type, a category, or a list of IDs.

Every long-running site collects posts that have outlived their point: expired announcements, old event listings, a test post from launch week. Clearing them out by hand is slow and nerve-racking, because bulk actions in the admin are one wrong checkbox away from taking down something you meant to keep, and there is no dry run.

This gives you the dry run. It counts, it lists, it waits, and it moves things to a Trash you can undo.

The prompt
I want to clear out old [posts] and I want to be careful about it. First,
read only: count how many [posts] match [published before 2023, in the
"News" category] and show me that number, then list them so I can see the
titles, dates, and links. Change nothing yet.
I will look at the list and tell you which ones to remove, or confirm the
whole set. Only after I say so, move them to the Trash in small batches,
pausing after each batch, so nothing leaves the Trash and I can restore any
of them from WordPress. Do not permanently delete anything. When you are
done, list every post you trashed with its old link.

Why this is safe to run

The whole first pass is reads. Counting the matches is its own ability, separate from listing them, and neither one can change anything, so you see the number and then the actual titles and links before a single post moves. Nothing is trashed until you confirm the set.

The write half only moves posts to the Trash, which is recoverable: a trashed post sits in WordPress until you empty it, so a mistake is a restore, not a loss. The permanent-delete ability, the one that bypasses the Trash, is a different ability with its own switch, and this recipe deliberately leaves it alone. The content write ability stays off until you enable it, every trash call is checked against the bound user’s capability, batching keeps you in the loop as it goes, and every move is written to the Activity Log with the post it affected.

Already connected? Skip the paste. Ask your agent for the “bulk-delete old posts” recipe, describe the set you want gone, and it runs the same count-list-confirm-trash flow on your own install.

How it works

  1. Count how many posts match your rule and show you the number.
  2. List them so you can read the titles, dates, and links.
  3. Wait for you to confirm the exact set before anything moves.
  4. Move the approved posts to the Trash in small batches, pausing after each.
  5. Return the list of everything it trashed, with each old link.

Questions

Is anything permanently deleted?
No. This recipe moves posts to the Trash, which is recoverable, so you can restore any of them from WordPress. A separate permanent-delete ability exists, but this recipe does not use it, and Trash is the safer default for a bulk clear-out.
What if I only want some of the posts it finds?
You tell it which ones. The list comes first and nothing moves until you confirm, so you can approve the whole set or hand back a shorter list of IDs to trash.