Why migrations cause downtime (and how to avoid it)
Most website moves don't go down because copying files is hard — they go down because of DNS propagation. The moment you point your domain at a new server, some visitors keep hitting the old one for minutes or hours, governed by your DNS record's TTL (Time To Live). If the old server is already wiped or the database is split between two locations during that window, you lose requests, orders, or form submissions.
The trick to a near-zero-downtime migration is simple in principle: keep the old site fully live, build a complete working copy on the new host, prove it works before you switch, lower your TTL in advance so the cutover is fast, and only then change DNS. This guide walks through that process for a typical PHP/MySQL site (WordPress, Laravel, custom apps) and applies equally to a server you control or a cPanel/web hosting account.
If you're moving to keep data inside Saudi Arabia for PDPL/NCA alignment, Skyline Cloud hosts in-Kingdom — but the steps below are universal.
Step 1 — Lower your DNS TTL first (24–48 hours ahead)
This is the single most important step, and it must happen before anything else. TTL tells resolvers how long to cache your records. If your A record TTL is 14400 (4 hours), a cutover can take up to 4 hours to fully propagate.
In your DNS provider (or managed DNS), set the TTL on your A, AAAA, CNAME, and www records to a low value — 300 seconds (5 minutes) is a safe choice:
Type Name Value TTL
A @ <OLD_SERVER_IP> 300
A www <OLD_SERVER_IP> 300
Do not change the IP yet — only the TTL. Then wait at least as long as the old TTL so every cached copy expires. After cutover you can raise the TTL back to 3600 or higher.
Step 2 — Provision the new host and copy files
Create your account or server on the new host first. If you're on Skyline Cloud, spin up your VPS or web hosting plan and note the new server's IP.
For a server you have SSH access to, rsync is the fastest and most reliable copy — it preserves permissions, is resumable, and can be re-run to sync only changes:
rsync -avz --progress -e ssh /var/www/html/ user@NEW_SERVER_IP:/var/www/html/
-apreserves permissions, ownership, timestamps, and symlinks-vverbose,-zcompresses in transit- The trailing slash on the source copies contents, not the folder itself
For cPanel-to-cPanel moves, the built-in Backup → Full Account Backup or a host-assisted transfer is usually simpler than manual rsync. Many providers, including Skyline, will run the transfer for you.
Step 3 — Migrate the database
Export the database on the old server:
mysqldump -u DB_USER -p --single-transaction --quick DB_NAME > backup.sql
--single-transaction gives a consistent snapshot of InnoDB tables without locking the live site. Copy the dump across and import it on the new server:
scp backup.sql user@NEW_SERVER_IP:~/
mysql -u DB_USER -p NEW_DB_NAME < backup.sql
Then update your application's config with the new database credentials — wp-config.php for WordPress, .env for Laravel, or the equivalent.
Step 4 — Test the new site BEFORE changing DNS
This is what makes the migration near-zero-downtime: you fully verify the new server while the live site is still on the old one. Force your machine only to resolve the domain to the new IP by editing your hosts file.
On macOS/Linux, edit /etc/hosts; on Windows, C:\Windows\System32\drivers\etc\hosts:
NEW_SERVER_IP example.com www.example.com
Now your browser loads the new server for example.com while the rest of the world still sees the old one. Click through pages, log in, test forms, checkout, and admin. Fix anything broken. When everything works, remove the hosts entry.
| Check | What to confirm |
|---|---|
| Pages load | No 500/database errors |
| Logins work | Sessions, cookies, admin access |
| Forms/checkout | Submissions reach the database |
| SSL | Valid certificate on the new host |
| Mail still routes (see Step 6) |
Step 5 — Final sync and DNS cutover
Briefly put the old site into maintenance/read-only mode so no new data is written during the final sync. Re-run rsync (it copies only changes) and a final mysqldump/import to capture last-minute writes. Then update DNS:
Type Name Value TTL
A @ <NEW_SERVER_IP> 300
A www <NEW_SERVER_IP> 300
Because the TTL is 300, most visitors switch within five minutes. Keep the old server running until traffic fully drains — typically 24–48 hours — so anyone still on a cached record gets served correctly. This overlap is what prevents lost requests.
Step 6 — Don't forget email, SSL, and verification
- Email (MX records): if your domain's email is hosted separately, leave the
MXrecords untouched during a web move. Migrating mailboxes is a separate process — see business email hosting for an in-Kingdom mail setup. - SSL: issue a fresh certificate on the new host before cutover (Let's Encrypt or your panel's auto-SSL) so HTTPS works the instant DNS flips.
- Verify propagation: check from multiple locations:
dig +short example.com
Run it from a couple of networks, or use a global DNS-propagation checker, until everyone resolves to the new IP.
Step 7 — After the cutover
Once traffic has fully moved and the old server has been idle for a day or two:
- Raise your TTL back to
3600or higher for stability and fewer DNS lookups. - Take a final backup of the old server, then decommission it.
- Update monitoring, cron jobs, and any hardcoded IPs in your app or firewall.
- Re-test forms and payments on the live new server.
Migration checklist
- [ ] TTL lowered to 300 (24–48h before)
- [ ] New host provisioned, files copied via
rsync - [ ] Database exported and imported, config updated
- [ ] New site tested via hosts file
- [ ] Old site set read-only, final sync done
- [ ] DNS pointed to new IP
- [ ] Old server kept live 24–48h
- [ ] Email/MX and SSL verified
- [ ] TTL raised back, old server decommissioned
Done carefully, your visitors never see an error — only a faster, in-Kingdom site.
Ready to move? Create your Skyline Cloud account and host inside Saudi Arabia with PDPL/NCA-aligned data residency, transparent pricing, and local Arabic support.
Comments
0 total · 0 threads