Last week, when I was in between projects, I decided to take one day and draft up a WP-CLI command that allows for listing and deleting orphan WordPress entities, as well as metadata.

I had the idea for this quite a while ago, and I tried to get it into WP-CLI. That failed, however, as the maintainers weren’t sure what package this functionality should live in, what the API should look like, what the feature set should entail, and more.

In case you are wondering “Why would I need something like this?”, reasons might include that some third-party developers deleted entities and/or metadata directly in the DB (instead of using the respective WordPress API to handle that data), or maybe because someone did a partial DB import, or partial migration. Over time, you might find yourself with quite a few dead database entries.

Orphan Command

I created a WP-CLI package, named Orphan Command, that can also be used as regular WordPress plugin (for people who need that).

For now, the repository is private, but after some people have had a chance to take a look at the code, functionality, and API, I would like to make it publicly available.


The package currently allows to manage the following pieces of orphan data and metadata:

  • blog metadata
  • comments (referencing non-existing posts)
  • comment metadata
  • posts
  • post metadata
  • revisions
  • term metadata
  • user metadata

Since comments can be nested (i.e., a comment can have a parent comment), an orphan comment could also be a comment referencing another comment that does not exist anymore. This is not what the wp orphan comment command does, though. The main reason is that a comment referencing a non-existing post will usually not be exposed to site visitors. Hence, it’s the more useful definition, in my opinion.

A future version of Orphan Command might allow to also list/delete comments referencing non-existing parent comments.


The main command is wp orphan.

For each supported object type, there is a dedicated subcommand, for example, wp orphan post. Metadata would go under the object type, for example, wp orphan comment meta.

For each of these, the supported actions are list and delete. Therefore, the full synopsis list is as follows:

  • wp orphan blog meta delete
  • wp orphan blog meta list [--format=<format>]
  • wp orphan comment delete [--type=<comment-type(s)>]
  • wp orphan comment list [--type=<comment-type(s)>] [--format=<format>]
  • wp orphan comment meta delete
  • wp orphan comment meta list [--format=<format>]
  • wp orphan post delete [--type=<post-type(s)>]
  • wp orphan post list [--type=<post-type(s)>] [--format=<format>]
  • wp orphan post meta delete
  • wp orphan post meta list [--format=<format>]
  • wp orphan revision delete
  • wp orphan revision list [--format=<format>]
  • wp orphan term meta delete
  • wp orphan term meta list [--format=<format>]
  • wp orphan user meta delete
  • wp orphan user meta list [--format=<format>]

In addition to the above, you may print the MySQL query to list orphan data for a given entity type to the console by using the query action (e.g., wp orphan post query). This might serve as a starting point for people who need to do more complex things.

Frequently Asked Questions

Let me quickly inline the FAQ from the repository:

What about terms?

For terms, there is no clear definition of orphans. An orphan term could be defined in one of several ways:

  • An entry in the wp_terms table that is not referenced at all in the wp_term_taxonomy table. (This is most likely not what you want, most of the time.)
  • An entry in the wp_term_taxonomy table referencing a non-existing term (i.e., wp_term_taxonomy.term_id does not exist in wp_terms.term_id).
  • An entry in the wp_term_taxonomy table referencing a non-existing parent term (i.e., wp_term_taxonomy.parent does not exist in wp_terms.term_id).
  • An entry in the wp_term_relationships table referencing a non-existing object. (This would either require the taxonomy, or the object type to then use all registered taxonomies.)

To some extent, this is similar to comments. However, there it is more of an interpretation issue, which is why Orphan Command, by default, defines orphan comments as comments referencing non-existing posts.

A future version of Orphan Command might allow to also list/delete orphan terms.

What about site/network metadata or options?

The terminology in WordPress around blog metadata and options, network options, and site metadata and options is quite confusing!

Some facts:

  • Orphan Command supports blog meta.
  • Options live in dedicated tables on a per-site basis, which means there cannot be any orphan options.
  • While it makes sense to manage site (i.e., network) metadata, Orphan Command currently does not allow for this. The main reason really is to prevent people from accidentally deleting the wrong data.
  • A future version of Orphan Command might allow to also list/delete site metadata.

What about use case XYZ?

Yes, there are most certainly several possible use cases around orphan data and metadata missing. However, this is on purpose.

While it may be a good idea to list all users of a specific role that are not added to any site, or to delete all orphan posts with a specific status, this would be out of scope.

Orphan Command provides easy access to tasks that a lot of people might want to perform a lot of times; not more.

That said, you should be able to use existing WP-CLI commands such as wp <entity> list|delete or wp db query to accomplish any of the above examples quite easily.


I’m happy to hear any thoughts! ?

Do you think this is useful? Would you have used it before, if it had been available?

Is there anything missing, or to be improved?

Leave a Reply

Your email address will not be published. Required fields are marked *