I have been running this blog on this domain for over ten years now but the “hardware” has changed a bit. I have always done a VPS but where it lives has changed over time. I started with Rackspace and then later moved to Digital Ocean back when they were the new kid on the block and offered SSD based VPS instances with unlimited bandwidth. I started on a $5 droplet and then upgraded to a pair of $5 droplets so that I could get better separation of concerns and increase the total amount of compute I had at my disposal. This setup has served me very well for the past five years or so. If you are interested in checking out Digital Ocean I have a referral code you can use – https://m.do.co/c/5016d3cc9b25

As of this writing, the site is hosted on two of the lowest level droplets Digital Ocean offers which cost $5 a month each. I use a pair of instances primarily because it is the cheapest way to get two vCPU worth of compute. I made the change to two instances back when I was running xboxrecord.us (XRU) as well as a NodeJS app. Xboxrecord.us and the associated NodeJS app (which also powered guardian.theater at the time), combined with MySQL, used more CPU than a single instance could provide. By adding a new instance and moving MySQL to it I was able to spread the load across the two instances quite well. I have since shutdown XRU and the NodeJS app but have kept the split server arrangement mostly because I haven’t wanted to spend the time moving it back to a single instance. Also, how I run WordPress is slightly different now because in addition to MySQL I am also running Redis. Four services (Nginx, PHP, Redis and MySQL) all competing for CPU time during requests is just a bit too much for a single core.

Making the dual server arrangement work is simple on Digital Ocean. The instance that runs MySQL also runs Redis for object and page caching for WordPress. This means Nginx and PHP gets its own CPU and MySQL and Redis get their own CPU for doing work. I am now effectively running a dual core system but with the added overhead, however small, of doing some work across the private network. Digital Ocean has offered private networking with no transfer fees between instances for awhile now so I utilize that move data between the two instances. Digital Ocean also has firewall functionality that I tap into to ensure the database server can only be reached by my web server. There is no public access to the database server at all.

The web server is, of course, publicly available. In front of this server is a floating IP, also provided by Digital Ocean. I use a floating IP so that I can create a new web server and then simply switch where the floating IP points so make it live. I don’t need to change any DNS and my cut overs are fairly clean. Floating IPs are free and I highly recommend always leverage floating IPs in front of an instance.

Although the server is publicly available, I don’t allow for direct access to the server. To help provide some level of protection I use Cloudflare in front of the site. I have used Cloudflare for almost as long as I’ve been on Digital Ocean and while I started out on their free plan I have since transitioned to using their Automatic Platform Optimization system for WordPress. This feature does cost $5 a month to enable but what it gives you, when combined with their plugin, is basically the perfect CDN solution for WordPress. I highly recommend this as well.

In all, hosting this site is about $15 a month. This is a bit steeper than some people may be willing to pay and I could certainly do it for less. That said, I have found this setup to be reliable and worry free. Digital Ocean is an excellent choice for hosting software and keeps getting better.

Running WordPress

WordPress, if you’re careful, is quite light weight by today’s standards. Out of the box it runs extremely quickly so I have always done what I could to ensure it stays that way so that I can keep the site as responsive as possible. While I do utilizing caching to keep things speedy you can never ignore uncached speeds. Uncached responsiveness will always be felt in the admin area and I don’t want a sluggish admin experience.

Keeping WordPress running smoothly is simple in theory and sometimes difficult in practice. In most cases, doing less is always the better option. For this reason I install and use as few plugins as necessary and use a pretty basic theme. My only requirement for the theme is that it looks reasonable while also being responsive (mobile friendly). Below is a listing of the plugins I use on this site.

Akismet

This plugin comes with WordPress. Many people know what this plugin is so I won’t get into it too much. It does what it can to detect and mark command spam as best it can and does a pretty good job of it these days.

Autoptimize

Autoptimize combines js and css files into single files as much as possible. This reduces the total number of requests required to load content. This fulfills my “less is more” requirement.

Autoshare for Twitter

Autoshare for Twitter is a plugin my current employer puts out. It does one thing and it does it extremely well. It shares new posts, when told to do so, directly to Twitter with the title of the post as well as a link to it. When I started I would do this manually. Autoshare for Twitter greatly simplifies this task. Twitter happens to be the only place I share new content to.

Batcache

Batcache is a simple page caching solution for WordPress for caching pages at the server. Pages that are served to anonymous users are stored in Redis, with memcache(d) also supported. Additional hits to server will be served out of the cache until the page expires. This may seem redundant since I have Cloudflare providing full page caching but caching at the server itself ensures that Cloudflare’s many points of presence get a consistent copy from the server.

Cloudflare

The Cloudflare plugin is good by itself but required if you are using their APO option for WordPress. With this plugin, API calls are made to Cloudlfare to clear the CDN cache when certain events happen in WordPress, like saving a new post.

Cookie Notice and Compliance

Cookie Notice and Compliance for that sweet GDPR compliance. Presents that annoying “we got cookies” notification.

Redis Object Cache

Redis Object Cache is my preferred object caching solution. I find Redis, combined with this plugin, to be the best object caching solution available for WordPress.

Site Kit by Google

Site Kit by Google, another plugin by my employer, is the best way to integrate some useful Google services, like Google Analytics and Google Adsense, into your WordPress site.

That is the complete set of plugins that are deployed and activated on my site. In addition to this smallish set of plugins I also employ another method to keep my site running as quickly as I can, which I described in Speed up WordPress with this one weird trick. These plugins, combined with the mentioned trick, ensure the backend remain as responsive as possible. New Relic reports that the typical, average response time of the site is under 200ms even if the traffic to the site is pretty low. This seems pretty good to me while using the most basic droplets Digital Ocean has to offer.

Do you host your own site? Leave a comment describing what your methods are for hosting your own site!

Today I’d like to discuss what I often see as one of the largest contributors to poor backend WordPress performance. Often times I see this particular issue contributing to 50% or more of the total time the user waits for a page to load. The problem? Remote web or API calls.

In my previous post, I talk about using Akismet to handle comment spam on this site. In order for Akismet to work at all it needs to be allowed to access an outside service using API calls. While API calls are necessary for some plugins to work properly I often see plugins or themes that make unnecessary remote calls. Some plugins and themes like to phone home for analytics reasons or to check for updates. Even WordPress core will make remote calls in order to determine the latest version of WordPress or to check for available theme and plugin updates even if you have otherwise disabled this functionality. These remote calls add a lot of extra time to requests or can even cause your site to become unavailable if API endpoints take too long to respond.

This site is very basic and runs a minimal set of plugins. Because of this, I am able to get away with a rather ham-fisted method of dealing with remote API calls so that I can ensure my site remains as responsive as possible given the low budget hosting arrangement I use. This one weird trick is to simply disallow remote calls at all except for the ones absolutely necessary for my plugins to operate properly.

In my wp-config.php file I have defined the following:

define( 'WP_HTTP_BLOCK_EXTERNAL', true );
define( 'WP_ACCESSIBLE_HOSTS', 'api.cloudflare.com,rest.akismet.com,*.rest.akismet.com' );

The first define tells WordPress to block all http requests that use wp_remote_get or similar. This has the immediate affect of blocking the majority of remote web calls. While this works for any plugin that uses WordPress functions for accessing remote data, any plugin that makes direct web requests using libraries like curl or guzzle will not be affected.

The second define tells WordPress what remote domains are allowed to be accessed. As you can see, the two plugins that are allowed to make remote calls are Cloudflare and Akismet. Allowing these domains allows these two plugins to function normally.

By blocking most remote calls I get the benefit if preventing my theme and core from phoning home on some page loads and while I’m in the admin. This trick alone, without making any other optimizations, makes WordPress feel much more snappy to use and allows pages that are uncached to be built much more quickly. Blocking remote calls has the side effect of preventing core’s ability to check the core and plugin versions but I am in the WordPress world enough that I am checking on these things manually anyway so the automated checks just aren’t necessary. I’d rather trade the automated checks for a continuously better WordPress experience.

What can you do as a developer?

This trick is decidedly heavy handed and only works as someone operating a WordPress site. Developers may want to consider their use of remote web calls and may be wondering, what can I do to ensure WordPress remains as responsive as possible? The primary question a developer should always ask when creating a remote request is “is the data from the remote request necessary right now?” Meaning, is the data the remote request is getting necessary for the current page load or could it be deferred to some background process like WordPress’s cron system and then cached? The issue with remote requests isn’t that they are being performed, it is that they are often performed on what I call “the main thread” where the main thread is the request a user has made and must then wait for the results. Remote requests that are made in the background will not be felt by end users. In addition, background requests can be performed once rather than for every request. In addition to improving page load times for end users you may also find you can get away with less hardware.

If you need help determine how many remote calls are being performed there are some options. You can certainly write an mu-plugin that simply logs any remote requests being made but what I used was a free New Relic subscription. I used New Relic on this site to determine what remote calls were being performed and then configured what domains were allowed based on that information. By blocking unnecessary remote requests I was able to cut my time to first byte timings in half.

Do you have any simple tricks you use to improve WordPress performance? Leave the info in the comments below!

At the beginning of November I decided to give comments on posts a try again. In the past, allowing comments on the site has been an issue as the overhead of managing spam comments was more than I wanted to deal with. It required almost daily attendance as spam was a constant stream of junk even with tools like Akismet installed, enabled and configured.

I am happy to report that Akismet is greatly improved and it is doing an excellent job of blocking and removing spam comments so that I don’t even need to see them. If you, like me, have had a negative experience trying to manage comments in the past then maybe it is time to try them again with an updated Akismet setup.

This one is, primarily, for all the people responsible for ensuring a WordPress site remains available and running well. “Systems” people if we must name them. If you’re a WordPress developer you might want to ride along on this one as well so you and the systems or DevOps team can be speaking a common language when things go bad. Often times, systems people will immediately blame developers for writing bad code but the two disciplines must cooperate to keep things running smoothly, especially at scale. It’s important for systems AND developers to understand how code works and scales on servers.

What I’m about to cover is some common performance issues that I see come up and then be misdiagnosed or “fixed” incorrectly. They’re the kind of thing that causes a WordPress site to become completely unresponsive or very slow. What I cover may seem obvious to some, and they are certainly very generalized, but I’ve seen enough bad calls to know there are a number of people out there that get tripped up by these situations. None of the issues are necessarily code related nor are they strictly WordPress related, they apply to many PHP based apps; it’s all about how sites behave at scale. I am going to explore WordPress site performance issues since that’s where my talents are currently focused.

In all scenarios I am expecting that you are running something getting a decent amount of traffic at the server(s). I am assume you are running a LEMP stack consisting of Linux, Nginx, PHP-FPM and MySQL. Maybe you even have a caching layer like Memcached or Redis (and you really should). I’m also assuming you have basic levels of visibility into the app using something like New Relic.

Let’s get started.

Continue reading

Does your WordPress site load in under a second? This one can despite running, for years, on one of the lower VPS tiers available at DigitalOcean thanks to Cloudflare. DigitalOcean’s server offerings are excellent for the price and I’ve always found the performance perfectly acceptable given what I’m paying each month. That said, Cloudflare offers a free CDN tier with just the right mix of features to be appealing and useful. No matter how good your server is you will always benefit from a CDN’s ability to cache content and get it physically closer to your audience. This post goes into detail about how to get the best possible performance from Cloudflare and WordPress by tweaking a few settings and installing a single plugin.

I have no association with Cloudflare and I’m not hear to sell it to you but for this post to make any sense you’ll need to have a WordPress site running through at least Cloudflare’s free CDN offering. If this sounds like you then lets continue.

Continue reading