Having a fast business website is essential for both Google ranking and overall conversion rate. Due to Kissmetrics, 40% of site visitors will abandon a page that takes three or more seconds to load. Earlier, the BBC calculated that they lost an additional 10% of users for every extra second their site took to load.
Your web hosting speed determines how fast it can process code, and how many visitors it can handle. Compare your website to a car. To make a car go faster, you either get a stronger engine and/or lighten the weight. For websites, the web server is the “engine,” and the code is the ”weight”. The goal is to improve our web server “engine” while decreasing code “weight”.
Changing your web hosting is one of the easiest ways to improve speed. Those of you on cheap $5/month shared web hosting will benefit the most from moving to a managed hosting service or even your own VPS. The difference will be night and day without any site changes. Moving from managed hosting to an optimized VPS or dedicated “bare metal” server will be another night-and-day jump.
The difference isn’t only in speed but also in cost (savings). A fast server can handle more visitors than a slow one. If your server can handle double the traffic, theoretically the bill can be twice as cheap. Not a big deal for a small site but what about a huge e-commerce site with a $1k/month server bill? 50% cost reduction sounds mighty attractive!
Tip: This guide uses great tips from The Ultimate WordPress Speed Optimization Guide written by Johnny Nguyen.
Each optimization suggestion below is marked with the required technical skill level and the estimated performance impact.
- SKILL:
- BEGINNER – can Google and follow instructions.
- INTERMEDIATE – working as a WordPress contractor.
- ADVANCED – programmer or server-admin.
- IMPACT:
- LOW – maybe 100-200ms difference. Possibly unnoticeable.
- MEDIUM – around 500ms difference.
- HIGH – 1 second difference or more.
Web Hosting Optimization Tips
- Choose a nearby data center location (BEG, LOW-MED)
- Choose the right website hosting service (BEG, HIGH)
- Choose a high-performance web server (INT-ADV, HIGH)
- Web server configuration (ADV, MED-HIGH)
- Disable unused services (INT, HIGH)
- Remove unused server modules (ADV, LOW)
- Use the latest PHP version (INT-ADV, HIGH)
- Recommended php.ini configurations (INT, MED)
- Use an updated MySQL fork version (INT-ADV, LOW)
- Convert MySQL tables from MyISAM to InnoDB (BEG, LOW)
- Tuning MySQL configurations (ADV, LOW)
- Server full-page caching (ADV, HIGH)
- Memory object-caching (ADV, LOW-HIGH)
- Use the latest HTTP protocol (BEG, HIGH)
- Content encoding (INT, HIGH)
- Control-panel (INT, HIGH)
- Use external DNS service (INT, LOW)
- Run WP-cron from your server (BEG, MED)
- Caging users & resource limits (ADV, MED-HIGH)
- Tracking down resource hogs (ADV, MED-HIGH)
Choose a nearby data center location (BEG, LOW-MED)
Obviously, you should pick a server location that’s closest to your visitors. Ideally, you don’t want your DNS ping time more than 100ms from the server to your visitor’s computer. There are many implications depending on your needs.
- Local businesses should get a server as close to their visitors as possible. Keep it within 100ms or less, within 50ms is better. Check ping times with WonderNetwork.
- The USA is about 80ms from coast to coast. Canada and Mexico are close enough as well.
- All of Western Europe is only 40-50ms, very close.
- Asia is within 80ms of most countries.
- India/Pakistan, Australia/NZ, and Africa are somewhat isolated. Local businesses there need a local data center. Even Singapore to Australia is borderline “far” by DNS standards (~150ms).
- South America can be an unreliable infrastructure. For that reason, many companies in Central/South America still use US-based data centers like in California, Texas, or Florida (Miami).
- If you have worldwide traffic (including Asia/Pacific) and no particular core region, I like the USA west coast as a perfect location for fast traffic to Europe and Asia.
- If you have only USA & Europe traffic and no particular core region, I like the USA east coast for fast traffic to Europe.
It’s also good to have a web hosting company in the same timezone as your core audience. That way they can (quickly) support or troubleshoot issues when most of your visitors are awake.
- Those of you thinking a CDN can make up for far server location (that’s not necessarily true!)
For those of you hunting for dedicated nodes, the best is the TIER-4 data center with four 9’s (99.9999% uptime guarantee). But good luck getting those guaranteed!
- Uptime calculator (99.9% uptime means 43min downtime per month).
- Nearest.host – cool site showing nearby server companies.
Choose the right website hosting service (BEG, HIGH)
- Shared hosting ($5-30/month) – fine for small sites and low traffic up to 100k hits/month. No access to server configurations.
- VPS/cloud hosting ($30-300/month) – great for medium sites and traffic up to 30 million hits/month.
- Dedicated (bare metal) server ($200/month & up) – great for large sites with TONS of traffic.
Buy the best that you can comfortably afford. A small website doesn’t need much power but it’s still noticeable when you get a better server and appreciated more than you think. Think of a new phone that opens apps just a fraction of a second quicker. You really can feel the difference and it improves user experience tremendously.
- Shared web hosting is usually slow because they stuff hundreds of customers/websites onto the same server (maximize profits). This increases slowdowns, unexpected crashes or server restarts, security attacks, and your email IP getting marked as spam.
- Shared hosting environments are also slow because they load many scripts/modules to maximize compatibility for as many users as possible. Without dedicated resources, your visitors end up waiting in line while the server is busy handling other websites first.
- VPS/Dedicated servers are faster because there are more resources available per account and your resources are serving only your websites. You have more control over your environment and can configure it for your needs. VPS/dedicated can be costly or difficult to manage for regular users. There are cloud-panel services to help manage it and also fully-managed services where they take care of everything for you.
- Those unable to handle the technical responsibilities of VPS can go for “premium shared hosting”. They don’t crowd the server as much but the performance (while better than regular shared hosting) will still be far behind a VPS.
Choose a high-performance web server (INT-ADV, HIGH)
Use any web server software but Apache. The best are NGINX, LiteSpeed, or highly-optimized Apache (rare to find). The higher your traffic, the more noticeable the difference.
- NGINX shines at simple sites. Just set it and go. Not many settings to optimize. But once you have a complicated site, NGINX is a mixed bag. Some NGINX features aren’t easy to configure. If you have a server admin to fine-tune, it’s great, but many people don’t.
- LiteSpeed has more easy-accessible features than NGINX. Like when you need some things cached but not others, or dealing with server-level redirects via htaccess. LiteSpeed also has a WordPress cache plugin, which NGINX doesn’t. That’s a HUGE advantage. (I personally prefer LiteSpeed.)
- OpenLiteSpeed is the free community version of LiteSpeed. It’s a great alternative for those wanting the free price of NGINX but the powerful LiteSpeed cache plugin.
- Some web hosts have the Apache+NGINX hybrid stack. I feel those are outdated now and make for an unnecessarily slow and heavy stack.
- If using Apache, MPM events are best (compared to worker or prefork).
- Keep your webserver updated. Later versions can speed up certain protocols and processes noticeably.
Web server configuration (ADV, MED-HIGH)
Most web servers come with safe/functional configurations right off the bat. Adequate for the average small site with little traffic. It’s when you get more traffic and more security attacks, or have more demanding apps that fine-tuning the configurations makes a big difference.
- Timeout – 30 to 60 seconds is a safe start. You can increase up to 600 or beyond if needed for long processes (import, export, backups). Keep in mind that allows poorly-coded processes or hack exploits to run out of your server resources.
- Number of child processes allowed – depends on the server environment. The default should be fine.
- Concurrent connections allowed – anywhere from 1-20k. Higher is not necessarily better!
- Keep alive – on, off, or LiteSpeed’s “smart keep-alive”. I think “on” is safer. If you have LiteSpeed, the smart keep-alive is awesome!
- Keep alive timeout – 3-5 seconds is a safe start. Increase if needed.
How many threads, body/buffer size, workers, clients, etc.? All that you can look up online. It depends on your server size and use scenario. Jump on forums and ask around or have a sys-admin configure it for you. Keep in mind different admins have their own ways of configuring.
The most important distinction for me is to decide whether this server should be set aggressive or conservative:
- AGGRESSIVE configuration – gives every site as many resources as possible. Good for low-tenant or dedicated servers.
- CONSERVATIVE configuration – gives every site as little resources as possible. Good for high-tenant or shared servers.
Disable unused services (INT, HIGH)
Many servers are automatically set up with all features running to make things easy for you. But they’re just like brand-new computers with pre-installed software. Get rid of the ones you don’t use. Even if they don’t use much memory, they can still be bombarded by hackers, and that eats resources.
- DNS – disable if you’re using an external DNS service. (Cloudflare, DNSME, etc.)
- Email – disable if you’re using 3rd-party email. (G-Suite, MXroute, etc.)
- FTP/SFTP – disable if not used.
- Memcache/Redis – disable if you don’t use it.
- Other services – Varnish, Elastipress, etc.
If you want to be OCD, scan your system for all listening ports and services.
Remove unused server modules (ADV, LOW)
Want to be even more OCD? Disable every single module not used by the server. Some of them are junk unused server stuff; others are unused Linux distro stuff. Old-school Apache-compatible stacks or unoptimized control panels tend to have many unused modules enabled by default (while also not enabling the ones you might need).
Read the documentation and check online before blindly removing or replacing them. The danger is you disable things you need (or worse, one that improves performance). You should make a list of disabled services/modules to reference later or give to a contractor when troubleshooting.
Use the latest PHP version (INT-ADV, HIGH)
The PHP version alone makes a HUGE difference.
- Use the latest PHP version possible! (easily configured from your web hosting control panel)
- For example, PHP 7.0 is 3 times faster than PHP 5.6.
- Even PHP 7.3 is 10% faster than PHP 7.2.
- At the time of this writing, PHP 7.4 is available.
- Be wary of any web hosts still using old PHP!
Keeping your website’s PHP version updated is not only for speed but also for security. The only issue is some themes or plugins may not be compatible with the latest PHP version. You’ll know because your site doesn’t work right, or looks weird. So test carefully and keep themes/plugins updated, which helps them stay compatible with the latest PHP.
Recommended php.ini configurations (INT, MED)
Most of you (on shared hosting) won’t even have access to these settings or know how to set them. But nonetheless, here are my recommendations.
- max_execution_time – lower (30-60 sec) is better to prevent resource hogs from lagging out the server. But you may need higher execution times for long processes like imports, exports, and backups.
- max_input_time – lower (60 sec) is better. Increase only if you’re trying to import something that takes forever.
- max_input_vars – set to “1000”, unless some plugins need higher.
- memory_limit – try “256M” to be safe. Raise if you have heavy plugins. I like to set it lower so I’m notified immediately when there are memory hogs. The “error_log” will tell you if you need more.
- zlib.output_compression – may or may not help. I leave it off.
Use an updated MySQL fork version (INT-ADV, LOW)
Most people only know of MySQL, which is now acquired/owned by Oracle. There’s also MariaDB (a fork of MySQL by its original creators), Percona, and others.
MySQL 8 is much better than MySQL 5.7.
But it’s better if you can use MariaDB over MySQL. It is community-friendly and has better performance than vanilla MySQL 5.7.
Use the latest MariaDB version that you can.
Whatever you do, just don’t use MySQL 5.7.
What about Percona? What about the other 3rd-party MySQL-compatible forks? For most sites, it makes little difference if any. Don’t forget to back up your database before changing or upgrading MySQL.
Convert MySQL tables from MyISAM to InnoDB (BEG, LOW)
- Make sure your tables are set to InnoDB instead of MyISAM.
- InnoDB is newer and regarded as being better overall (faster, safer).
- MyISAM can be faster in some scenarios (when mostly read-only).
- You can convert manually in phpMyAdmin or use a plugin (Servebolt Optimizer or LiteSpeed Cache). Can delete the plugin afterwards if you don’t need it.
Tuning MySQL configurations (ADV, LOW)
- Usually not required (or noticeably beneficial) for the average site but can help tremendously for large sites with high traffic and varying query lengths.
- You can run MySQLTuner for general recommendations or ask around the sys-admin community to see what everyone else uses.
- Buffer size, packet size, cache, connections, cache, stack, etc. are all among the general things to tune.
- Simple Linode guide.
When trying out random configurations online or copying somebody else’s, please make sure their environment is similar to yours. The main distinctions are:
- server size, resources available
- how many clients/sites are on the server
- how many end users are on the server
- how much traffic
- how big are the sites
- what kind of read/write behavior
It’s important to know whether their settings are for efficiency (high-tenant web host) or aggressive performance (low-tenant webserver).
Server full-page caching (ADV, HIGH)
Full-page caching can help speed up any website. But caching directly from the server is much more powerful and resource-efficient than PHP/application-level caching done through a plugin.
- Some Apache or NGINX servers use Varnish, which is an outdated approach. Don’t use a Varnish proxy. Just upgrade to pure-LiteSpeed or pure-NGINX stack.
- LiteSpeed servers can use LiteSpeed cache – powerful, with many features, and comes with a handy WordPress cache plugin (called “LiteSpeed Cache”).
- NGINX servers can use FastCGI – great, super fast! While there’s no official NGINX cache plugin for WordPress, there are various “NGINX helper” plugins to facilitate basic cache functions (like purging).
To be safe, you should disable caching on pages with forms, carts, or checkouts. Private pages (for logged-in users) CAN be cached but don’t mess with that unless you have that much private traffic and are ready to spend hours configuring private cache.
You can only enable server-level caching if you own or have access to the server. Otherwise, your web host decides what caching options you have.
- Shared hosting usually allows all caching plugins.
- Managed hosting usually limits you to only their proprietary one.
Memory object-caching (ADV, LOW-HIGH)
Object-caching caches only the database queries instead of the entire page HTML. This technically makes it “slower” than full-page caching (since you’re not caching the entire page) but useful for speeding up dynamic pages or private pages (logged-in users, admin backend) that can’t be static-cached.
Any site with lots of constantly refreshed data on the frontend or lots of numbers and reports on the backend would stand to benefit from object caching. Mostly static sites or low-traffic sites would not benefit from object-caching at all; don’t use it on them – it can make them slower!
- Redis is the gold standard in object caching now. It’s superior to the older memcache in almost every way.
- Memcache is only used in rare situations where Redis doesn’t work or is slower.
- If your data doesn’t change much, you can set longer object caching times (e.g. 60 mins and up). Longer times mean fewer database queries.
- Otherwise, stick with the default 5-10 mins to be safe, unless you don’t mind users seeing stale data.
- Object caching can be managed by WordPress plugins. Most ideal if you have one cache plugin to manage both full-page caching and object caching.
You can get ~25% faster object caching by using a Unix Socket.
- UNIX sockets are run from a lower-level layer on the OSI networking model and therefore faster than standard TCP sockets.
- Redis and Memcache UNIX socket configuration guides for CentOS.
- Redis and Memcache UNIX socket configuration guides for Ubuntu.
- Note: with UNIX socket enabled, only one server user account (and presumably all sites by that user) can use object caching. So you can’t use this if you plan to have multiple server users deploying object cache.
Some background on memory-caching.
Memory-caching is the gold standard in caching because cache runs faster from memory than from disk. The issue is we have limited amounts of memory (most of it is already used for applications) so we can’t store the entire site cache in there. It matters less nowadays anyway since server disks are so much faster now (thanks to SSD technology).
Sure memory is more abundant now too but then again, applications are bigger. You may have heard of others loading their entire site into memory – some using the cache route, others by mounting their WordPress directory into memory. It works great if your site is small enough but for most people: your memory is only big enough to store database queries, anything else you want to cache will be stored on your disk.
Use the latest HTTP protocol (BEG, HIGH)
HTTP/2 loads browser requests so much faster than HTTP/1 (thanks to parallelization). It feels like 3 times faster to me.
- You should be using HTTP/2 or even HTTP/3 (recently released).
- Avoid older web servers still on the archaic HTTP/1.
- Check your site for HTTP/2 and HTTP/3.
- Using HTTP/2 requires HTTPS/SSL. If your site isn’t in HTTPS, do it now!
Content encoding (INT, HIGH)
GZIP is so 2016. Every web server should have BROTLI compression nowadays. It’s superior to GZIP (produces smaller files AND in less time). But shockingly, BROTLI still isn’t available on all web servers.
- If using BROTLI – set static compression to 4.
- If using GZIP – set dynamic compression to 1 and static compression to 6.
You can push static compression levels higher if your CPU is strong (or low-usage server) and/or your static content is cached for a long time (long expiry times). If you’re using a CDN or Cloudflare, make sure you enable BROTLI compression there as well.
Control-panel (INT, HIGH)
This issue matters only for VPS users. Control panels used to be critiqued for the initial weight they put on the server. That’s because control panels were originally designed for large dedicated servers, but have since been optimized for smaller VPS. While it’s true that having no control panel is lighter than having one, it makes day-to-day tasks harder. Their footprint is now negligible considering how useful panels can be.
The best-performing control panel is one that fits your needs.
- Allows you to pick the web server of your choice – NGINX or LiteSpeed.
- Easily configure redirects at the server level – instead of a slower PHP-level redirection plugin.
- Easily configure granular caching rules – choosing what and what not to cache.
- Easy to manage – for you or your sys-admin.
- Can cage users – preventing resource-hogs on high-tenant servers.
- Secure against hacks – as hacking attempts eat many resources.
- Easy to use – for you or your clients.
Use external DNS service (INT, LOW)
- Lower DNS latency (small benefit)
- Easy to update DNS (convenience)
Will using an external DNS like Cloudflare or DNS Made Easy make a world of difference in terms of web hosting speed? I think it improves lookup time but not so noticeable unless your previous DNS server was a piece of junk by a cheap web host.
The main benefit for me is how quickly I can redirect things. Suppose you get hacked and need to redirect through a security proxy. Or maybe you’re switching certain aspects of your site to another server. In moments like this, having a DNS service is so convenient. You can switch things over with very little downtime, and even switch them back quickly if there’s an issue.
DNS services may seem like an extra hassle to set up, but once in place, they allow you to integrate new services and mitigate performance issues so much faster.
Run WP-cron from your server (BEG, MED)
Many WordPress tasks need a trigger to function, such as sending out system emails, running backups, and releasing scheduled posts. By default, WordPress uses a function called WP-Cron (conveniently located at yourdomain.com/wp-cron.php). It works by checking (and executing) any pending tasks any time someone visits the website. It’s great for small sites, but terrible if you have tons of traffic (triggering many unnecessary cron-checks). Also an obvious DDOS vulnerability.
The sensible thing is to disable WP-cron and use a real cron job, whether from your server or an external cron service. Some cron jobs visit the website directly. Others go through the Linux directory. Use whichever one works. I think a 5-minute interval is good.
Caging users & resource limits (ADV, MED-HIGH)
Do you have many sites or clients on the same machine? Are you unable to police them all effectively? If you’re losing control of your tenants, it’s probably time to limit their resources. I’ll start you off with a few tactics below. You look up the rest.
- Cloudlinux & CageFS – limit CPU and memory usage
- Server-wide bans on cache-prebuilding, broken-link checkers, and other resource hogs.
- Decrease php execution time.
- Global configs block the usual offenders, such as bots.
The worst-case scenario is just to split off some clients onto another server. Split them up by size, space usage, traffic amount, whatever you want.
Tracking down resource hogs (ADV, MED-HIGH)
We often run into slow server issues with no obvious clue of where to look. Today, it’s this client. Tomorrow, it’s that client. It seems any site can be the culprit on any given day. When you have so many clients, and none of them can afford to switch plugins on and off, it is really difficult to track down the problem.
Here are some ideas:
- Check server logs – are you being hacked? Are there excessive requests?
- Check server monitors – which users are hogging the CPU, memory, and bandwidth?
- Once you know which site it is, check the WordPress error log. Run Query Monitor.
- Of course, it might not even happen all the time. You have to track down which users or processes were running when the slowdown occurred.
Sometimes you’ll need more of a developer mentality. What plugin was updated last? Are there any new themes or plugins that were custom-coded? (Check for memory-exhaustive commands.) Yes, you can use application monitors like New Relic, but for me, it’s overkill. The trickiest problems are when it seems like every site is the problem. Or also when the server load is low, but the sites are still slow. Good luck!