Failure domains and resilience

Where the SLA boundary actually sits, what fails independently, the blast radius of each failure, and the degradation patterns that keep an app useful when a storage binding is slow rather than returning errors.

The Spikefrost Team30 Jul 20265 min read

Designing for this platform means designing for partial failure, because the parts fail independently and are guaranteed independently.

Where the SLA boundary actually sits

Cloudflare commits to a 99.99% monthly uptime SLO for Workers. The exclusions are what an architect needs to see:

The Service Level Objective does not apply to unavailability resulting from "…incorrect configuration of bindings (e.g., KV, Durable Objects, D1, or R2, etc.), mismanaging Workers secrets, or exceeding resource limits" or from "unavailability or performance degradation of interdependent Cloudflare services" including the CDN, DNS, WAF, and storage bindings.

Drawn as a picture:

The Workers SLO covers the compute path. Storage bindings, and your own configuration, sit outside it — which is why graceful degradation is a design requirement rather than a nice-to-have.

Your responsibility

Covered by Cloudflare's 99.99% Workers SLO

misconfiguration is excluded

your own errors are excluded

OUTSIDE the Workers SLO

D1

Durable Objects

KV

R2

CDN · DNS · WAF

Worker isolate
your code executing

Binding configuration
secrets · routes · resource limits

Your code returning 5xx

The Workers SLO covers the compute path. Storage bindings, and your own configuration, sit outside it — which is why graceful degradation is a design requirement rather than a nice-to-have.

Two conclusions follow, and they shape everything else here:

  1. "The platform is up or down" is not a model that exists. Plan for the case where compute is healthy and one store is slow.
  2. Your own configuration is inside your responsibility. A misconfigured binding, a mismanaged secret, or exceeding a documented limit is not a platform failure — which makes change management part of your availability story.

Spikefrost's own commitment sits at 99.9% monthly uptime for app serving, deliberately beneath Cloudflare's compute figure to leave headroom for the excluded bindings and our control plane. Full terms in SLAs, limits and quotas.

The failure domains

Domain Blast radius Detected by Your mitigation
A single Cloudflare location Requests routed there, briefly Nothing to do — automatic None needed; reroute is automatic
The CDN / edge cache Cache misses; all traffic reaches your Worker Traffic spike into the isolate, x-sf-cache Ensure the app survives 100% miss traffic
Your Worker code That route, or all routes 5xx in request logs Rollback; guard rails in code
D1 (your app's database) Every route that queries it Errors or latency in logs Timeouts, cached reads, queued writes
A single Durable Object Only that key's clients WebSocket errors for that room Retry with backoff on the client
KV Cached lookups and flags Fallback path exercised Always code a default
R2 / assets Media and file downloads 5xx on asset URLs Assets are cached at the edge already
The Spikefrost control plane Deploys, CLI, agent dispatch. Not app serving Deploy failures None needed to keep serving traffic

The last row is worth stating explicitly to enterprise reviewers: a control-plane incident does not stop your deployed app from serving traffic. Your Worker and its bindings keep running; what you temporarily lose is the ability to ship changes.

The Durable Object row is the one people misread. Failure is scoped to one object, not the class — a problem with room-42 leaves the other hundred thousand rooms untouched. That granularity is a resilience feature, and it argues for many small objects over one large one.

Degrade, don't fail

The difference between an incident and an outage is usually whether the application was written to degrade.

A read path that degrades. Each fallback serves something useful; only the last resort is an error page, and writes are queued rather than dropped.

yes

no

yes

slow / error

yes

no

yes

no

Request

Edge cache
HIT?

Serve cached
no code, no DB

Query D1
within timeout?

Serve fresh

KV fallback
available?

Serve last-known-good
+ 'may be stale' notice

Static shell
usable?

Serve shell,
hydrate later

Honest error page
+ status link

A read path that degrades. Each fallback serves something useful; only the last resort is an error page, and writes are queued rather than dropped.

Four patterns that carry most of the weight:

Cache the read paths that can be cached. A cached route keeps serving when the database is unreachable, because it never touches it. This is the highest-leverage resilience work available and it's a one-line change per route — see Routing and pages.

Bound every dependency. Wrap a database or external call in a timeout and decide what to serve when it expires. Unbounded waits turn one slow store into a queue of stuck requests, which is how partial degradation becomes total.

Queue writes instead of dropping them. If accepting an order matters more than processing it this second, put it on a queue and acknowledge. The customer succeeds; the work drains when the store recovers.

Keep a kill switch in KV. A flag read on the hot path lets you disable an expensive feature in seconds with no deploy:

const heavyEnabled = (await c.env.KV.get('feature:recommendations')) !== 'off';

During an incident, seconds matter and a deploy is a minute. Flags are the fastest mitigation you have.

Mitigations, ordered by speed

Mitigation Time to effect Use when
KV feature flag Seconds An expensive or broken feature needs disabling
Maintenance mode Seconds The app must stop serving traffic entirely
Firewall rule / blocked path Seconds Abuse or a hot path needs blocking before your code runs
Code rollback (sf deploy --commit @1) ~1 minute A deploy caused it
D1 point-in-time restore Minutes Data was corrupted
Fix forward As long as it takes Everything else

Maintenance mode and firewall rules act before the isolate runs, so they work even when your code is the problem — worth remembering when the failing path is the one you'd need to deploy through.

What this platform does not give you

Stated plainly, because discovering it during procurement is worse:

  • No cross-provider failover. If a Cloudflare-wide event occurs, an app here is affected. Provider redundancy means running a second implementation elsewhere, which is a decision above this platform.
  • No control over data residency via compute placement. Code runs wherever the request lands. See Isolation and tenancy.
  • No point-in-time recovery outside D1. Durable Object and KV state cannot be rewound — see Durability and recovery.
  • No long-running processes to hold a warm connection or retry loop between requests. Use queues and schedules.

If any of these is a hard requirement, tell us before you build rather than after. We would rather lose a deal early than fail an architecture review late.

Next

Frequently asked questions

Does the 99.99% Workers SLO cover our whole application?

No, and this is the most important thing on this page. Cloudflare's Workers SLO covers the compute path and explicitly excludes the availability of storage bindings — D1, Durable Objects, KV, and R2. Compute and state do not fail together and are not guaranteed together.

What happens if a Cloudflare location goes offline?

Traffic reroutes to the next nearest location automatically. Because every location runs your code and holds no unique state, there is no failover to orchestrate and no region-level runbook to write.

What if the database is slow rather than down?

That's the more common and more dangerous case. Because D1 executes queries serially, a slow query delays every request behind it — so partial degradation looks like a site-wide slowdown. Timeouts and cached read paths are the mitigations.

Can we fail over to another provider?

Not within the platform. If provider-level redundancy is a hard requirement, an app on Spikefrost is one tier of your architecture rather than all of it — tell us early so nobody discovers the constraint late.

What's the fastest mitigation during an incident?

A feature flag in KV changes behavior in seconds with no deploy. Maintenance mode and firewall rules act before your code runs. A code rollback is about a minute. Choose by what's broken.