Abusive Usage of Transients in WP Options Table
Abusive Usage of Transients in WP Options Table
“Slow WordPress Website and Dashboard”
Problem Description
WordPress is using wp_options table to store data about the site itself, data classified as Options and Settings.
Data Stored in wp_options vary, following is a list of some:
Data related to the setup of the website
Data related to the administration of the website
Data related to the plugins installed on the website
Theme options and settings
Default view of site (main landing page)
Pages view settings and options
Posts view settings and options
Setting and options added via plugins
Cached objects
Transients’ data is stored in wp_options table; transients are entries such as RSS feed data, last cron run information, and temporary cached objects. They are stored on wp_options with option of time lifespan to delete automatically from wp_options table.
WordPress Plugins Developers enjoys the idea of having easy to use API like Transient API to store temporary data as well. Transient API is similar to Options API with extra feature to set time lifespan.
Great flexibility and fluid API developed by Automattic (WordPress Creator Company) as part of WordPress core, to provide easy to use tools for developers who develop WordPress plugins. That flexibility resulted in over usage of transients entries in wp_options table; typically, any over usage of something without planning and pre-design consideration leads to problems and cause failures.
By default, transients’ entries creation via Transients API does require lifespan time parameter; it is for automatic deletion of transients’ once lifetime span expires. By design, transients should not store data that cannot be automatically re-created.
Transients is perfect use for time consuming operations that takes long time to generate, data that have dependency on other services outside website like social data. For simple database queries, and small datasets, avoid using transients.
Good use case of transients on WordPress plugins is to cache time consuming data calculation, cache requests results from social media plugins for reuse during specified period instead of requesting frequent updates from Social Media providers every time a user hits the website.
Behavior of Problem Development
WordPress will scan wp_options for all options and settings during first start; cache them in memory to reduce the number of times it connects to the database to retrieve them repeatedly. Transients as well are loaded and cached in memory. WordPress core does not always delete expired transients due to some design consideration or bugs on its core, plugins that generates transients not necessarily developed efficiently to handle expired transients. They keep growing and growing in wp_options table without limitation.
The failure of WordPress or inefficient designed plugin to remove expired transients causes WordPress website backend server performance degradation, every time a person hits a page or update something on the WordPress website.
Accumulated transients’ turns using WordPress Dashboard as nightmare, as the Dashboard heavily depend on options and settings more than published pages and posts. WP Dashboard will become slower and slower by the time as transients are injected into wp_options without proper removal upon transient lifespan time. WordPress Dashboard will scan all transients, settings, options from wp_options table always, and causes more pain to website administrators.
Another angle of the problem development is resulting from the technology used to store transients objects content in wp_options table; it is JSON serialization. While JSON parser is very strong in WordPress core, it is still adding extra overhead to the CPU each time a transient parsed in-memory. By far querying the database is much faster than parsing large datasets of JSON objects. Parsing JSON objects of large size datasets consumes multiplied amount of memory of the actual JSON object, while querying database engine seeking same result is much faster and efficient.
Abusing the flexibility provided by software core frameworks as WordPress Core causes drawbacks over the time rather than providing ease of use.
Developers are not equal when it comes to the skill-set in designing good solution; the usual behavior of beginners in development is to use the simplest approach of writing code rather than drawing a solution design to develop new plugins with its features for WordPress.
Performance optimization, effective memory usage, and well-designed solution are necessary elements to avoid getting into such trap.
Transients’ accumulated storage on wp_options could go larger than the entire WordPress database tables other than wp_options, which defeat the purpose of using them completely as they turn to be slow to parse and consume.
Transient API Functions
These are the only six functions provided by WordPress core to use and consume transients.
Set/Get Transient
set_transient()
get_transient()
set_site_transient()
get_site_transient()
Delete Transient
delete_transient()
delete_site_transient()
Transients’ API is simple to use for developers, however proper design-consideration with effective handling of stored transients’ will result in good designed solution.
Accumulated Transients’ Temporary and Quick Solution
To solve the issues caused by accumulated transients’ objects stored in wp_options table, a website administrator need to do regular check on wp_options table, and remove stored transients. Clearing wp_option from transients is completely safe job; WordPress and Plugins will create new entries once required.
Using PHPMyAdmin or CLI with the following commands is useful:
Command to check the number of stored transients in wp_options table:
Select count(*) from (select from `wp_options` where `option_name` like '_transient_%')
Command to delete transients:
delete from `wp_options` where `option_name` like '_transient_%'
There are few WordPress plugins to manage transients, those plugins are out of the box solution to manage transients and other entries in WordPress website installation.
Good Solution
To handle the problem of accumulated transients in wp_options table, it is the responsibility of the developer to verify previously stored transients that relates to the plugin and remove them from wp_options table using the Transient API.
The usual behavior by developers is to query wp_options table for specific transient and use it without verifying content (verifying content means querying database again), which conflict with the purpose of caching transient objects into memory. However, the developer can be more creative by validating transient lifespan time and relevant object actual availability in memory or database. The tradeoff between validation from the database and using another technique to validate transient validity is performance improvement and extra mile of careful solution design and coding.
As a developer, design your usage of transients to predict the worst, which is accumulated transients over the time. Quick technique, is to name your transients with time stamp based on your requirements, it could be hourly basis ordaily basis; then store your transient keys in using another option entry in wp_options as an array of all your plugin specific transients. After that, once you encounter the need to create new transient with updated time stamp, create the new transient, store it in wp_options using API, then invoke a cleaning function to go through previously registered transients and delete them, and do not forget to update the stored array. Furthermore, once you could not find the special entry array of your stored transients, remove all plugin related transients and create them again along with the array.
If you need full description of Transients API and sample code, please read SCOTT FENNELL blog post on css-tricks.com The Deal with WordPress Transients, it is one of the best and very useful.
Ultimate Solution
Developers need to build solution-design skills; they need to follow some of the best practices and guidelines to develop WordPress plugins.
WordPress.org official website provides some guidelines as best practices; nevertheless, they are just guidelines for developing plugins.
SmashingMagazine.com illustrated good article on best practices as well.
If you do not have time to develop plugins’ using structured approach and well-crafted methodology follow the following guideline:
Preparation Stage:
1- Prepare multiple separate WordPress installations for development and testing aside from the production installation
2- Set single isolated WordPress installation for development and light weight testing
3- Set another WordPress installation with large amount of data
4- Use the light weight installation for development purpose
5- Use the heavy weight installation for stress-testing
Development Stage:
1- Develop a prototype to prove your idea works
2- Test your developed plugin and make sure to handle edge cases
3- Deconstruct your functions again into small pieces with absolute specific minimal job per function
4- Write one function for writing entries to the database
5- Write one function for writing entries to wp_options
6- Do not write functions to update database or transients with hardcoded names
7- Use naming standard and good naming convention
8- Reduce your dependency on transient usage and create your own tables (disk storage is cheap)
9- Stress test your plugins for worst case scenarios and edge cases
10- Write code with performance optimization in mind
11- Do not write query to retrieve all entries from the database like (select * from table)
12- Use special flag on development and test environment to log execution path, make sure to switch-off this flag in production website.
Testing Stage:
1- Use performance monitoring plugins like GoDaddy.com P3 (Plugin Performance Profiler)
2- Overload the testing website with other plugins and check performance impact on your plugin
3- Read the log thoroughly and make sure execution path is doing its job
4- Let others to test your plugin
5- Test as dummy person, try to make mistakes
Final words
Coding is fun make it more fun by delivering quality.
Author: Jawad Alalawi
Information Technology Professional specialized in Financial Payment Services, Risk Management, Information Security, and Compliance. Experienced in solutions development and implementation, and technical writer. Email contact (sjawada5 at gmail.com)
Technology Specialist & Consultant