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.
# 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-doha.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.

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:
| Task | Shared hosting | VPS |
|---|---|---|
| OS updates and security patches | The provider | You |
| PHP version and extensions | Pick from a list | Install whatever you want, and maintain it |
| Firewall and blocking login attempts | The provider | You |
| Backups | Usually included in the plan | You, with your own tools or the provider’s space |
| Usually included in the plan | A separate decision: a hosted mail service or a mail server you run | |
| SSL certificate renewal | Automatic | You set it up with ACME |
| Monitoring and alerts | The provider | You |
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.

03A migration plan with minutes of downtime
The example: a recipe blog from Doha, matbakh-doha.com, running WordPress on cPanel hosting. The plan has seven steps:
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
# 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-doha.com:443:203.0.113.41 https://matbakh-doha.com/# The current TTL as the resolver sees it (the number after the domain name)dig +noall +answer matbakh-doha.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:
# 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
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:
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-doha.com -d www.matbakh-doha.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.
# 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.




