DNS is where most multi-CDN estates actually steer: the delivery hostname resolves to different CDNs for different users, by weight, geography or health, and no client changes at all. It is also a control plane with famous quirks — caching you don’t control, resolvers that ignore your TTLs, and a granularity of “per resolver,” not per user. Here is the build in order, with the quirks priced in rather than discovered.
How DNS steering works, and its honest limits
The mechanism: your delivery hostname is a CNAME managed by an intelligent DNS platform, which answers each query with CDN A’s or CDN B’s target based on policy — static weights, geographic rules, health-check state, or telemetry. Understand three built-in limits before designing around them. Granularity: decisions apply per resolver, and one resolver may sit in front of an ISP’s entire customer base — fine for percentage splits and geo policy, hopeless for per-user logic. Latency of action: a change propagates only as cached answers expire, so “instant failover” is really “failover within roughly a TTL, mostly” (section four). And visibility: geographic policy sees the resolver’s location unless clients’ resolvers send EDNS Client Subnet, which the big public resolvers handle differently. These limits are exactly why client-side switching exists for the cases that can’t accept them — the comparison is in our steering-vs-switching piece — but for most web estates DNS’s reach and simplicity win.
Step 1: the DNS platform and the record design
You need a DNS provider with weighted answers, health-checked failover and geo policies as first-class features — the managed-DNS tier compared in our field guide; run it on infrastructure independent of both CDNs, because a steering layer that fails with one of the platforms it steers is not a control plane. Record design: keep the user-facing hostname (www, media) as the policy-bearing CNAME; keep each CDN’s native target (customer.cdn-a.net, customer.cdn-b.net) as the answer set; and mind the apex — bare domains can’t CNAME, so use your provider’s ALIAS/ANAME flattening or keep the apex as a redirect to www, per the choices in configuring DNS for a CDN. Both CDNs must be configured to accept the same user-facing hostname with valid certificates — the estate-wide cert workflow is in the certs-and-DNS guide — before a single steering record exists.
Step 2: health checks that tell the truth
Failover quality equals health-check quality. Check what users need, not what is easy: an HTTPS fetch of a real page through each CDN’s path (resolving that CDN’s target explicitly), validating status and a content marker — not a ping, not a bare TCP connect, which stay green through most real CDN failures. Probe from several regions and require multi-region agreement before declaring a platform down, so one probe network’s bad morning doesn’t drain a healthy CDN. Add hysteresis in both directions: several consecutive failures to mark down, a longer clean streak to mark up, because flapping a platform in and out multiplies every propagation delay. And test the checks themselves quarterly — break a staging hostname deliberately and time detection-to-drain; a health check that has never fired is a hypothesis, the same discipline as every alarm in synthetic monitoring.
Step 3: TTLs and the resolver reality
TTL sets your steering speed limit: 30–60 seconds is the working range for steered hostnames — low enough that weight changes and failovers act within a minute or two, high enough that resolvers aren’t re-querying constantly (and your DNS bill, priced per query, stays sane). Then accept the untidy truth: a minority of resolvers cache longer than told, some clamp very low TTLs up, and a long tail of clients will keep arriving at a drained platform for many minutes. Design for that tail rather than against it: never take a “drained” CDN’s config down (it must keep serving stragglers correctly), and during planned migrations keep both platforms fully valid for days, not minutes. Measure your own propagation empirically once — flip a test weight and watch per-CDN traffic curves — so the incident-day expectation is a measured number, not a hope.
Step 4: policies, testing and go-live
Start with the simplest policy that delivers your architecture: fixed weights for an active-active split (the workload-and-ratio decisions are in splitting traffic), failover-only records for active-passive, geo rules only where a regional case is proven. Then rehearse before go-live: with a small percentage live on the steered hostname, drain each CDN in turn and watch traffic move at the speed section four predicted; verify sessions survive the move (the session-continuity checklist is its own guide); and only then ramp percentages up. Keep every policy change in version control with a rollback, and resist policy sprawl — each clever rule is another behaviour to test quarterly. Graduation to telemetry-driven steering — weights set by measured per-network performance instead of by hand — is the natural next step once this foundation is boring, and it is covered in steering on RUM data.
