Skip to content

Moving from Shared Hosting to a VPS

Section 1 of 7
Size 3 of 5

Virtual servers04/08Part of the “From shared hosting to your own server” track · Article 5 of 8

Moving from Shared Hosting to a VPS

When you’ve outgrown shared hosting, how to move your site to a VPS with minutes of downtime, harden it in the first hour, and what becomes your job.

Abdulwahed MohammadContent writer at tech+8 min read

If your site shows “508 Resource Limit Is Reached” at peak hours, or its jumps from 300 ms to two seconds every time you publish a new post, you’ve hit the ceiling of shared hosting. A VPS raises that ceiling, but it hands you work the provider used to do for you: updates, security, backups and monitoring. This article is a complete migration plan: how to confirm you really need one, how to move your site with minutes of downtime, and what to do in your first hour on the new server.

01Signs you’ve outgrown shared hosting

On shared hosting your account runs inside resource limits, usually enforced by CloudLinux : a share of a core, a fixed amount of memory, a number of concurrent processes, and a disk read/write rate. Going over them doesn’t just slow your site down; it gets requests refused. These signs say you’ve outgrown them:

  • Recurring 508 or 503 errors: They appear when your account hits its concurrent-process limit (Entry Processes) or its memory limit. The resource usage page in cPanel shows how many times each limit was hit (Faults); if that happens every day, the limit is choking your site.
  • TTFB doubles under load: Measure it in a quiet hour and at peak. A large gap on cached pages means the shared server is crowded, or your account is being throttled at its limit.
  • Software you can’t run: You need Redis, an always-on Node.js app, queue workers, a PHP extension that isn’t installed, or cron jobs every minute.
Measuring TTFB and the request phases. Repeat it ten times in a quiet hour and at peak, and compare the medians
# Request phases in seconds: DNS, connect, TLS, first byte and totalcurl -o /dev/null -s -w 'dns %{time_namelookup}  tcp %{time_connect}  tls %{time_appconnect}  ttfb %{time_starttransfer}  total %{time_total}\n' https://matbakh-amman.com/

Before you decide, make sure the slowness isn’t coming from the site itself: a heavy plugin, uncompressed images or no caching. Those problems move with you to any server, and a VPS won’t fix them.

A camera and a plate of food on a wooden kitchen table beside an open laptop and a memory card
A photo uploaded at full camera resolution can weigh more than the whole page should, and slows your site on any server until you resize and compress it.

02What becomes your job

On shared hosting the provider runs the server and you run your site. On a VPS you have , so you control everything, and you’re responsible for everything:

TaskShared hostingVPS
OS updates and security patchesThe providerYou
PHP version and extensionsPick from a listInstall whatever you want, and maintain it
Firewall and blocking login attemptsThe providerYou
BackupsUsually included in the planYou, with your own tools or the provider’s space
EmailUsually included in the planA separate decision: a hosted mail service or a mail server you run
SSL certificate renewalAutomaticYou set it up with ACME
Monitoring and alertsThe providerYou

If you don’t have time for these tasks, there are two middle paths: a higher shared plan with wider limits, or a VPS with a control panel that handles part of them for you. CoreVPS, for instance, lets you add a cPanel, Plesk or ISPmanager licence, or pick a ready-made app such as LEMP or WordPress when you order. As for the server’s size, work it out from your workload numbers, as we explain in a separate article on choosing a VPS.

An administrator, seen from behind, working on a laptop in the evening beside a notebook and tea
On a VPS, updates, security, backups and monitoring come out of your own time, except what a control panel you add takes over.

03A migration plan with minutes of downtime

The example: a recipe blog from Amman, matbakh-amman.com, running WordPress on cPanel hosting. The plan has seven steps:

  1. 01Two days before: lower the TTL: Set the of the domain’s A and AAAA records to 300 seconds, then wait out the full old TTL, which may be 14,400 seconds or a whole day. After that, caches won’t hold the old address for more than five minutes.
  2. 02Prepare the server: Harden it and install the stack as in the next two sections, and create the database with the name, user and password already in wp-config.php, so you don’t touch the configuration during the move.
  3. 03First sync: Copy the files and database while the site is still live on the old hosting. This pass takes the longest, with no downtime. If the old host doesn’t offer SSH, download a full cPanel backup and upload it.
  4. 04Test before switching: Copy the current SSL certificate to the new server temporarily, and test the site there on its new address without changing DNS.
  5. 05Freeze writes and sync the difference: Turn on maintenance mode for a few minutes, then sync the files again (rsync transfers only the difference), and re-dump and re-import the database.
  6. 06Switch DNS: Point the A and AAAA records at the new server, follow the change with Illevante’s DNS propagation checker, then issue a new certificate with certbot.
  7. 07Keep the old host for a week: Don’t cancel the old hosting for seven days, and watch its logs: any request that reaches it means a cache still holds the old address. Then raise the TTL back to 3,600 seconds or more.
Migration commands: dump the database, pull the files, import, and test the new server before switching DNS
# On the old hosting (cPanel Terminal): dump the databasemysqldump --single-transaction --quick -u matbakh_wp -p matbakh_wp > ~/matbakh.sql# On the new server: a site folder owned by your user, then pull the files and the dump over SSHsudo install -d -o "$USER" /var/www/matbakhrsync -az --info=progress2 [email protected]:public_html/ /var/www/matbakh/rsync -az [email protected]:matbakh.sql ~/sudo mysql matbakh_wp < ~/matbakh.sql# Test the new server before changing DNS, without touching the hosts filecurl -sI --resolve matbakh-amman.com:443:203.0.113.41 https://matbakh-amman.com/# The current TTL as the resolver sees it (the number after the domain name)dig +noall +answer matbakh-amman.com A# After the final sync only: hand the files to the web server usersudo chown -R www-data:www-data /var/www/matbakh

04The first hour: hardening the server

A new server with a public IP gets automated SSH login attempts within minutes of booting. Before you move any file onto it, create an admin user, switch to logging in with an instead of passwords, and close every port you don’t need. On Ubuntu or Debian:

An admin user and key-only login. The file name starts with 00 because sshd keeps the first value it reads, so it wins over a cloud-init file that may enable passwords
# 1) As root on first login: update the system, then create an admin userapt update && apt full-upgrade -y && apt install -y sudoadduser deployusermod -aG sudo deploy# 2) From your own computer: copy your public key to the new userssh-copy-id [email protected]# 3) As the new user, once key login works: turn off passwords and root loginprintf 'PasswordAuthentication no\nKbdInteractiveAuthentication no\nPermitRootLogin no\n' | sudo tee /etc/ssh/sshd_config.d/00-hardening.confsudo sshd -t && sudo systemctl reload ssh
Firewall, blocking brute-force attempts, and automatic security updates
sudo apt install -y ufw fail2ban python3-systemd unattended-upgrades# Firewall: allow SSH first, then the web, then enable itsudo ufw allow OpenSSHsudo ufw allow 80,443/tcpsudo ufw enable# fail2ban: ban for an hour any address that fails to log in 5 timesprintf '[sshd]\nenabled = true\nbackend = systemd\nmaxretry = 5\nbantime = 1h\n' | sudo tee /etc/fail2ban/jail.localsudo systemctl restart fail2bansudo fail2ban-client status sshd# Automatic security updatessudo dpkg-reconfigure -plow unattended-upgrades

05A lean stack

A WordPress site needs nothing more than Nginx, PHP-FPM, MariaDB and Certbot, plus Redis if you want an object cache. Every extra panel or service uses memory and adds attack surface, so install only what you use:

A lean WordPress stack on Ubuntu 24.04 or Debian 13
sudo apt install -y nginx mariadb-server redis-server certbot python3-certbot-nginx# Your distribution’s default PHP version with the common WordPress extensionssudo apt install -y php-fpm php-mysql php-curl php-gd php-intl php-mbstring php-xml php-zip php-redissudo mariadb-secure-installation# After switching DNS and setting up the Nginx server block: a new certificate, then test automatic renewalsudo certbot --nginx -d matbakh-amman.com -d www.matbakh-amman.comsudo certbot renew --dry-run

These packages install your distribution’s default PHP, which is 8.3 on Ubuntu 24.04 and 8.4 on Debian 13. If your site needs another version, use Ondřej Surý’s well-known PHP repository. And if you want a control panel, choose it when you order the server rather than installing it over an existing stack: panels such as cPanel and Plesk expect a clean system.

06Monitoring after the move

  • From outside: An availability check every minute from somewhere other than your server, alerting you when the site doesn’t answer or takes more than two seconds. A server that’s down can’t tell you it’s down.
  • From inside: Follow CPU, memory and disk live in your server’s control panel; for longer history and finer alerts, use Prometheus with Grafana.
  • Logs: Review the Nginx error log and the PHP-FPM logs in the first days: they reveal the plugin that needs a missing package or a file permission.
  • Certificate: After the switch, check the site with Illevante’s SSL checker to confirm the issuer, the chain of trust and the expiry date. With the maximum lifetime of public certificates cut to 200 days since March 2026, and to 100 days in 2027, manual renewal is no longer an option.
  • Backups: Turn them on from day one; we cover building them and testing restores in a separate article on VPS storage.
A quick health check for the first days
# Failed services, if anysystemctl --failed# Latest Nginx and PHP-FPM errorssudo tail -n 50 /var/log/nginx/error.logsudo journalctl -u 'php*-fpm' --since '1 hour ago'# The certificate renewal timersystemctl list-timers | grep certbot
ProblemSome visitors still see the old site a day after the switch
FixThe TTL wasn’t lowered early enough, or an ISP’s resolver ignores it. Follow it with the DNS propagation checker, and keep the old hosting running until requests to it stop.
ProblemEmail stopped after cancelling the old hosting
FixThe MX record pointed there, and changing the A record doesn’t touch it. Move email to a separate service and change MX days before cancelling.
Problem502 Bad Gateway after installing the stack
FixThe PHP-FPM socket path in the Nginx config doesn’t match the installed version. Check the socket’s name in /run/php and fix fastcgi_pass.
ProblemYou’re locked out after disabling passwords
FixThe key wasn’t copied to the right user. Log in through the console in the provider’s panel and fix the authorized_keys file.

07Before you move

A VPS is worth the move when the problem really is resource limits, not a heavy site that needs optimising. Measure first: 508 errors, how often limits are hit in cPanel, and TTFB at peak. Then count the time: two hours to set up and harden the server, and about an hour a month for updates, log reviews and backup tests.

If you or your team have that time, the move gives you resources reserved for your server, free of a shared account’s limits, and freedom at every layer of the stack. If you don’t, a higher shared plan or a server with a control panel is a sound engineering decision, not a step back.

Test your understanding

Three questions, one minute

⁦0 / 3⁩Set 1

  1. 01Your site shows 508 errors at peak, and cPanel’s resource usage page shows dozens of concurrent-process limit hits every day. What do you conclude?

  2. 02Your A record’s TTL is 86,400 seconds and you want to switch tomorrow with minimal downtime. What’s right?

  3. 03You want to turn off password and root logins. What must come first?

Ready to start? Power your projects today

Choose the hosting, server or domain that suits your business, and our specialist team is available around the clock to make your projects a success.

A .com domain a year
$17
cPanel hosting per month
$2
CoreVPS servers per month
$3.50