Updates!

Running high traffic sites means WordPress optimization is crucial. I spend a lot of time reading, thinking, and testing configurations to constantly improve the performance of my WordPress sites, as well as the server load. When sites are getting over 100,000 visitors per month, every millisecond counts. Whether you are running a blog, enterprise site, or local business, ensuring your visitors and customers have a fast speed can make all the difference between someone who clicks away and someone who stays for a while. This post is formatted in a way which starts with the lowest hanging fruit and gets harder and more complex the farther down you read. Begin your WordPress optimization from the top and begin measuring results!

If you’re reading this and realize its simply more than you feel comfortable taking on, or want to hire a WordPress optimization expert, send me a message for hire and I’d be more than happy to speed up your website!

Last Updated: June 14, 2016

Disclaimer: This post includes affiliate links for some of the products mentioned, however, I am not being compensated to endorse any of the products.

WordPress Web Hosting

The first step in WordPress optimization is choosing a good web host.As a web developer, I’ve used and been exposed to a huge variety of web hosts. I’m ultra-picky and want the very best available for my budget. I use iWFHosting.

A lot of people running WordPress website are going to be on what’s called “Shared Hosting” plans. While these are not inherently bad, a lot of times web hosts overload the amount of customers on a single server, causing a slowdown for everyone. With the amount of sites and traffic I handle, I’m beyond the shared hosting spectrum. I run a VPS, or virtual private server. Running a VPS allows me to quickly scale on demand, as well as better manage backups and testing configurations.

Beyond Hosting – A CDN for WordPress

With a good web host selected, the next step is getting a content delivery network, or CDN setup. I ended up with MaxCDN for several reasons. The first being a lot of plugins support integration with their API. The second being their support and speed were excellent. I’ve bugged them multiple times with silly questions and their expertise has always proved worthwhile. With a Pull Zone setup, these are the ideal settings I’ve found for a WordPress site running SSL/HTTPS.

WordPress Optimization

With a good server setup in place, now we can move on to actual WordPress optimization. The first step is getting some plugins in place to do some automated tasks. Then, we’re going to analyze what the WordPress site is currently loading, and then install a few more plugins and optimize the theme.

WordPress Plugins to Help Auto Optimize

Better WordPress Minify This minifies and combines your CSS/JS files, and works with MaxCDN. Combining files equals less HTTP requests and a faster load time. Once the automatic configuration is in place and the rest of the optimization of this section is complete, you’re going to want to come back and revisit the advanced and enqueued files section to start moving scripts to the footer and test until something breaks. Moving js files to the footer means portions of the site won’t stop displaying as scripts download and render. These are the settings I am currently using on this site.

Comet Cache This is one of the best automatic non-configuration-required caching plugins I’ve found and used. If you have users visiting your site whom are logging in, you’re going to need the Pro version. This is a common pro feature across a lot of caching plugins. For everyone else, these are the only options you’ll need, and this is what will display in the source code:

EWWW Image Optimizer Optimizes all of your images and PDFs into the smallest size possible without sacrificing quality. This means your assets will load much faster. The only settings I usually touch on this plugin are Deferred Optimization and I use a bit more intense optimization levels. This is so I can work on posts and upload images faster, and I know when my wp_cron (will get to this soon) runs every hour, the images will be optimized.

Heartbeat Control WordPress has an API that autosaves drafts which by default goes every 15 seconds. This plugin lets you change the frequency to every 60 seconds. There is an option to disable where it runs, but I kept it everywhere so future plugins or features aren’t affected. I could totally see myself spending an hour trying to figure out why a plugin doesn’t work, only to realize its a setting here.

WP-DBManager Over time, junk data accumulates in the database. This plugin can automatically run an optimize and repair command every set amount of days – I do 3 days – and helps keeps database requests running smoothly. I ran an optimize command on a client’s site that had been running for several years without any maintenance and got the database size from around 90 megabytes to under 10. That’s a lot of junk. You can also use this to run automatic backups of the database.

Analyzing Your WordPress Performance

Head over to either GTMetrix or Pingdom. Or, do both and see how the different companies analyze your site, cause you’re just as particular as me.

This is what a typical graph will look like as I optimize a WordPress site, testing as I go. I was already familiar with my own site, so the process didn’t take as long, but it generally takes anywhere from 2-6 hours to optimize a WordPress site before even getting to the server itself.

Going off the GTMetrix waterfall view or the Pingdom File requests view, the first thing I look for is how many fonts are being loaded. A lot of times themes or plugins load multiple themes. Your site should have a consistent brand and look, so this will accomplish several things. Removing extra fonts from loading will improve your branding, as well as reduce the number of requests for your site to load.

Next, look for any 404 errors that are popping up. Go and find out what is missing, and fix those. For example, in testing this site, I realized I had a 404 image that was causing a huge slowdown. Oops.

I like to check out the 200 response code request. This is going to be the first one in the list and the most crucial. This is also where caching will shave off a lot of time.

Keep analyzing the waterfall as you go, and take care of different items that seem out of place to you. Try playing with BWPM to get to the ideal configuration.

Remove, minify, or modify one item at a time, flush your cache, and retest. If something breaks, its easy to undo what you just changed, versus guessing over multiple items. This is the most tedious of the entire process and takes a lot of close scrutiny. You’ll also have a much better understanding of how your website works and dependencies when you’re done.

High Traffic Websites and wp-cron.php

Every time a visitor goes to your site or loads a page, wp-cron.php is triggered. This is WordPress checking to see if it needs to do anything. This includes checking for updates, scheduled posts, email notifications, or a number of other tasks. When your website is getting several thousand or more hits per day, this uses up resources unnecessarily. Disabling the default wp-cron.php will be a lifesaver.

Open wp-config.php and add the below code. I usually place new code near the debug function.

define('DISABLE_WP_CRON', 'true');

Now, login to cPanel and setup a Cron Job to hit wp-cron.php every hour. Change the username to your cPanel username and make sure the path is correct, especially if you’re on a subdomain or subdirectory.

cd /home/CPANELUSERNAME/public_html; php -q wp-cron.php

Database Bloat and Revision Control

Every time you save a post, WordPress saves a version of that post in the database. These are all accessed via the Revisions interface. WordPress will keep saving every version indefinitely. I got up to 48 revisions on this post alone in writing the initial spec. Figuring out an appropriate number of revisions for your style and setting that will reduce the size of the database. I personally set mine to 7 via wp-config.php:

define('WP_POST_REVISIONS', 7);

Miscellaneous WordPress Notes

Too many plugins equals a slow site – This is a false myth. I currently have 50 active plugins on this site, and another 20 or so which are inactive. I get load times in under 3 seconds, and often under 1 second.

wc-ajax=get_refreshed_fragments – This is something which will show up as a slowdown if you’re running WooCommerce or haven’t installed the Heartbeat Control plugin. Its probably a bad idea to disable completely. I run WooCommerce on this site, and the only way to speed it up significantly is to disable the ajax-cart option here: /wp-admin/admin.php?page=wc-settings&tab=products&section=display

Remove extra fonts being loaded – If you can’t find where fonts are being loaded, or if the theme is loading extra fonts on its own, removing them via BWPM is the way to go.

Themeforest themes are slow – Would you be surprised to learn I am using X and a child theme? Sure, there are bad themes out there, but it isn’t always the theme causing slowdowns.

cPanel WordPress Optimization

Optimize Website – This generically named setting is where you can enable compression/gzip of your content.

For the more advanced readers – Zlib for compression is another good option when configuring WHM, although I’m not sure what PHP7 support is.

While not directly related to WordPress speed, its a good idea to make sure your DKIM and SPF records under Authentication are valid. These records help fight spam and let’s other mail servers know that your e-mail is authentic.

Advanced WordPress Optimization

Alright, time to take a break, make a fresh brew of coffee, and get ready to dive into the heavier and more advanced areas of getting the most performance out of your WordPress website.

Disclaimer and notice of imminent danger: Modifying settings in WHM could very well render your enter server useless. This guide includes items which can break stuff. If you feel unsure of a setting, or want a better understanding, ask your web host support or search for more information. I am only providing a very superficial overview on many of the following items. WHM supports Dry Runs of some of these settings, particularly EasyApache – take advantage of this, even if it takes you longer.

My current setup is a VPS with 8G Ram, 4 Xeon CPU cores, SSD drive, SolusVM, CentOS 6.8, and WHM56. If your setup is radically different, you may encounter problems. Feel free to ask your web host if these settings are safe.

WHM WordPress Optimization

There is a lot to adjust within WHM. I’m going to go down the menu and just list changed settings related to WordPress performance. There are plenty of other settings you may want to change for security, or based off of a specific website environment.

If there is another setting within WHM I missed which has impacted your WordPress performance, comment with an explanation and let me know to add it. Most of the heavy lifting was done prior to this point, and now that we are in WHM/PHP configurations, I’d love to have some input from others on further performance tuning.

Again, only settings which have been changed from their default and related to WordPress optimization are listed here.

Apache Configuration

Global Configuration

Piped Log Configuration: Enable Piped Apache Logs

PHP7 Configuration

As of the time of writing this post, PHP7 and EasyApach4 are not quite released for production. According to support, EA4 is ready for 95% of the people. Based off outstanding bugs, I felt they didn’t affect my usage, therefor it was reasonably safe to upgrade. If you read this and you’re running WHM 58, then EA4 is ready for you!

EasyApache4

To install EasyApache4, follow this link. If something goes wrong, you’ll want to follow the same link to uninstall.

Below is my current configuration. I did not include versions for security reasons. I’m probably using whatever is listed as the latest.

Comments 22

Great information here, I love reading about other webmasters efforts to achieve page speed optimizations.

I did have a couple questions.

Why not use W3 Total Cache or WP Rocket for example to do your minify and cache functions in one plugin versus two separate? I know most people new to W3 have a hard time with the settings etc, however, once you understand that plugin you really can do a lot in a very short period of time. WP Rocket also is a great solution (depending on host) that runs all that you mentioned right out of the box with one plugin.

In regards to WP-DBManger, I highly endorse that plugin as well, I love it and makes working with the DB so much easier.

In the cPanel/WHM section, do you find that the compression messes with the minification of elements on your sites or have you not run into any issues in that regard?

I’m so glad you brought up W3TC! That plugin used to be my default and I had a couple configs I imported based on the type of site and was pretty happy. However, on some sites I discovered W3TC was slowing down logged in users to a crawl to the point where productivity was horrid. I started exploring other cache plugin options and settled on Comet Cache. Its done a spectacular job on the highly trafficked sites and is very friendly to not needing configuration. I don’t think I tried WP Rocket, but now I’d be interested in checking it out compared to CC. One thing CC cache does well is integrates with my CDN, without any additional setup or configuration. It seems to provide an awesome balance of function with ease of use. What’s your experience on backend speed with W3TC?

The compression in cPanel doesn’t make a difference – its a bit of redundancy with the plugins used, but it also ensures any files outside of WordPress get compressed. If people are hardcoding links to images/etc in theme files, cPanel will ensure the files are compressed.

Thank you for sharing your insights which is obviously the result of a crazy amount of work over a long period of time. You are going to save a lot of people a lot of grief! Just one comment on cache plugins – I’m using WP Rocket and I have found it to make a huge difference (like it better than all the others I have tried including W3TC, but I have not used Comet. I’m currently debugging an issue on one site that might be cache related but other than that, Rocket has been great. For image compression I typically use Photoshop and the ‘Save for web’ option and THEN further compress the image via the website: http://tinypng (which will do jpgs too). Google maps slows down a page I find and has some issues. I usually replace the map with a static image and a button. Way faster.

Great post mate, enjoyed working through the steps and cross checking my own new EA4 setup. Turns out something fundamental on my server was broken though…no idea what.

I upgraded to EA4, php7 (stripped the others), and used above config and hit provision…

Now the sites seem fine but trying to add a plugin to a WordPress site is resulting in the dreaded “To perform the requested action, WordPress needs to access your web server. Please enter your FTP credentials to proceed. If you do not remember your credentials, you should contact your web host.”

Did the usual chown command and…nada…still broken.

Been at it for hours now.

Decided to provision a new server and move my sites over to it as this is driving me nuts (wish I had the time to faff and fix, sadly it’s a time consuming process so went for easier option)

Great post, thank you. Yip. must also add autoptimize in the list. Has been great on my site. Also using snippets plugin, to disble emojis, remove share counts (big saving), remove query strings, load only the font awesome essentials filter. also async javascript plugin. Also use webpagetest.org… seems to give the most conservative loading times. Also use wp optimize. I know how you feel things can get very frustrating… (my blog posts vanished a few hours ago in my dashboard for instance)…. but got my 100% google page speed and 99% yslow on gtmetrix.

It’s as a result of being anal… because the site used to be a little go daddy $5 website on their website tonight and get tons of leads and traffic. Which was actually as a result of content being written for the target market. Whereas now all the fiddling hasn’t achieved what the result should be… other than the joy in getting the 100% score.

Thank you, good detailed list wished I’d know about this a long time ago. I have to ask though, you mention as short list of the elements you have activated in Apache, I assume those are all the ones that are not active by default? As it’s a very short list, or do you mean you only run exactly those on their own? I’m still working with an earlier version of Apache, so I haven’t got a reference point as those aren’t in my current Easyapache set up. Or at least the naming scheme is different enough, to not make it obvious barring a few which are replacements for which. It’s confusing because some you listed are active by default, but the list itself looks way too short.

i like say any words….. Thank you so much for your good will to write detailed article to help us, simple people :D~ I install the php 7.1, and if your list my serve work´s fine… Frog strone media for me know now are seriously tech blog.

Great article. I didn’t realize that wp-cron ran every time a user accessed a page. I think disabling wp-cron should be automatic for every WP site. I will have to study the article a little more to determine what I want apply.

I went and checked out your link for iWFHosting. I really like their vps hosting. On the higher end, the offer better resources and price than my current provider. I took a quick look at their dedicated plans and they look good do. Have you played with their dedicated servers?

I also implemented another optimization tip I founf on another blog… Disable performance scuema, IUreally don’t know what this means but by implementing this tip along with the tips found at this blog, I now the 60-80% free memory on my 1MB VPS, previously I was getting constant outrages and memory shortage notifcations….. thanks a lot to all The quote from the other blog reads: “Optimize MySQL: By far the most impactful of the configuration tweaks we implemented (300mb+ reduction in idle server memory usage) For MySQL 5.6.6 +, turn off performance_schema . This is turned on by default in 5.6.6+ and seems to eat RAM for breakfast To disable performance_schema: Open my.cnf (typically @ /etc/my.cnf) via SSH or VPS admin panel » add the following line just under [mysqld] » performance_schema=0 Save/close my.cnf and restart mysql service”