How a restore works
The term is captured on pre_delete_term, before WordPress touches posts or child terms, and saved on delete_term once the delete has really happened.
Restoring:
- inserts the term row with its original
term_idandterm_taxonomy_idwhen they are still free, and otherwise gives it new ones and says so - re-adds the meta, moves children back only if nobody moved them since, and recreates the menu items in their old position
- re-attaches objects with their
term_orderin batches, skipping objects deleted in the meantime, and firesadded_term_relationshipandset_object_termsfor each one so search indexes such as ElasticPress and VIP Enterprise Search pick them up - takes the default term (Uncategorized) back from objects that only got it because of the delete, if nobody changed their terms since
Large sites
A term on a million posts is fine:
- Delete: relationships are read 1,000 at a time and kept as packed
id:orderstrings, one meta row per 1,000. The snapshot itself stays a few KB. The work grows with the number of posts, the same way WordPress’s own delete does. - Restore: the first 5,000 objects come back in the request. The rest are re-attached through WP-Cron, 5,000 per run, with a lock so two runs never overlap. The trash screen says so, and the item leaves the list while it runs.
wp axle-category-tag-trash restore <id>finishes it in one go. - Empty trash: deletes 200 items in the request and the rest through WP-Cron.