UpCloud WordPress Hosting Review

If you spend time in the WordPress hosting space and few names constantly come up, and one of them is UpCloud. UpCloud is a European cloud provider with data centers all over the world that claims to have the world’s “fastest cloud servers”. In this review we’re going to take a look at how WordPress performs while hosted on UpCloud and also see how the reliability of the service is.

Want to run your own WordPress load tests? Sign up for Kernl.

Hardware Tested

For our test of WordPress running on UpCloud, we tested 3 different hardware configurations.

  • 1vCPU + 1GB RAM – This is the cheapest possible option for hosting WordPress on UpCloud at $5 / month.
  • 2vCPU + 4GB RAM – At $20 / month, this option is a nice balance of processing power and memory. If I were to host a few sites on UpCloud with moderate amounts of traffic I would probably start here.
  • 4vCPU + 8GB RAM – This machine was as expensive as I was willing to go for this review, coming in at $40 / month.

Software Used

The software used in this test was the latest available from the included repositories with Ubuntu 20.04.

  • Ubuntu 20.04 LTS
  • MariaDB
  • Nginx
  • PHP-FPM 7.4
  • Memcached

What was tested?

For each test we ran on UpCloud we used Kernl’s WordPress Load Testing service to generate load against each virtual machine. The content for the load tests was a copy of this blog. The load generators for each test lived in DigitalOcean’s SFO2 data center and ran against UpCloud’s Chicago data center.

UpCloud WordPress Load Tests

We ran a total of 6 WordPress load tests on UpCloud’s servers. For each machine we tested we ran a test where nothing was cached and a test where everything was cached (using W3 Total Cache backed by Memcached). Each test was for 1000 concurrent users for 45 minutes.

1vCPU + 1GB RAM (No Cache)

For this configuration the requests per second peaked at around 41/s before failure rates started to increase. Once failures started in earnest, successful requests leveled off at around 11/s.

UpCloud 1vCPU 1GB RAM - Requests/Failures
Not bad for no caching!

On the response time front, things weren’t great. As the request (and error) rate increased, the response times started to get pretty unwieldy.

UpCloud 1vCPU 1GB RAM - Response Time
Less than a 1000ms, then 2500-3000

A graph of median and average response times doesn’t always tell the whole story, so lets take a look at the response time distribution.

UpCloud 1vCPU 1GB RAM - Response Time Distribution
No great.

The response time distribution tells us that 50% of requests finished in under 5000ms, but that 99% finished in under 6000ms. Usually you want to see a large difference between 50th and 99th percentile. But here they’re awfully close, meaning that most request response times were pretty terrible.

1vCPU + 1GB RAM (Cached)

Now that we’ve looked at uncached performance, lets take a look at how this UpCloud server handled WordPress with caching enabled.

UpCloud 1vCPU 1GB RAM Cached – Requests/Failures Per Second

As you can see, performance is much better. We end up leveling off at around 436 request per second. The only issue here is that we still have quite a few failures. Certainly more failures than would be acceptable in a production situation.

UpCloud 1vCPU 1GB RAM Cached – Average / Median Response Time

Looking at response times you can see performance is a lot better, and much more in line with what you’d expect from a WordPress site that’s under heavy load. Average response time was a hair less than 1000ms, with the median response time (doesn’t include outliers) closer to 475ms. This is a bit less than an order of magnitude improve in performance just be turning on caching with W3 Total Cache.

UpCloud 1vCPU 1GB RAM Cached – Response Time Distribution

So far everything looked great (with the exception of the request failures) for this UpCloud configuration with caching enabled. However if we take a look at the response time distribution you can see that all is not what it seems. 80% of requests returned in less than 600ms, but the upper 20% too anywhere between 3000ms and 12000ms. 20% of your customers waiting more than 3 seconds for the page to load isn’t awesome.

2vCPU + 4GB RAM (No Cache)

The next machine we tested was far better provisioned than the first machine with twice the CPUs and 4x the RAM.

UpCloud 2vCPU 4GB RAM - Request / Failures per Second

As you can see request throughput peaked at around 50 per second, and then leveled off at 22 per second when the error rate elevated. I honestly expected the throughput to be better for this scenario given how much more hardware there was to work with.

UpCloud 2vCPU 4GB RAM - Average / Median Response Times

Response times slowly increased as load increased on the server, with average response times ending up near 5000ms and the median response times closer to 5500ms. At that point, 500ms probably doesn’t matter that much.

UpCloud 2vCPU 4GB RAM - Response Time Distribution

The response time distribution for this test was predictably bad. The difference between the lower 50% and upper 50% is only 1000ms, which doesn’t give me warm fuzzy feelings. If anything, this is a great example of how much you need caching in a WordPress installation. Throwing twice as much hardware at it barely even makes a difference uncached.

2vCPU + 4GB RAM (Cached)

Now lets take a look at the same machine, but this time with caching enabled via W3 Total Cache and Memcached.

UpCloud 2vCPU 4GB RAM Cached – Requests / Failures per Second

No we’re getting somewhere! Requests per second leveled out at around 600, which is actually quite high. We also didn’t start to see failures increase until around 300 per second, which is pretty amazing for a $20/month machine.

UpCloud 2vCPU 4GB RAM Cached – Average / Median Response Time

The response times for the cached version were pretty great until the failure started accumulating. Up until the failures started we were seeing response times right around the 60ms mark, which is excellent under heavy load. After that they leveled out at around 450ms, which still isn’t bad when you are serving ~600 requests/s.

UpCloud 2vCPU 4GB RAM Cached – Response Time Distribution

The response time distribution wasn’t terrible here either considering all the failures we were seeing. 95% of requests finished in under 1000ms and 50% finished in under 500ms.

4vCPU + 8GB RAM (No Cache)

Our final test was with a fairly robust machine (by my standards anyway).

4vCPU 8GB RAM – Requests / Failures Per Second

As you can see the results in an uncached situation were pretty solid until failures started in a major way. This machine was able to handle about 175 req/s uncached, and then leveled out at 215 req/s once the errors started. Obviously this number of errors isn’t great, but at the 175 req/s mark thats enough to serve 15 million requests a day.

UpCloud 4vCPU 8GB RAM – Average / Median Response Times

As expected in an uncached situation the response times weren’t great, but they weren’t terrible either given the amount of load the system was under. Prior to elevated error rates we were seeing response times around 100ms. Once errors picked up they leveled off at 2500ms.

4vCPU 8GB RAM – Response Time Distribution

The response time distribution is what we would expect from an uncached WordPress installation under heavy load. 50% of requests finished in 2500ms and 99% of requests finished in 3250ms. That’s not all bad considering there wasn’t any caching.

4vCPU + 8GB RAM (Cached)

Our final load test was a cached version of the previous test. Given drastic improvements we saw in the other tests, the same sort of results were expected here.

4vCPU 8GB RAM Cached – Requests / Failures Per Second

Now that we have a more robust machine + caching enabled, you can see that the server was able to process quite a few requests concurrently before errors started. Even once errors started they stayed relatively low. Initial errors didn’t show up until around 500 req/s and eventually we leveled off at 850 req/s. Not bad for $40/month.

4vCPU 8GB RAM Cached – Average / Median Response Times

The response times were also excellent in the cached scenario. Before errors and failures we were seeing 65ms and after we were stilling coming in at around 100ms. Not too shabby for the intense load the server was under.

UpCloud 4vCPU 8GB RAM Cached – Response Time Distribution

My favorite chart this time around is the response time distribution. 99% of all requests finished in under 300ms. With 1000 concurrent users.

UpCloud WordPress Reliability

An often overlooked metric when comparing VPS providers like UpCloud is reliability. To get some objective numbers on that, I ran a reliability test with Kernl for 30 consecutive hours. The test is low volume (25 concurrent users), but enough to make sure the server stays active and that we’ll notice is sometimes goes awry.

Reliability test

Over the course of 30 hours we saw one error spike that was quickly resolved. After that, no errors at all. Over the entire test we saw 400 requests fail, which is roughly 16 seconds of failures. I’ve done quite a few of these reliability tests with different hosts and this is pretty average.


UpCloud is solid choice for VPS hosting though their claim to be the “fastest” may not be completely substantiated (with WordPress at least). If I wanted to use a VPS host based in Europe they would definitely be near the top of my list. The only odd thing about them is their billing model where you add “credits” to your account versus just having a credit card of file. This is likely to prevent fraud, but doesn’t really make for a great user experience.

What’s New With Kernl – May 2020

Hello everyone and welcome to the May 2020 edition of “What’s New with Kernl”! This month was relatively slow for us with little work on new features and more focus on bugs and refactoring. Let’s dive in.

  • We now have video tutorials for enabling Git deployments on your WordPress plugins and themes. You can see them on your Kernl dashboard, or in the Kernl documentation.
  • License Tab UX – The license tab in the plugin and theme edit interface was getting out of control. We collapsed the provider specific controls into an accordion to make it a little easier to digest.
  • Global CDN – Kernl now has the option to serve your updates via a global CDN powered by Vercel. If you have a geographically diverse customer base, this might be for you.
  • Analytics Date Selection Bug – There was an issue with date selection being wrong in some cases.
  • Mongoose Upgrade – Kernl used Node.js and MongoDB under the covers to deliver your updates. Our ORM is Mongoose and had been stuck on the 4.X version of it for a long time. We finally upgraded to the 5.x series and saw 40% reduction in queries to our database.
  • Analytics Database Maintenance – Removed 2 indexes that we didn’t need and dud a full vacuum on the largest and highest traffic table. Recovered 5Gb of hard disk space.
  • Kernl Blog Rebuild – Our blog is self-hosted and was running on some pretty ancient hardware/software. We rebuilt the machine to use Ubuntu 20.20 + Nginx & PHP-FPM.
  • Analytics Daily Aggregates Failure – For 2 days Kernl analytics daily aggregates were failing due to disk space space and memory issues (see Analytics Database Maintenance). This has been resolved.
  • Site Health SSL Certificate Expiration – We forgot to renew the WordPress Site Health SSL Certificate (oops!). This is now an automated process 🙂

That’s all for this month. I hope everyone has a great June!