The point of a second CDN is not the second CDN — it is the sixty seconds in which traffic moves to it without a human awake. This guide builds the minimum honest version: two providers, health-checked DNS steering, and a failover you have actually tested.
The architecture in one paragraph
Both CDNs sit in front of the same origin, each fully configured and certificated for your hostnames. Above them, a DNS-level traffic steering service (managed DNS with health checks, or a dedicated traffic manager) answers your hostname with CDN A or CDN B based on health and policy. Users notice nothing; the steering layer is the brain, and it must live outside both CDNs — a steering service hosted on the failing provider fails with it.
Health checks that reflect users, not datacenters
A ping from one monitoring node to a POP is not health. Check the full path users take: fetch a real object over HTTPS through each CDN’s production hostname, from multiple external regions, validating status code and a content checksum. Alert-and-steer thresholds: three consecutive failures from two or more regions moves traffic; one region alone alerts humans but does not steer, or a single measurement outage will ping-pong your traffic at 3 a.m.
Configuration parity is the real work
Failover fails when the backup CDN answers differently: a missing redirect, an unsynced signed-URL key, a stale certificate. Treat edge configuration as code — keep both providers’ configs generated from one source of truth, and make every change a two-provider change with a parity test (same top-50 URL diff as a migration). Rotate shared secrets on both providers in the same change window. Parity drift is measured in weeks, so a weekly automated diff is not paranoia, it is maintenance.
Weights, TTLs, and the cost of standby
Run active/active at something like 80/20 rather than active/standby at 100/0: the 20% keeps the second provider’s caches warm, its config battle-tested, and its invoice honest — a truly cold standby fails its first real test on cache misses alone. Set the steering record’s TTL to 60 seconds or below; failover speed is bounded by TTL plus detection time. Commercially, size each contract’s commit to its steady-state share, and confirm neither contract penalizes burst — failover doubles the survivor’s traffic instantly, which is an overage-clause stress test.
Test it like you mean it
A failover that has never fired is a hypothesis. Quarterly, in a low-traffic window: block the primary’s health-check object (a WAF rule matching the checker’s path works), watch detection → steer → recovery on your own dashboards, and time it end to end. Record user-visible error rate during the transition; sub-60-second steering with under 0.1% errors is a pass. Then fail back deliberately and re-run the parity diff — the fail-back finds the drift the failover hid.
When this runs clean twice in a row, put the runbook next to the on-call rota and stop thinking about it. That is what the second CDN buys: the right to stop thinking about it.
