The real risk in website migration lies not in the “moving” action itself, but in the few minutes of switching. Data transfer can be verified repeatedly and done slowly, but once DNS is changed, all traffic instantly changes direction with no turning back.
The most frequent cause of migration incidents, which sounds basic, is actually this: failing to lower the DNS TTL in advance.
Why Downtime Always Occurs During Switching
TTL (Time To Live) determines how long various levels of DNS cache records. If your domain’s TTL is 86400 (24 hours), at the moment you change the resolution, a large number of recursive DNS servers and user local caches worldwide will still hold the old IP, taking up to 24 hours to query again.
The result is that some users access the new server while others remain on the old one—leading to data inconsistency, lost login sessions, and orders being written to two different databases. This is worse than simple downtime because the data becomes corrupted.
Executable Switching Timeline
T-48h Lower domain TTL to 60~300 seconds (otherwise, it may take up to 48 hours to take effect after switching)
T-24h New environment deployment complete; fully verify functionality using hosts binding
T-2h Perform incremental sync (especially for databases to minimize data gaps)
T-0 Stop writes to the old site (or set maintenance page) → Final incremental sync → Switch DNS
T+5min Verify item by item: Homepage, Login, Order Submission/File Uploads
T+30min Monitor new site error logs to confirm no anomalies
T+24h After confirming no issues, restore TTL to original value
Rollback Window: Keep the old environment running for at least 48 hours
TTL must be lowered in advance. Many people only remember to do it when switching DNS, which is too late—you are changing the TTL of the new record, but the expiration time of the old record in various caches still follows the original 86400.
Check Current TTL First
dig +short example.com A
dig example.com | grep -i ttl
Common Post-Migration Error Messages
# Database connection failed
Error establishing a database connection
# Database table corruption (due to interrupted transfer)
One or more database tables are unavailable. The database may need to be repaired.
# Incorrect file permissions; Web cannot read
403 Forbidden
(13)Permission denied: access to / denied
# Pseudo-static rules not configured — Homepage works, inner pages return 404
404 Not Found
# Character set mismatch; Chinese characters become question marks
??? or Incorrect string value: 'xF0x9F...' for column
Cause-and-Effect Reference Table
| Phenomenon | Root Cause |
|---|---|
| Homepage normal, inner pages all 404 | Pseudo-static (rewrite) rules not migrated |
| Database connection failed | Wrong credentials / No remote authorization / Database not started |
| Table corruption | Transfer interruption or disk full |
| 403 Forbidden | Incorrect file ownership or permissions; Web user cannot read |
| Chinese garbled text | Inconsistent character sets (utf8 vs utf8mb4) |
| Images not displaying | Incomplete file transfer or case-sensitive path mismatches |
| Mixed content warnings | Switched from http to https, but database still contains old addresses |
Synchronization and Verification Commands
# ① Incremental file sync — Executable multiple times, transfers only differences
# Ensure direction is correct; recommend using --dry-run first
rsync -avz --delete -e 'ssh -p 22' /var/www/html/ root@NewIP:/var/www/html/
# ② Database export — Must include character set, otherwise exported data will be garbled
mysqldump -u root -p --default-character-set=utf8mb4
--single-transaction --routines --triggers dbname > db.sql
# ③ Import
mysql -u root -p --default-character-set=utf8mb4 dbname < db.sql
# ④ Verify row counts after export/import
mysql -N -e 'SELECT COUNT(*) FROM wp_posts;' dbname
# ⑤ Bind hosts locally to verify new site — Full testing without changing DNS
echo "NewIP example.com www.example.com" >> /etc/hosts
# ⑥ Check error logs on both sides after switching
tail -f /var/log/nginx/error.log
tail -f /var/log/php-fpm/www-error.log
# ⑦ Fix permissions if encountering 403
chown -R nginx:nginx /var/www/html
find /var/www/html -type d -exec chmod 755 {} ;
find /var/www/html -type f -exec chmod 644 {} ;
Item ⑤ is the most practical trick in migration: By pointing the domain to the new server via hosts in advance, you can run through the entire site’s functionality completely without modifying any online configurations, including callback interfaces dependent on domains.
Decision Tree
Post-switch anomaly
├─ Homepage normal, inner pages 404 → Pseudo-static rules missing → Add rewrite
├─ Site-wide 403 → Ownership/Permissions → chown + chmod
├─ Database connection failed → Credentials / Authorization / Is it running?
├─ Table corruption → Re-import from backup (hence the need for a rollback window)
├─ Chinese garbled text → Unify utf8mb4 across the chain (export, import, table, connection)
├─ Images not displaying → Files not fully transferred / Path case sensitivity
└─ Some users still on old site → TTL not lowered in advance; must wait
Why Inconsistency Persists After Lowering TTL
There is a scenario that easily leads to misjudgment: Even though TTL was lowered to 60 seconds in advance, a significant number of users still access the old server after switching, prompting checks to see if the DNS record was edited incorrectly.
The actual reason is that some ISP DNS servers do not strictly adhere to your set TTL and cache records for longer periods on their own. This is beyond your control, so migration plans must account for this margin.
- Do not calculate old environment decommission time based on TTL values: A TTL of 60 seconds does not mean the whole world switches in 60 seconds; keep the old environment for at least 48 hours.
- Verify synchronization status using multi-location DNS probes before switching: Relying solely on local
digresults is insufficient. - For businesses intolerant of write splitting, stop writes during the switch window: Otherwise, each database writes part of the data, making the cost of merging much higher than downtime.
The conclusion is: Lowering TTL is a necessary condition, not a sufficient one. It significantly shortens the inconsistency window but cannot guarantee instantaneous global synchronization.
Another regrettable type of incident occurs when TTL is forgotten to be lowered in advance; half the users remain on the old site, and the old server is recycled the next day—these users lose access entirely. Therefore, the “keep old environment for 48 hours” rule in the process is just as important as “lowering TTL in advance”; missing either can lead to disaster.
Scenario Simulation: TTL Lowered in Advance, Yet Half Still Access Old Site After Switch
Phenomenon: DNS TTL was lowered to 60 seconds 48 hours before switching, yet a considerable proportion of requests still hit the old server after switching.
- First, confirm if TTL is truly effective → Use
digto check the TTL in the authoritative response; finding it remains 3600.
Do this step first because “I changed it” and “it took effect” are two different things; failing to verify after changing is the most common prerequisite error. - Investigate why TTL didn’t take effect → The modification took effect later than expected; at the actual effective time, only a few hours remained before switching,
meaning recursive servers everywhere were still caching the old value. - Look at the other half of the reason → Some network service providers do not strictly follow TTL and extend caching times themselves;
this portion of traffic cannot be controlled via TTL. - Handling → Do not shut down the old server; continue handling this traffic and reverse-proxy to the new server,
until traffic naturally decays to near zero. - Verification → Compare access logs from both servers, tracking the decline curve of old site traffic daily,
rather than looking at resolution results at a single moment.
Root Cause: Treating “TTL lowered” as “all visitors will immediately query,”
ignoring that cache effectiveness requires waiting for an original TTL cycle and the reality that some recursive servers ignore TTL.
Two Key Takeaways:
- Lower TTL at least one original TTL cycle in advance and verify effectiveness with dig.
Changing it without checking the TTL value in the response is equivalent to not changing it—the verification cost here is only a few seconds. - The old site must remain serviceable until logs confirm traffic has reached zero.
The criterion for “switch completion” is the traffic curve, not the switching action itself;
shutting down the old site early saves a few hours of machine costs but loses those real users who haven’t refreshed yet.
8 Common Pitfalls
- Lowering TTL on the day of switching: The number one cause of migration downtime; must be done 24–48 hours in advance.
- Omitting
--default-character-setinmysqldump: Default may not be utf8mb4; exported data becomes garbled, especially emojis. - Forgetting to export stored procedures and triggers: Omitting
--routines --triggerscauses direct loss of business functions. - Reversing rsync direction: Combined with
--delete, this wipes out new site files; run--dry-runfirst. - Shutting down the old site immediately after switching: If the new site has issues, rollback becomes impossible; keep the old environment for at least 48 hours.
- Testing only the homepage, not business logic: Form submissions, payment callbacks, and file uploads are most prone to failure due to environment differences.
- Linux case sensitivity: When migrating from Windows,
Image.jpgandimage.jpgare treated as two files, causing widespread image 404 errors. - Omitting email-related records: MX / SPF / DKIM are not in website files; omitting them interrupts email services directly.
Real Customer Feedback (From Cloud Market Reviews and Consultations for Similar Products)
The following excerpts are taken from real buyer reviews and consultations for similar operations services on Alibaba Cloud / Tencent Cloud / Huawei Cloud Cloud Markets (service providers include our store and peers, provided solely for reference of genuine feedback, not fictitious tickets from this site):
1****n Rating: 5.0 Jan 04, 2018 18:04
45***76 Apr 14, 2021 5.0 On-time delivery. Excellent.
10***02 Jul 31, 2024 5.0 Secure and reliable | Comprehensive features | Affordable price. Prompt handling, migration successful. 10***31 Jun 22, 2022 5.0 Affordable price | Skilled technology | Perfect after-sales. Good job, helped me migrate my years-old site to a new server.