+44 7575 472931[email protected]
HostAccentKnowledge BaseHosting, websites, SEO, and growth

Migrate from Shared Hosting to Linux VPS Without Downtime: Practical Checklist

A step-by-step checklist to move from shared hosting to Linux VPS safely — backup, stack setup, DNS cutover, and rollback strategy so nothing breaks.

Linux HostingVPSCloud HostingMigration Guides
Migrate from Shared Hosting to Linux VPS Without Downtime: Practical Checklist - Linux Hosting guide cover image

Moving from shared hosting to a VPS sounds scarier than it is. The site goes down during migration, the database doesn't import cleanly, the PHP version is different — these are the stories people tell. But almost all of them come from the same source: skipping steps and rushing the cutover.

Follow this checklist in order and your migration will be predictable. There are no shortcuts worth taking here.

When you actually need to migrate

Before you start: make sure migration is the right answer. If your shared hosting TTFB is under 600ms, your site loads in under 3 seconds, and you're not hitting resource limits — you might not need VPS yet.

Migrate when you see:

  • Consistent TTFB above 800ms
  • "Resource limit exceeded" errors or CPU throttling from your host
  • Traffic growing beyond 20,000–30,000 monthly visitors
  • Need for custom server software (Redis, custom PHP config, Node.js)
  • WooCommerce slow queries your host can't resolve

Step 1: Full backup before touching anything

This is non-negotiable. Take a complete backup from your current shared host before any other step:

bash
# Files backup
tar -czf site-files-backup.tar.gz /home/username/public_html

# Database backup
mysqldump -u dbuser -p dbname > db-backup.sql

Store a copy off-server — download it to your local machine or upload to cloud storage. Your old host's backup is not sufficient; if something goes wrong mid-migration, you need a copy you control.

Also note your current settings:

  • PHP version (check in cPanel or phpinfo())
  • MySQL/MariaDB version
  • Any custom PHP.ini settings
  • Cron jobs running on the old server

Step 2: Provision and harden your VPS first

Set up your VPS completely before touching your live site. This means:

bash
sudo apt update && sudo apt upgrade -y

Security baseline (SSH keys, UFW, fail2ban) — see our Linux VPS security guide.

Then install your web stack. Match PHP and MySQL versions to what your site currently runs:

bash
sudo apt install nginx mysql-server php8.2-fpm php8.2-mysql php8.2-curl php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip -y
php -v
mysql --version

For WordPress, also install:

bash
sudo apt install php8.2-imagick php8.2-redis -y

Version matching matters. A WordPress plugin that works on PHP 7.4 may behave differently on PHP 8.2. Better to discover this in testing than after cutover.

Step 3: Configure Nginx and create web root

bash
sudo mkdir -p /var/www/example.com/public_html
sudo chown -R www-data:www-data /var/www/example.com

Create your Nginx server block (/etc/nginx/sites-available/example.com):

nginx
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com/public_html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_name;
    }
}
bash
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 4: Copy files and database to VPS

bash
# Copy files
scp site-files-backup.tar.gz user@your-vps-ip:/tmp/

# Copy database
scp db-backup.sql user@your-vps-ip:/tmp/

On the VPS:

bash
# Extract files
sudo tar -xzf /tmp/site-files-backup.tar.gz -C /var/www/example.com/public_html --strip-components=1
sudo chown -R www-data:www-data /var/www/example.com

# Import database
sudo mysql -u root -p -e "CREATE DATABASE exampledb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mysql -u root -p -e "CREATE USER 'dbuser'@'localhost' IDENTIFIED BY 'strong-password';"
sudo mysql -u root -p -e "GRANT ALL ON exampledb.* TO 'dbuser'@'localhost';"
sudo mysql -u root -p exampledb < /tmp/db-backup.sql

Update your wp-config.php (or app config) with the new database credentials:

php
define('DB_HOST', 'localhost');
define('DB_NAME', 'exampledb');
define('DB_USER', 'dbuser');
define('DB_PASSWORD', 'strong-password');

Step 5: Test with /etc/hosts before touching DNS

This is the step most people skip and then regret. Before changing DNS, point your local machine to the new server by editing your hosts file:

On Mac/Linux: /etc/hosts On Windows: C:\Windows\System32\drivers\etc\hosts

Add:

bash
YOUR_VPS_IP  example.com www.example.com

Now open example.com in your browser — you're actually hitting the new VPS. Test everything:

  • [ ] Homepage loads correctly
  • [ ] WordPress admin login works
  • [ ] All pages and posts render
  • [ ] Contact forms work
  • [ ] WooCommerce checkout (if applicable)
  • [ ] Images and media load
  • [ ] No PHP errors in logs (sudo tail -f /var/log/nginx/error.log)

Fix any issues here before DNS cutover. This is your last safe testing window.

When done, remove or comment out the hosts file entry.

Step 6: Reduce DNS TTL 24 hours before cutover

Log into your DNS provider and lower your A record TTL to 300 seconds (5 minutes). This needs to be done 12–24 hours in advance, because the current TTL determines how long DNS resolvers cache the old value.

If your current TTL is 86400 (24 hours) and you change the A record now, some users will still hit the old server for up to 24 hours. Lowering TTL first makes the switch near-instant.

Step 7: Install SSL on the VPS before cutover

Install Certbot and get your SSL certificate ready:

bash
sudo apt install certbot python3-certbot-nginx -y

You can't run certbot --nginx until DNS points to your VPS (Let's Encrypt validates via HTTP). So have this ready to run immediately after DNS propagates:

bash
sudo certbot --nginx -d example.com -d www.example.com

Step 8: The cutover

Choose a low-traffic window — early morning on a weekday works for most business sites. For ecommerce, check your analytics for the slowest hour of the week.

Sequence:

  1. Put old site in maintenance mode (optional but cleaner)
  2. Take a final incremental backup — sync any new database changes since your initial backup
  3. Update DNS A record to your VPS IP
  4. Run Certbot as soon as the domain resolves to the new IP
  5. Monitor error logs on the new server for 30 minutes
  6. Test from a mobile device (different DNS resolver than your computer)
bash
# Watch nginx error log in real time:
sudo tail -f /var/log/nginx/error.log

# Watch PHP errors:
sudo tail -f /var/log/php8.2-fpm.log

Step 9: Keep old hosting active for 48–72 hours

Do not cancel your old shared hosting immediately. Keep it active for at least 48–72 hours after DNS change. DNS propagation is not instant globally — some users may still reach the old server for a day or two.

After 72 hours, if everything is running clean on the VPS, you can safely cancel old hosting.

Checklist summary

Before migration:

  • [ ] Full file and database backup taken and stored off-server
  • [ ] PHP/MySQL versions documented
  • [ ] Cron jobs documented

VPS setup:

  • [ ] Security baseline applied
  • [ ] Nginx + PHP-FPM + MySQL installed with matching versions
  • [ ] Web root created, permissions set

Migration:

  • [ ] Files and database copied and imported
  • [ ] App config updated with new DB credentials
  • [ ] Tested with /etc/hosts before DNS change

Cutover:

  • [ ] DNS TTL lowered 24h in advance
  • [ ] Certbot ready to run
  • [ ] Cutover done in low-traffic window
  • [ ] Error logs monitored post-cutover

Cleanup:

  • [ ] Old hosting kept active 48–72h
  • [ ] SSL confirmed working
  • [ ] Search Console submitted (if domain changed)

Common migration problems and fixes

Images not loading — Usually a file permissions issue. Run: sudo chown -R www-data:www-data /var/www/example.com

WordPress says "database connection error" — Check wp-config.php database credentials. Confirm MySQL user has correct grants.

PHP errors that didn't exist on shared hosting — Version mismatch. Check error_log and update deprecated function calls or plugin versions.

Redirect loops — Nginx + WordPress permalink mismatch. Make sure try_files $uri $uri/ /index.php?$args; is in your Nginx config.

Moving to HostAccent VPS? Our team can help with migration for any plan. Clean Ubuntu images, NVMe storage, and support that actually knows Linux.

Reviewed by

HostAccent Editorial Team · Editorial Team

Last updated

Apr 12, 2026

HostAccent Editorial Team publishes practical hosting guides, operations checklists, and SEO-focused tutorials for businesses building international web presence.

Discussion

Have a question or tip about this topic? Share it below — your comment will appear after review.

Your email stays private and is only used for moderation.

How do I choose the right VPS location for my audience?

Pick the datacenter closest to your primary users, then test latency, page speed, and checkout flow from that region before scaling.

When should I move from shared hosting to VPS?

Move when you need guaranteed resources, root-level control, custom server tuning, or when traffic spikes cause unstable performance.

What baseline security should a new VPS have?

Use strong SSH practices, firewall rules, auto security updates, regular backups, and active monitoring for uptime and suspicious activity.

Start typing to find the right article.

Write for the Community

Have a tutorial, tip, or insight to share? Get published on the HostAccent Blog with your name, bio, and website link.

Become a Contributor