Home About Me

Why WordPress Has Both term_id and term_taxonomy_id

When working with WordPress APIs—or querying its database directly—it is common to find parameters that accept both term_id and term_taxonomy_id. They look nearly identical, and in many cases swapping one for the other appears to make no practical difference.

They are not the same thing, though. Their confusing relationship is largely the result of WordPress’s older taxonomy design.

A useful way to think about a term is as a label or name: any noun used for classification. The term_id is the identifier assigned to that label.

Terms and taxonomies are separate concepts

WordPress originally had categories only. Tags were introduced in WordPress 2.3, and the development team treated tags and categories as variations of the same underlying concept. That shared concept became the term. Later additions, including post formats and custom taxonomies, followed the same model.

A term does not mean much on its own. It becomes meaningful only when used within a particular taxonomy—such as a category, a tag, or a custom taxonomy.

The word taxonomy comes from classification. It may seem unnecessarily technical, but WordPress could not simply reuse the word category: categories had existed since the beginning, and the term already had a specific meaning in the system.

A tag is one taxonomy; a category is another. The concrete record tying a term to a taxonomy is stored in wp_term_taxonomy. Every actual tag, category, or custom-taxonomy term has its own row in this table, and those rows are distinct.

This is what term_taxonomy_id identifies: not just a term, but a particular term-in-a-taxonomy combination.

What the two tables store

The wp_term_taxonomy table does not hold the human-readable name. Names, slugs, and other visible term information are stored in wp_terms instead.

That split originally allowed different taxonomies to reuse the same named term without duplicating its row in wp_terms. In practice, that was likely the main reason for maintaining two separate tables.

For example, imagine both of these exist:

  • a tag named “Games”
  • a category also named “Games”

In older WordPress versions, these could share one term_id and the same slug in wp_terms. But they still had separate rows in wp_term_taxonomy, because one represented a tag and the other represented a category. Their term_taxonomy_id values were therefore different.

The connection between posts and taxonomy entries is stored in wp_term_relationships. That table uses term_taxonomy_id, because a post is attached to a specific taxonomy instance rather than to a bare term name.

Why the IDs now usually match

WordPress 4.2 introduced taxonomy term splitting after bugs were discovered when renaming tags. From that point forward, separate taxonomy records no longer shared the same term name record. Each term_taxonomy entry received its own term entry as well.

As a result, the number of records in wp_terms and wp_term_taxonomy became aligned, and the two IDs stopped differing in normal use. This is why exchanging term_id and term_taxonomy_id often seems harmless in modern WordPress installations.

The conceptual distinction remains useful:

  • Use term_id for operations concerning the term itself, such as its tag or category name.
  • Use term_taxonomy_id for relationships between a taxonomy entry and a post.

Since WordPress 4.2, however, the values generally no longer differ.