get_option() vs get_theme_mod(): Why is one slower?

The answer that yes, the theme_mod functions will be slower, but not significantly, and the benefits outweigh the differences.

Theme mods are stored as options. So, in essence, the theme_mod functions are wrappers around the options functions.

First, understand that theme_mod settings are stored as an array in a single option, keyed to the specific theme name. So, if I do this:

set_theme_mod('aaa',123);
set_theme_mod('bbb',456);

Then what I actually get in the database is a single options row with the name of theme_mods_themename which contains a serialized array with (‘aaa’=>123, ‘bbb’=>456) in it.

Now, get_theme_mod will be slower because it’s actually making two get_option calls. First, it gets the name of the theme. Then, it gets the theme_mods_themename option. So right there that’s a 50% speed loss. The rest of the work done lies mostly in filters, in that there is an extra filter call, but unless you have something on that filter, this is kinda insignificant.

Note that the options system stores retrieved data in the object cache, so it’s not making multiple database calls here. Only the first use results in a database hit.

The set_theme_mod will be somewhat slower because it makes those same two get options calls, then it makes another get_option call to get the theme name again, and then it does update_option with the full set of now changed options. This causes a database update, and the fact that it’s sending a lot more data can indeed be the cause of a noticable slowdown. Updating a few bytes is quicker than updating a larger row. But not so much as you’d notice, usually. Unless you have a whole heck of a lot of settings…

The theme mod functions are probably due for optimization overall, certainly, but nevertheless you should still use them instead of get_option and such because child themes.

The problem with using options rows directly is that you are using them directly and using specific key names for your settings.

If I have a theme called “AAA” and I make a child theme of it called “BBB” for use on another site, then my “AAA” theme might use an option named “example”. When I update one site, and it updates my option, then the same option will now apply to my child theme. What if I didn’t want it to do so? What if I wanted the child theme to use a different set of option settings?

Theme mods, by including the actual theme name (and not a hardcoded value) as part of the key ensure that each “theme” on the site uses its very own set of settings. I can switch back and forth and the settings don’t transfer between them, they stay how I set them. Simpler, more obvious, more intuitive.

And if some future core change or plugin modifies how theme_mods work, then you will automatically get the benefits of that without any changes. Wrappers are always going to be slower, that’s unavoidable, it is the nature of wrappers. Nevertheless, you’re still writing PHP code, not machine language. We use wrappers like this to simplify things and separate functionality. Themes should not need to know, or care, how their options are stored in the database, or how the naming works. The theme_mod functions provide a simpler solution that is cleaner.

Leave a Comment