Isn’t it true that, when you (start to) develop WordPress websites for clients, and you host them yourself, you find yourself in a situation where you need to know a lot about “stuff” other than WordPress development? In this optimizing WordPress hosting post, I provide 9+ practical tips for you to improve WordPress hosting performance. Especially useful if you plan to develop and host WordPress websites yourself.
Learn how to optimize your WordPress hosting environment
WordPress optimized hosting is a subject on which a lot is written about. And therefore, this post is not about where to host your WordPress blog, or who offers the best WordPress hosting. This post is for you developers, what you can do to tune & optimize your WordPress hosting. Because for the best performing WordPress, you need to optimizing WordPress and WordPress hosting.
Or any other PHP web application for that matter.
This post is not about setting up high-availability, fail-over, clustering, IIS versus Nginx versus Apache, RAID 1, 5, 6, 10, different types of storage, and so on. It’s about solving performance issues! This post tackles most of your performance issues, by explaining important configuration settings to use for PHP & MySQL, server, security, and so on.
When reading Facebook groups like Advanced WordPress (AWP) or WordPress Development Stack Exchange, you often find questions like:
Will it affect the performance of the site if we increase the number of records inwp_posts
table by 10000 records? At this moment there are 200 posts.
Of course it will affect performance, doh! :) But, you can do a lot to optimize & tune your server/VPS and WordPress hosting.
Server hardware & separate web and MySQL services
One of the most important tips I can give you: separate services.
Whether you run your WordPress blogs on a VPS or bare-metal server, make sure you separate different server types and services. A lot of problems arise from having both Apache/PHP and MySQL on the same server, because MySQL loves memory. Approximately 80% memory needs to be available to MySQL.
My advice for you is to separate them to two servers, dedicated and optimized for their purpose (web or MySQL). Sure it’ll cost you an additional $10/m for an extra DigitalOcean droplet, but trust me: it’s worth it.
Isn’t it true that, when you (start to) develop WordPress websites for clients, and you host them yourself, you find yourself in a situation where you need to know a lot about “stuff” other than WordPress development? These 10 practical tips helps you tackle the most common performance issues.
MySQL optimization
As always, to tune MySQL you need to run an as high version of MySQL as possible. That means running MySQL 5.7, MariaDB 10.1 or Percona Server 5.6, at the time of this writing. Some MySQL administration experience is recommended for optimizing these settings.
InnoDB storage engine
Make sure your MySQL database tables are using the InnoDB storage engine. Nowadays MyISAM is outdated, just like PHP 5.3/5.4, .NET 3.5 and Windows Server 2008/2003 are. All MySQL optimizations are for the InnoDB storage engine, so switch to that and convert MyISAM tables to InnoDB.
InnoDB Disk I/O performance
First, starting with MySQL 5.5, InnoDB disk i/o performance can be greatly improved by increasing the innodb_write_io_threads
and innodb_read_io_threads
settings in your MySQL server’s my.cnf
file. These are very important settings.
Secondly, from MySQL version 5.5.4, you can divide the InnoDB buffer pool into multiple instances with multiple innodb_buffer_pool_instances. However, one important detail to remember is:
This options takes effect only when you set the
MySQL InnoDB performance improvement: InnoDB buffer pool instancesinnodb_buffer_pool_size
to a size of 1 gigabyte or more.
This means that when you are dividing your InnoDB buffer pool into 6 instances, you’ll need at least 6 GiB RAM. Please note: innodb_buffer_pool_instances
is disabled in MariaDB 10.5, and removed from MariaDB since version 10.6. It is still available in Oracle MySQL though.
MySQL query cache
MySQL Query Cache is deprecated as of Oracle MySQL 5.7.20, and is removed in MySQL 8.0, but it is still available in MariaDB. But I wouldn’t recommend using it now, see it’s limitations and there’s more information in MariaDB’s blog post Flexible MariaDB Server Query Cache.
RAM, SSD, and CPU
As said, MySQL loves memory (RAM). Make sure your server has plenty of it, and some more. About 80% of the RAM needs to be available for MySQL, and when you start dividing Innodb_buffer_pool_instances, adding query-cache, and various buffer sizes, RAM consumption increases rapidly.
Because SSD offers the best read/write (disk I/O) performance, SSD’s are a must too. If you can, switch to NVME disks.
If you don’t need MySQL’s binlog -or binary log, then disable it. Having MySQL’s binary log enabled will increase read/write operations on your disk, decreasing performance. Do enable the slow query log to identify slow running database queries.
The following example enables the slow query log for queries running three (3) seconds or more:
slow_query_log = 1
long_query_time = 3.000000
slow_query_log_file = /var/log/mysql/slow.log
Code language: plaintext (plaintext)
Through this MySQL slow log, I once found that the autoload column of the wp_options table wasn’t indexed. You can fix that easily too: wp_options table autoload index.
Don’t save on CPU power, because MySQL likes to use the CPU for heavy calculations as well.
Webserver optimization – PHP
No Apache, Nginx or IIS optimizations here, as I feel the webserver is not often the bottleneck when a WordPress site is slow – but maybe you have a great tip for this? Share a comment!.
PHP Optimization
As with MySQL versions, go with the highest possible version: 5.6.18, or preferably 7.0.3 (at the time of this writing), if all your code is PHP 7 compatible. Some PHP settings need optimization too, I discuss them below:
PHP OPcache
Zend OPcache PHP extension is in PHP nowadays, so why not enable OPcache and use it? I recommend you do. Wait, did I stress out you should enable OPcache? In your php.ini
verify the following line is not commented out:
zend_extension = php_opcache.dll
Code language: Apache (apache)
You have to properly configure and optimize OPcache to take fully advantage of this opcode cache.
For IIS, set up WinCache and be sure to disable WinCache opcode cache in favor of OPcache’s opcode cache:
extension=php_wincache.dll
wincache.ocenabled = 0
wincache.ocachesize = 0
Code language: Apache (apache)
The .dll-part comes from my Windows Server hosting environment. Because of slow development, I stopped using WinCache on our web servers. OPcache is good enough, even on Windows Server.
Be careful when enabling WinCache server-wide though, it might consume all available memory.
PHP realpath_cache_size
The PHP realpath_cache_size setting sets the size of the realpath cache to be used by PHP (e.g, the file locations on disk). Increasing realpath_cache_size
can improve PHP performance a lot, and this value should be increased on systems where PHP opens many files. But you have to test and retest the amount of open files to properly set this directive.

WordPress optimization
The following section will give you some quick tips on how to improve the speed of your WordPress website.
Optimization is key.
- Check out my WordPress and MySQL categories to learn more about various WordPress and MySQL optimization techniques:
- For example: index autoload column wp_options table.
- delete transients regularly (automatically using Pressjitsu’s wp-transients-cleaner)
- delete post revisions regularly, delete spam comments and meta-data too
- Optimize WordPress database tables, in the background using a cron or must-use plugin
- Move the database from MySQL to Elasticsearch, especially with large WooCommerce ecommerce WordPress shops. Not only is Elasticsearch much faster than MySQL, it also provides and/or searches that are not possible using the normal WordPress MySQL search (like select all products with tag A and tag C, but not tag B or E).
- Use Redis as a full page cache, or install Varnish Cache and deploy it in front of your web server. (Core Caching Concepts in WordPress is a great article introducing you into WordPress caching – “Caching concepten in WordPress: wat is caching en hoe maakt dit WordPress sneller?“, is my Dutch translation on ITFAQ.nl). I once created a DIY CDN using Varnish Cache and Bind geo-location DNS on Digital Ocean droplets, to take Sysadmins of the North global.
- Install a cache plugin like WP-Super-Cache or Cache Enabler (they’re the cache plugins I prefer, but there are many other cache plugins out there). With WP-Super-Cache and Cache Enabler you can speed up WordPress by serving gzip compressed files.
- Use SSL in WordPress, it’s the de-facto standard nowadays!
Are you looking for rock solid, eco-friendly, WordPress hosting? Look no further! UmbHost got you covered, offering hosting services for websites and businesses of all sizes.
Enable GZIP compression in WordPress .htaccess
The easiest way to enable gzip compression in WordPress, for your images, CSS and JS files, is to add these lines to your .htaccess file in the root WordPress folder:
## ENABLE GZIP COMPRESSION ##
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
## / ENABLE GZIP COMPRESSION ##
Code language: Apache (apache)
If your server supports it, enable BROTLI compression instead of gzip. Set an Brotli output filter in .htaccess
:
SetOutputFilter BROTLI_COMPRESS
Code language: Apache (apache)
Caveat: be aware that not all plugins and external optimization sites / services recognize Brotli compression yet. You may get notices about not having gzip enabled…
Leverage browser caching
Add the following lines to your WordPress .htaccess to enable browser caching for resources:
## ENABLE EXPIRES HEADERS - LEVERAGE BROWSER CACHING
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
# Web feeds
ExpiresByType application/atom+xml "access plus 1 hour"
ExpiresByType application/rss+xml "access plus 1 hour"
</IfModule>
## ENABLE EXPIRES HEADERS - LEVERAGE BROWSER CACHING
Code language: Apache (apache)
Enable HTTP Connection keep-alive
Set the following header directive in your .htaccess file to enable HTTP Connection keep-alive:
Header set Connection keep-alive
Code language: Apache (apache)
Remember that for everything you add to your .htaccess file to optimize WordPress, you don’t have to install a plugin! This saves on PHP files and CPU processing time. Win win!
WordPress development tips – DevOps :)
An area I’m not very experienced in, but here goes… A tip: always (try to) follow WordPress development guidelines. For optimized PHP code, check out the PHP Benchmark tests, it’s a real must!
Also, it’s recommended to try to avoid catching exceptions in PHP. Exception handling can cause a performance penalty: Checking the performance of PHP exceptions, Speed performance of Trying and catching Exceptions in PHP.
Try to create your own Windows 11/10 and WSL 2 DevOps environment.
Conclusion
When you develop WordPress websites for clients, and you want to host them yourself, you find yourself in a situation where you need to know a lot about systems administration “stuff”. Completely different topics than WordPress development. Like MySQL configuration, web server configuration, PHP settings, server security, performance & optimization, and so on.
I often receive, and read about, questions from developers saying their hosting performance has degraded drastically over the course of time, and have no idea how to resolve the performance issues. In this optimized WordPress hosting post, I provided 9+ important and practical tips to improve your WordPress hosting performance. This post tackled most of your performance issues by explaining those important configuration settings for PHP & MySQL, server & security. Especially useful when you plan to host WordPress websites yourself.
As you might have noticed, MySQL optimization is very important for your hosting environment. If you have a valuable tip, please do share! And don’t forget to share this post with your friends and co-workers, thanks!
Your tips is very correct. I have also few tips(https://www.postnidea.com/6-tips-for-optimized-and-secure-wordpress-during-development/) if we remember during the time of development then it will help in optimization as well as in performance.
Thanks a lot for such a detailed explanation on how to optimize WordPress. Thanks
Thanks a lot. I found this guides so much helpful.
Thanks for the great article.
i have a few questions regarding opcache on php 5.x up to 7.x, i read that php-fpm doesn’t play well with opcache in shared hosting environments, allowing one site to read another site’s files. This is because opcache=on means all sites share the same memory pool, and php-fpm doesn’t check for ACLs. My question is whether the same security issue occur on IIS shared hosting environment where is opcache is a shared memory pool? Does opcache run in the context of a site’s ApplicationPoolIdentity which check for ACLs before serving from the shared opcache memory pool?
I know a way of testing by using url_fopen on php to test if a crafty file on one site can access files of another site because of opcache enabled. Solution would be to turn off url_fopen like in most production envs but that still doesn’t eliminate all possibilities at least in a shared hosting for environment.
Hi Leo, thank you for your interesting question!
Yes, under rare circumstances it was possible to get control of OPcache memory files, under PHP 7 though. You may want to read Binary webshell through OPcache in PHP 7 for more information on this. This only was an issue when file based caching is enabled with
opcache.file_cache=
. On the Windows IIS web servers I manage, it is kept in memory.Furthermore, it is recommended to ensure file permissions are properly in place, so website/user_A cannot access temporary files created by website/user_B. Even when they share the temporary folder. Where possible you must provide a dedicated temporary location on a per website/user basis.
Where you discuss “install a cache plugin like WP-Super-Cache” you could add a link to your article with the rewrite rules for WP Super Cache – https://www.saotn.org/valuable-wordpress-snippets/#wp-super-cache-rewrite-fix
Rewriting to the static files offers a huge performance gain for five minutes work. And you don’t need to dig into the hardware setup or software config.
I wish more of my resellers would do this instead of hammering MySQL over and over.
Hi Chris, thank you for your comment and suggestion. I kind of forgot about that link :-) I just spotted an error, there can’t be two or more HTTP_USER_AGENT lines when
logicalGrouping
is set to “MatchAll”. I’ve fixed that now.All you can do is pointing your resellers to information like this and urge them to setting it up.
There are more WP-Super-Cache enhancements you can make: how about minifying the static supercache files or serve gzip supercache files on IIS (rewrites included). I also did an enhancement request for
web.config
support in WP-Super-Cache: issue #93 on GitHub.Jan, Pagely is hiring. Put your knowledge to good use? https://pagely.com/careers/
Hi Joshua,
Thanks(!), but no thanks. I’m (very) fine where I’m at now :-)
Nice article. It’s really helpful for people. Thanks! See my work http://www.wpthorp.com/
Really good article, it tackles some important topics. I feel like the “avoid catching exceptions” part is unnecessary, It’s the kind of micro-optimization I would never recommend.
Hi Milos, thank you for your comment!
I’ve had my thoughts and questions about including the “catching exceptions” part. And true, it’s not really something for WordPress, but more for general PHP. I feel it can make a difference, especially when done wrong (I’ve tested the examples a few years ago and could reproduce the results, I don’t know if the exception handling has improved in PHP since).
Hello Jan, your post is interesting. I have to say here that you have done a really good job by publishing the article above. This is really going to help a huge audience searching for such information. Have to seen Cloudways? Its a super fast managed cloud hosting platform. You can explore all its features by getting started for free. managed WordPress hosting
Thank you for your comment Jamil. I’m familiar with CDN services like Cloudways. A CDN can be a great addition for one’s hosting environment.
Cloudways isn’t a CDN, they offer optimized WordPress hosting servers of four popular clouds (DigitalOcean, Vultr, GCE, AWS).
The stack they have is Nginx, Varnish, Apache, Memcached, MySQL, PHP 5.6.