20 thoughts on “Post Meta Abuse

  1. Super interesting post, thank you!

    I must admit, up until now I used to only consider taxonomies whenever the data I wanted to save was very similar to categories or tags. For everything else, I used post meta. I’ll try to change that!

    I have a few questions, though:

    1) What do you do for post meta that is usually saved as an array, with multiple values? This little plugin of mine for example stores 2 different colours for each post. Would you suggest creating 2 different taxonomies?

    2) It’s relatively easy to create custom meta boxes in the admin, allowing one to create user-friendly input fields for custom meta data. To take the example above, I add a colour picker to the post editor. What do you do when data has to be saved as a taxonomy term?

    • Thanks 😀

      1) I must admit, exact hex or RGB value colours don’t lend themselves to terms, you’d end up with hundreds of terms that have a single post, so it’s a case of precision and use case.

      The same is true of prices, you wouldn’t search for $4.98, but you might want to show all products between $1 and $5. I’d do this by adding a price range taxonomy, defining my terms as buckets, then putting products in each bucket when they’re saved/updated.

      The same strategy might work for colours, but you’d need some rules about how to define those buckets.

      But if on the other hand you mean an example of ‘red & blue’ or ‘green & orange’, I’d have a non-hierarchical taxonomy and use a tax_query to filter.

      TLDR: Store it as a post meta for precision when displaying on the page or doing calculations, but store a more general version as a term that you can filter on for searching and browsing

      2) While I’m not sure that the data a colour picker generates is best stored in a term, creating a metabox should be just as easy as post meta but using `wp_set_post_terms` etc instead.

      Admittedly people have had a lot more time and incentive to build meta box frameworks, but one of the more popular and well tested/scalable frameworks Field Manager by Alley Interactive supports this. When defining a field, tell it to use a term datasource object. Coincidentally there’s a Colourpicker field.

  2. Indexes on meta_value won’t really help with WP_Query, because internally WordPress does CAST(), which needs to read and convert all values, before filtering any of them out, which means the index can’t really be used, unless you hack into the generated queries and try to strip away the CAST(), in which case you may have other problems when working with numeric values.

    Also surprised you haven’t mentioned Elasticsearch on Sphinx. That would go under a “Not so easy fix” heading, but once it’s all set up, it works like a charm, especially with 10up’s ElasticPress plugin.

  3. So from reading both yours and Alex’s articles, would it be right to say that it’s fine to use custom fields (post meta) for elements on a page which won’t be searched for – ie Phone Number, Gallery, link to external website, Google Map etc? But then to use custom taxonomies for elements which will be queried – ie to display all posts which are “Self Catering or B&Bs”, “Dogs Welcome/Not Welcome” or “Has Wifi”?

  4. Hi Tom,

    This is the kind of posts I LOVE to read, just perfect for people like me = not developers, but able to understand when explained clearly 🙂 and I also like the fact that the “you shouldn’t” is followed by the “why” … thanks a lot!

    Are you on your gravatar with Finnish’ Moominpappa? If yes, I must friend you somewhere on social networks absolutely 😉


  5. Great post Tom. Both eye opening and frustrating in equal measure, as the more performant solution is right under our noses!

  6. Great timing of this post – it made me realise I should be using a taxonomy instead of custom field for a project I’m working on at this very moment, and inspired me to optimize another query to be way less complex. Thank you! 🙂

  7. Pingback: How to vet a plugin for add on development - Austin WordPress Meetup

  8. Pingback: Custom Fields vs. Custom Taxonomies, when to (not) use? - Meta Box

  9. Isn’t part of the problem with saying “use taxonomies for search” that they still need meta-data to be useful for searching more than a title because these are general purpose objects?

    On pricing, I’m particularly worried that categories might be a lower-effort fit, but certainly not a best-case (for the end-user) fit.

    As an alternative, you could instead of using a direct meta query, simply wrap these expensive queries in a pre-primed cache for the most common search. By separately priming the cache (perhaps a curl call to a REST endpoint, or admin-ajax), you can relatively swiftly get the result you like.

    Alternatives would be some method (I’ve seen lots of them), connecting to a copy of the database in a master->slave setup (I don’t particularly like the terminology, but it’s whats in the mysql manual). This would also allow you to spread the load (search is always going to be read-only).

    I’ll concede logging searches then becomes another discussion, but by thinking in blocks of what you want to do, you become less restrictive about how you use WordPress, and open yourself to more options.

    • No because so are post meta key value pairs. You can still make a key value pair that’s searchable, except the key is the taxonomy, and the value is the term. It’s a matter of imagination, and deciding the trade off. A lot of people are unaware they’re making a trade off with performance and scale as the cost they’re paying.

      As for caching, the problem there is it assumes the server can finish the query to begin with. Cache stampedes and race conditions also factor in. As for database load, adding slave databases could get expensive very quickly, especially at scale, but it’s still fundamentally a slow query even in the most optimistic of situations ( a fast server with a single visitor )

      I’m also unsure if you mean the same thing when you say search. I mean it as in a database finding posts given X Y and Z, rather than me typing a search term into a search box, or using the ‘s’ query variable in WP_Query. If you need to log post queries or user searches, there are dedicated systems for that such as elastic search + Kibana to name one

  10. This post will save my client time and money – real money. One problem is using dynamic.ooo “view” element in elementor which is just a grid basically they dont allow you to orderby a taxonomy. 🙁

    • At most indexes mitigate the problem, they don’t solve it. Indexes can help with edge cases, but you can’t keep adding indexes until all the problems go away. If that were the case there’d be no reason for indexes in the first place, indexes have a cost. It’s also not an excuse to just keep using post meta for absolutely everything.

      There is a tradeoff here and most people are unaware of it with major performance implications. You can still write expensive multi-dimensional queries using tax_query, that doesn’t mean taxonomies have no value from a performance standpoint.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.