{
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "@id": "https://hostdir.net/blog/zero-downtime-hosting-migration",
    "headline": "Zero-downtime hosting migration: the playbook",
    "url": "https://hostdir.net/blog/zero-downtime-hosting-migration",
    "datePublished": "2026-06-05T16:45:00+00:00",
    "author": {
        "@type": "Organization",
        "name": "HostDir News Desk",
        "url": "https://hostdir.net"
    },
    "publisher": {
        "@type": "Organization",
        "name": "HostDir",
        "url": "https://hostdir.net",
        "logo": {
            "@type": "ImageObject",
            "url": "https://hostdir.net/assets/logo.svg"
        }
    },
    "image": "https://hostdir.net/uploads/blog/zero-downtime-hosting-migration__featured.webp",
    "description": "Moving a live site to a new host without a single failed request is not magic. It is one TTL drop, one warm cache, one careful DNS cutover, and a rollback plan. This is the playbook that works for almost every site under a million pageviews a month.",
    "articleSection": "Tutorials",
    "articleBody": "Moving a live site to a new host without a single failed request is not magic. It is one TTL drop, one warm cache, one careful DNS cutover, and a rollback plan. This is the playbook that works for almost every site under a million pageviews a month.\n\nMost hosting migrations are described as scary because the people doing them have not done one in a while. The mechanics are well-understood. The first time you do it carefully, the playbook is the same as the hundredth. What follows is the sequence that works for the typical migration: a single WordPress, Drupal, Django, Rails or static site, moving from one host to another.\n\nTwo weeks out: prepare the new host\nThe mistake people make is starting the migration on the day of the move. Almost everything can be done in advance, then the actual cutover is the last and smallest step.\nOn the new host:\n\n  Provision the box. Same OS family as the current host, ideally the same version. Migrating Ubuntu 20.04 to Ubuntu 24.04 in the same move is two migrations stacked on top of each other and you will regret it.\n  Install the runtime. PHP, Python, Node, Ruby, whatever the application needs. Match the version exactly.\n  Install the database. MySQL or Postgres, same major version as the source.\n  Install the web server. nginx, Apache or Caddy, configured for HTTPS even if you have not pointed DNS at it yet.\n  Set up the application directory layout. Empty for now, but the paths and permissions should match what the application expects.\n\nNone of this touches the live site. It can take as long as it takes. The point is to have the destination ready well before the cutover.\n\nOne week out: copy the application\nApplication code is the easy part. If it is in git, clone it. If it is not, this is the moment to put it in git. Migrating a site whose only copy of the code is on the production server is not migration; it is gambling.\nCopy any uploaded user files (the uploads directory, the media folder, the avatars) from the old host to the new. rsync is the right tool. Run it once to establish the baseline, then again on the day of the cutover for the delta.\nrsync -avz --delete \\\n    -e \"ssh -i ~/.ssh/migration_key\" \\\n    user@old-host:/var/www/site/uploads/ \\\n    /var/www/site/uploads/\n\nEditorial · HostDir\n\nThree days out: drop the DNS TTL\nThe single most important thing you can do in advance: drop the time-to-live on the DNS records for the site to a small value, typically 300 seconds (five minutes). The TTL is how long DNS resolvers cache the answer to \"what IP is example.com.\" Once you change it from the typical 3600 or 86400 seconds down to 300, every resolver worldwide will pick up the new value within one full TTL cycle.\nDoing this three days out gives the global DNS system time to converge. Doing it on the day of the cutover means a meaningful percentage of resolvers will still be caching the long TTL, and your cutover will take hours to propagate instead of minutes.\nThe cost of a low TTL is more DNS lookups, which is negligible for almost every site. Raise it back to 3600 or 86400 once the migration is done.\n\nThe day of: copy the database\nThe database is the hardest part because it is the part that changes during the migration. The pattern that works:\n\n  Put the old site into a low-write state. For a content site, this might mean disabling new comments and posts for a few hours. For an application, this might mean a maintenance page or a read-only mode.\n  Take a fresh database dump on the old host.\n  Transfer the dump to the new host.\n  Restore it.\n  Run any last-mile rsync for files that may have changed since the previous sync.\n\n# On the old host\nmysqldump --single-transaction --quick mydb &gt; /tmp/mydb.sql\n\n# Transfer\nscp /tmp/mydb.sql user@new-host:/tmp/\n\n# On the new host\nmysql mydb &lt; /tmp/mydb.sql\nFor Postgres, the same shape with pg_dump and pg_restore. For MongoDB, mongodump and mongorestore. The principle is the same.\n\nThe cutover: smoke test before DNS\nThe new host now has the application, the files, and the database. Before you point DNS at it, you need to be sure it actually works.\nEdit your local hosts file to map the production domain to the new host's IP. Open the site in a browser. Click through every important page. Log in as a real user. Check that the database is connected, that uploads work, that the cache is warm, that the CDN configuration points the right way.\n# On Linux/macOS: /etc/hosts\n# On Windows: C:\\Windows\\System32\\drivers\u001btc\\hosts\n203.0.113.42  example.com www.example.com\nIf anything is broken, fix it now. The site is still live on the old host; the new one is only visible to you. This is the cheapest moment to discover a problem.\n\nThe cutover: switch DNS\nWhen the smoke test is clean, switch the A record (and AAAA if you have IPv6) to point at the new host's IP. Because you dropped the TTL three days ago, the change propagates within minutes.\nWatch the new host's access log. You should see traffic begin to arrive within a minute or two. Within fifteen minutes, almost all traffic should be on the new host. Within thirty minutes, you can be confident the cutover is complete.\nThe old host will continue to receive a trickle of traffic for hours from resolvers that ignored the TTL or from clients that pinned the IP. Leave the old host running until that trickle dies, then decommission it.\n\nThe rollback plan\nIf the new host is broken in a way you did not catch in the smoke test, the rollback is to switch DNS back to the old host. Because the TTL is still 300 seconds, the rollback propagates as quickly as the cutover did. The old host is still running. The database may have a few writes that came in via the new host during the failed window; you reconcile those manually.\nThe mistake people make is decommissioning the old host the moment the new one looks alive. Leave it running for at least 48 hours. The bug you missed in the smoke test will reveal itself within the first day, and rollback is only possible if the old box is still there.\n\nVariations on the playbook\nThe shape above works for almost every site under a million pageviews a month. Beyond that, you start needing fancier techniques: blue-green deployments where both hosts run in parallel and you shift traffic gradually, database replication so the new host has live data when you cut over, traffic-shifting at a load balancer instead of at DNS. None of these are necessary for the typical migration. They are tools you reach for when the standard playbook is not enough.\nThe honest answer for most operators is that a careful TTL drop, a clean smoke test and a methodical DNS cutover does the job. The migrations that go wrong are almost always the ones where someone tried to skip a step to save an hour. Take the hour. Do it once, do it right, and the migration is boring instead of dramatic.",
    "mainEntityOfPage": "https://hostdir.net/blog/zero-downtime-hosting-migration",
    "_hostdir": {
        "kind": "blog-post",
        "slug": "zero-downtime-hosting-migration",
        "canonical": "https://hostdir.net/blog/zero-downtime-hosting-migration",
        "category": "tutorials",
        "attribution": "HostDir News Desk — https://hostdir.net/blog/zero-downtime-hosting-migration"
    }
}