Maximum option and transient key length

If you work with WordPress you’ve most likely worked with its options. The WordPress Option API is pretty self explaining and easy to use. The WordPress Transient API is a little less known but also a powerful API that’s definitely worth taking a look at if you’ve never heard of it before.

Options

If you look at the Codex page for the add_option function and look at the Parameters you find the following description for the first parameter: $option

(string) (required) Name of the option to be added. Must not exceed 64 characters. Use underscores to separate words, and do not use uppercaseā€”this is going to be placed into the database.

The most important part of the description is ‘Must not exceed 64 characters’, they should make this bold and uppercase. What happens when your $option (key) exceeds 64 characters? It’s truncated to fit, saving the option with a different key than you’ve set as parameter. This results in not being able to retrieve an option with the same key as you’ve set it if the key exceeds 64 characters.

A small example of how this can go wrong:

I understand the need of a maximum length on the option key but there’s no error or notice when the key exceeds 64 characters. This can cause some serious hard to track down bugs.

tumblr_liuck9FYQZ1qcin7r

Transients

Transients, like options, also have a maximum character key length and like the options there’s also no error or notice when exceeding this length. The maximum length for transients differs to the maximum length of options though, there’s even a difference between expiring and non expiring transients. The key of a transient that doesn’t expire has a maximum length of 53 characters. The key of a transient that does expire has a maximum length of 45 characters. Please note the difference between the two because when you attempt to set an expiring transient with a key length between 46 and 53 characters, the transient will store but will be deleted before it can be returned by get_transient due to the missing _transient_timeout_ option.

Like I’ve showed in the option example above, if you try to store a transient with a key longer than it’s maximum character length, the key will be truncated to fit. This results in the transient being saved with a key different that the key in your code. For transients this is especially tricky because transients are often used to store something for a longer period of time and validate it at some point in the future. So you add a transient by using set_transient, the function will return true and you think everything works. Then when you check your transient in the future, it’s not there. Annoying bugs to track down, very annoying bugs to track down.

A transient key length gone wrong example

Imagine having a WordPress plugin that contacts your own server to log some settings*. Let’s say we do this on an admin page load with a maximum of once every 4 hours. To ensure we only do this once every 4 hours, we use a transient. We generate the transient key automatically based on our plugin slug appended by ‘last_logged’, to ensure we’ve got a unique key and prevent conflicts with other plugins. The problem, this automatically generated key exceeds the maximum transient length and is therefor saving with a different key than the key that’s in your code. So what will this easy to make error result in? It will result in your server being contacted on every admin page load, terrible for the performance of the plugin and when implemented in a populair plugin close to a DDOS attack on your own server.

* This is known as phoning home, only do this opt-in.

Core changes

There’s a 4 year old Core Trac ticket that identifies this problem and offers a solution. The patch adds a validation to both functions that check the length of the key and displays a warning when they’re exceeded. The ticket is (again) pretty active so fingers crossed this will make it into Core one day.

Using options and transients and not sure what the length of the keys are you’re using? Be sure to check them! I hope this helps any one out reading this. Missing something? Found a problem? Got an improvement? Please let me know in the comments below.

Related Posts

Powered By Related Posts for WordPress
Click Here to Learn More About Related Posts for WordPress

3 thoughts on “Maximum option and transient key length

  1. This is a very easy thing to fall prey to if you are setting transient keys based on dynamic data. If you don’t cap what length of dynamic data can be entered, the problem can be trigged very easily.

  2. Hi Barry – I’ve used this as a reference for years. Thanks so much for writing it. As of 4.4.0 the option_name column supports 191 characters and transient keys can be 172 characters long. See https://core.trac.wordpress.org/browser/tags/4.4/src/wp-admin/includes/upgrade.php#L1619 and the updated doc for `set_transient()` https://developer.wordpress.org/reference/functions/set_transient/

Leave a Reply

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