Skip to content
All articles

Ask this question before believing anyone's SLA numbers

8 minutes read

Ask this question before believing anyone's SLA numbers

99.99% uptime allows about four minutes of downtime a month. WordPress VIP's baseline is 99.95%, and the gap is not effort, it is architecture. Count how many systems have to be awake for a URL to return HTML, and you can predict any vendor's SLA before you read it.

Every hosting company will sell you a number. 99.9%. 99.95%. Four nines if you pay enough.

The number is easy to print. What it costs to keep is architecture, and architecture is the part nobody puts on the pricing page.

plym Cloud runs on a 99.99% uptime SLA. That is about four minutes of downtime a month. WordPress VIP, Automattic's enterprise platform, publishes 99.95% as its baseline SLA, with 99.99% sold as an upgrade. Automattic is not short of engineers or money. So the gap is not effort. It is shape: their default is lower because their default architecture has to earn it the hard way.

Here is how to tell the difference before you sign anything.

What 99.99% uptime actually means

In short: 99.99% uptime allows about 4 minutes and 19 seconds of downtime in a 30-day month, or roughly 53 minutes across a full year.

Each nine you drop multiplies the budget by ten. That sounds abstract until you put it in minutes.

Uptime Downtime per 30-day month Downtime per year
99.99% 4m 19s 52m 34s
99.98% 8m 38s 1h 45m
99.95% 21m 36s 4h 23m
99.90% 43m 12s 8h 46m
99.00% 7h 12m 3d 15h

The distance between 99.99% and 99.95% looks like rounding error. Over a year it is three and a half hours of your site being gone.

Before you believe an SLA, count the hops

Here is the framework. Take the URL of a page on the platform you are evaluating. Ask the vendor to walk you through every system that has to be awake and correct for that request to return HTML.

Count them. That number tells you more than the SLA does.

The serial availability tax

When systems sit in series, availability multiplies. Ten dependencies at 99.99% each do not give you 99.99%. They give you:

0.9999 ^ 10 = 0.99900  →  99.90%

Five of them give you 99.95%. Exactly 99.95%.

0.9999 ^ 5  = 0.99950  →  99.95%

Nobody at Automattic sat down and derived their SLA this way, and we are not claiming they did. The point is the shape of the curve: every tier you add to the read path taxes the number at the end of it, and the tax compounds. Five tiers of very good infrastructure produce a merely good result.

Real platforms fight back with redundancy inside each tier: replica databases, multiple app servers, failover pools. So it is never quite this brutal in practice. But redundancy inside a tier does not delete the tier. A database cluster with three replicas is still a database that has to answer, still a connection pool that can exhaust, still a schema migration that can lock a table on a Tuesday afternoon.

Count the hops on a typical WordPress request

A cache miss on a well-run WordPress stack looks something like this:

  1. DNS resolves
  2. CDN edge takes the request and misses
  3. Load balancer picks an origin
  4. Web server accepts the connection
  5. PHP-FPM hands the request to a worker
  6. WordPress bootstraps core
  7. Plugins load, in order, each one able to fatal
  8. Object cache is consulted
  9. MySQL runs the queries
  10. PHP renders the HTML and sends it back

Ten hops. Nine of them can fail in ways your reader will see as a white screen. This is a perfectly good architecture and it powers a large share of the internet. It also explains the 99.95% without anyone being bad at their job.

How plym Cloud gets the hop count to one

plym Cloud does not run your blog. It publishes it.

Every page on a plym site is compiled to a static artifact at write time and pushed to Cloudflare R2 with a very high edge TTL. When a reader asks for a page, the read path is:

  1. Cloudflare edge serves the cached file

That is the whole list. No load balancer. No application server. No PHP process. No database.

On a cache miss, there is exactly one more hop: Cloudflare pulls the object from R2 and serves it. R2 is object storage, not a query engine. It has no connection pool to exhaust and no slow query to wait on.

The origin is a build server, not a web server

This is the part that decides the SLA. The plym origin (FastAPI, Postgres, Caddy, the admin app) is in the write path only. It exists to turn your edits into files. Once the files are out, it has no further job in serving your readers.

So if the plym origin catches fire at 2am, your blog does not notice. The pages are already sitting in 348 Cloudflare cities and in R2. There is nothing for the origin to fail to do.

What you lose during an origin outage is the ability to publish. That is a real cost, and it is why the admin panel is scoped out of the SLA below. But your readers, your search rankings and your ad impressions are untouched.

Pages get faster the more they are read

Cloudflare caches per location. The first reader in São Paulo pays for a fetch from R2. Every reader after them in São Paulo gets the file from a machine in São Paulo.

Popular pages therefore end up resident in more of the 348 cities, and stay resident longer. Your best post is your fastest post. Traffic makes the system stronger instead of hotter, which is the exact inverse of a database-backed CMS, where your best post is the one most likely to take the site down.

The hard part is invalidation, not caching

Anyone can cache a page for a year. The reason most CMSes do not is that they cannot reliably tell you when the cached copy is wrong.

plym runs a watcher (we call it purged) that observes changes to posts and purges exactly the affected resources at the edge. Updates land in seconds. Everything else keeps serving from cache for as long as it stays true, which can be years.

This step has to be flawless, because a missed purge means serving stale content forever, and nobody files a bug report about a page that loads fast and says the wrong thing. It is the single most carefully tested path in the product.

The credit table

An SLA without teeth is a marketing claim with a lawyer attached. If we miss 99.99% in a calendar month, you get money back.

Monthly uptime Downtime in a 30-day month Credit on your bill
99.99% or better up to 4m 19s none owed
Below 99.99%, at or above 99.98% 4m 19s to 8m 38s 10%
Below 99.98%, at or above 99.95% 8m 38s to 21m 36s 25%
Below 99.95%, at or above 99.90% 21m 36s to 43m 12s 50%
Below 99.90%, at or above 99.00% 43m 12s to 7h 12m 75%
Below 99.00% more than 7h 12m 100%

For comparison, here is what the same downtime earns you on WordPress VIP's published 99.95% SLA. At 99.90% uptime, a month with 43 minutes of downtime, their table pays 5%. Ours pays 50%. Their 100% credit only triggers below 98.55%, which is more than ten hours dark in a single month.

We are comfortable writing a steeper table because of the hop count. A platform with ten things in the read path has to write a gentle credit schedule, because it will eventually need it.

What the SLA covers

Covered. The things your readers and Google touch:

  • Your homepage and all index pages
  • Every published post and page
  • Category, tag and archive pages
  • sitemap.xml, RSS feeds and robots.txt
  • Static assets: CSS, JS, images, fonts
  • Markdown representations of posts

Not covered. The things only you touch:

  • The plym admin panel
  • Settings, configuration and billing screens
  • The authoring and publishing pipeline
  • Preview and staging environments
  • Outages caused by DNS you control, custom code, or a proxy you put in front of us
  • Force majeure

The split is deliberate and it follows the architecture. The read path is the part we made nearly impossible to break, so that is the part we insure. The write path is a normal application with normal failure modes, and we are not going to pretend otherwise to make a page look better.

The question to ask

You do not need to take our number on faith, and you should not take anyone else's either.

Ask your current host, or the next one you talk to, one question: what has to be awake for this URL to return HTML?

If the honest answer is a list, the SLA is a forecast. If it is one line, it is a description.

Frequently asked questions

How is uptime measured?
By external synthetic checks against real published URLs from multiple regions, not by our own servers reporting that they feel fine. A location has to fail repeatedly before it counts, so one flaky probe does not trigger a payout, and one healthy region does not hide a real outage.
How is an SLA violation compensated?
With money, off your bill. Not support credits, not a free feature tier, not an apology and a status page postmortem. A percentage of what you paid us that month comes back.
Do I have to ask for the credit?
Open a ticket for the affected month. We do not require you to prove the outage or produce your own monitoring logs.
What actually happens if the plym origin goes down?
Your site keeps serving. You lose the ability to publish new posts or edit existing ones until it is back. Anything you published before the outage stays live, fast and cached.
Does the 99.99% include Cloudflare's own downtime?
Yes. We are not going to point at a subprocessor. If your pages did not serve, they did not serve, and the reason is our problem.
Is this different from a CDN in front of WordPress?
Yes, and the difference is what happens on a miss. A CDN in front of WordPress falls back to the full ten-hop stack. plym falls back to object storage. The point is not that we cache harder. It is that there is nothing behind the cache that can be down.