Zero-Downtime Website Migration: The Complete Guide
Moving your website to a new host (or new server) doesn’t have to mean going offline. With some prep, a reliable rollback plan, and a staged cutover, you can switch traffic with users none the wiser. This guide walks you through a production-safe process you can reuse for WordPress, PHP frameworks (Laravel, CodeIgniter), static sites, and even most eCommerce stacks.
At a glance: Lower DNS TTL → full backups → stage on new host → sync files + database → verify on a hosts file preview → freeze writes → delta sync → switch DNS → monitor → re-enable writes → clean up.
Before You Start: Define Scope & Success Criteria
- Inventory the stack: app code, CMS (e.g., WordPress), DB (MySQL/MariaDB), file uploads, cron jobs, redirects, SSL, CDN, email routing, analytics, ad tags.
- Decide the window: low-traffic hours (based on analytics). Publish a maintenance notice only if you anticipate a brief content-freeze—not downtime.
- Success metrics: zero 5xx errors, median response time unchanged or better, no SEO regressions (no 404s for indexed URLs), forms and payments working, email deliverability intact.
Step 1 — Lower DNS TTL
DNS records often have a default TTL (time-to-live) of 1–24 hours. Lowering it to 300 seconds (5 minutes) a day or two before your move means your switch propagates fast. Update A/AAAA records for the root domain and CNAME for www. If you use a CDN (e.g., Cloudflare), ensure the proxying mode and caching rules are compatible with the new origin.
Step 2 — Back Up Everything
- Files: code + media (e.g., /wp-content/uploads in WordPress).
- Database: mysqldump or a panel export; verify the dump by importing into a local test DB.
- Config: .env/wp-config.php, .htaccess/nginx.conf, PHP version, extensions, scheduled tasks.
- SSL & keys: export certificates or be ready to issue Let’s Encrypt on the new host.
Tip: Store backups in offsite storage (S3/Backblaze) and label them with a timestamp. Test a mini-restore so you trust the safety net.
Step 3 — Stage on the New Host
Create a staging environment that mirrors production:
- Set PHP version, memory limits, upload limits, and necessary modules (e.g., imagick, intl).
- Set up the database and an app user with least-privilege access.
- Copy site files (excluding cache folders) and import your database.
- Generate/attach an SSL certificate for the staging domain or use HTTPs with a self-signed cert if you’re testing locally.
Step 4 — Preview Using Your Hosts File
Rather than exposing staging publicly, preview the site on your machine by mapping the production domain to the new server’s IP in your hosts file. That way, you see the site as if DNS has already switched, while the world keeps hitting the old server.
- macOS / Linux: edit /etc/hosts
- Windows: edit C:\Windows\System32\drivers\etc\hosts
Visit your domain; only you will see the new host. Test pages, forms, search, logins, admin flows, and any third-party scripts (analytics, ads, chat).
Step 5 — Freeze Writes (Short Content Lock)
To avoid data divergence during the final sync, put the old site into a brief “content freeze.” For blogs, this means pausing new posts/comments; for stores, scheduling a short “checkout pause” window. Keep the site readable—just block actions that write to disk/DB. For WordPress, set the site to maintenance mode for admins only (or temporarily disable comments/uploads), and place a friendly banner to inform contributors.
Step 6 — Delta Sync (Files + DB)
Perform a final, incremental sync to capture changes since staging:
- Files: use rsync or your panel’s file manager. Exclude caches and tmp folders.
- Database: run a fresh mysqldump from the old host and import it into the new host’s DB.
- Configuration: ensure env vars, SMTP settings, payment/webhook secrets, and any API keys are updated.
Step 7 — Go Live: Switch DNS
With TTL already low, switching the A/CNAME records to the new server is instantaneous for most users within minutes. If using a CDN, update the origin IP there instead. Keep the old server online for 24–48 hours to serve stragglers whose resolvers cached the old IP.
Step 8 — Post-Cutover Verification
- Crawl: run a quick crawl (e.g., Screaming Frog or an online crawler) to catch broken links or 404s.
- Logs: monitor access/error logs for spikes, 4xx/5xx bursts, or slow queries.
- SEO: confirm robots.txt, XML sitemaps, canonical tags, and existing redirects.
- Forms & email: test contact forms, password reset flows, and transactional email (check SPF/DKIM/DMARC alignment).
- Payments: do a test order (in sandbox) if you run eCommerce.
Rollback Plan (Have It Ready—Rarely Needed)
If something critical appears, revert DNS to the old server (thanks, low TTL), re-enable writes there, and investigate without pressure. Because you kept the old host intact, rolling back is a record change—not a crisis.
Platform-Specific Notes
WordPress
- Search/replace: if domain changes, run a serialized-safe search/replace on the DB to update URLs.
- Uploads: ensure /wp-content/uploads is fully synced; consider offloading to S3/Cloudflare R2 for future resilience.
- Cache: clear page/object caches after cutover; warm the homepage and key landing pages.
- Security: re-issue salts, confirm firewall rules, and disable any host-specific MU-plugins that don’t apply.
PHP/Laravel
- Copy .env securely; regenerate app key if building fresh.
- Run composer install --no-dev and php artisan migrate --force (if schema changes).
- Set file permissions for storage and bootstrap/cache.
Static Sites
- Just sync the build output directory (dist/ or public/).
- Enable GZIP/Brotli and caching headers; verify redirects and 404 handling on the new server.
eCommerce
- Freeze checkout briefly; communicate the window in advance.
- Recreate webhooks on the new origin (payment gateway, fulfillment, email service).
- Validate tax/shipping integrations and inventory sync after cutover.
Performance & Security Quick Wins During the Move
- PHP version bump: move to a supported, faster PHP (subject to plugin/theme compatibility).
- HTTP/2/3 + TLS 1.3: ensure the new stack supports modern protocols.
- WAF/CDN: place a lightweight WAF/CDN in front for DDoS and caching benefits.
- Image optimization: convert heavy images to WebP/AVIF where feasible.
Common Pitfalls (and How to Avoid Them)
- Forgetting email DNS: If mail is hosted elsewhere (Google/Microsoft), don’t change MX records. Keep SPF/DKIM/DMARC aligned.
- Mixed content after SSL: Update hard-coded http:// assets to https:// and enforce HSTS only once everything’s clean.
- Permissions mismatch: Ensure the web user can write to cache/upload directories—avoid 777 shortcuts.
- Uncleared caches: Edge caches (CDN) or plugin caches can show “old site” to part of your audience; purge thoroughly.
- No monitoring: Add uptime and error alerting before the move. If something blips, you’ll know instantly.
SEO Considerations
- Retain URL structure; if you must change, map 301 redirects one-to-one.
- Keep title/meta/structured data intact; don’t ship a template change on cutover day unless you planned and tested it.
- Resubmit the XML sitemap in Search Console post-cutover and fetch a few key pages.
- Monitor index coverage and Core Web Vitals for a couple of weeks.
Blue-Green Concept (Optional)
For high-traffic or mission-critical apps, run a “blue-green” setup: blue (current) and green (new) environments behind a load balancer or DNS. Smoke-test green with internal traffic, then switch 100% of traffic when ready. The old environment remains your instant rollback.
Communication Template (Copy/Paste)
Subject: Heads-up: Site infrastructure upgrade (no downtime expected)
We’re upgrading our hosting to improve speed and reliability. The change happens during a low-traffic window. No downtime is expected; you may briefly see cached content while things update. If you notice anything odd, please reply to this email or use the contact form. Thank you!
Launch-Day Timeline
- Confirm backups and rollback steps.
- Freeze writes and capture delta backups.
- DNS switch (or CDN origin update).
- Purge caches (app + CDN), warm key pages.
- Run automated and manual checks (forms, payments, search, 404s).
- Re-enable writes; keep the old host as a safety net for 24–48 hours.
FAQs
How long should I keep the old server? 24–48 hours is standard; heavy B2B audiences with strict resolvers may warrant 72 hours.
Will users lose sessions or carts? If you switch domains or session keys, yes. Otherwise, most PHP sessions will naturally expire—warn active users during the short window. For WooCommerce, schedule cutover outside peak shopping time.
What about email? If your domain’s email is with Google/Microsoft, leave MX as is. If email moves too, plan a separate sync window and keep IMAP copies.
Related: How DNS Works · Website Speed Optimization · Website Security Checklist
References for sitewide layout/style alignment:
:contentReference[oaicite:0]{index=0}
:contentReference[oaicite:1]{index=1}