Why DNS TTL is an Advisory Hint, Not an Enforcement Contract
A example.com 60 192.0.2.1, the client behind an ISP resolver might receive or retain that record for much longer.
Client behavior introduces another layer of persistence. Web browsers and operating systems maintain their own internal DNS caches that do not always align with authoritative records. Modern browsers also maintain persistent HTTP/1.1 and HTTP/2 TCP connections (keep-alive). If a user opened a checkout session or dashboard tab prior to the DNS change, the browser reuses the existing socket connection to the old server without triggering a fresh DNS lookup at all, regardless of whether the record has technically expired.
If you assume DNS cutover is instantaneous, users who have resolved the new IP address will write data to the new database, while users whose resolvers cached the old record will continue writing to the old database. Reconciling divergent database auto-increment keys, session tables, and transaction logs after the fact is painful and prone to human error.
For a deeper look at how recursive caching isolates upstream record states from downstream monitors, see our analysis on why your uptime monitor stays green during an authoritative DNS outage.
The Three Cutover Paths
Option 1: Hard Maintenance Window (Read-Only Mode)
- Workload match: Ideal for internal tooling, non-critical web portals, or sites where an hour of scheduled downtime has minimal financial impact.
- Budget & Resources: Lowest setup cost. Requires no additional networking infrastructure or load balancers.
- Risk profile: Zero risk of database split-brain. The trade-off is guaranteed user disruption during the propagation tail.
Option 2: Reverse Proxy Forwarding at the Old Origin
- Workload match: Best suited for transactional websites, dynamic WordPress or Magento stores, and REST APIs that cannot afford extended downtime during regular migrations between standard cloud providers.
- Budget & Resources: Low cost, but requires solid understanding of web server proxy configuration, header preservation (
Host,X-Forwarded-For,X-Forwarded-Proto), and SSL termination between nodes. - Risk profile: Prevents split-brain entirely while maintaining service availability. The main risk is increased latency for straggler requests travelling across the network hop between the old and new hosts.
Option 3: Upstream Edge or Load Balancer Origin Switching
- Workload match: Enterprise platforms, high-concurrency APIs, and mission-critical applications that require sub-second cutover without relying on remote client DNS resolution.
- Budget & Resources: Highest ongoing cost and architectural complexity. Requires maintaining a centralized load balancing or CDN layer in front of the infrastructure.
- Risk profile: Minimal cutover latency and zero split-brain risk. The primary operational risk lies in configuration errors within the edge layer itself.
Evaluating Your Options
| Evaluation Factor | Hard Maintenance Window | Old-Origin Reverse Proxy | Centralized Edge Switch |
|---|---|---|---|
| Downtime Required | Full write downtime during cutover | Zero downtime | Zero downtime |
| Split-Brain Risk | Zero (writes are disabled) | Zero (writes routed to new host) | Zero (traffic switched at edge) |
| Infrastructure Complexity | Minimal | Low (standard web server config) | Moderate to High |
| Bandwidth Cost | None | Double egress on straggler traffic | Standard edge transit costs |
| Skill Level Needed | Junior sysadmin / webmaster | Support engineer / sysadmin | DevOps / Infrastructure engineer |
Implementing Reverse Proxy Forwarding on the Old Host
NGINX
server {
listen 80;
listen 443 ssl http2;
server_name example.com www.example.com;
# Existing SSL certificates must remain valid on the old host
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
location / {
# Forward directly to the new server IP address
proxy_pass https://203.0.113.50:443;
# Preserve client headers and host context
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Ensure large payloads like file uploads pass through
client_max_body_size 64m;
proxy_connect_timeout 10s;
proxy_read_timeout 60s;
}
}