WordPress has one amazing feature. It performs just as well on a small blog with a few hundred visitors as it does on an online store with thousands of orders. But as is often the case, almost any project eventually runs into certain limitations, and very often these are hosting limitations - specifically, those of shared hosting.
So you’ve launched your online store, and everything is working perfectly. But after a while, your site starts to slow down a bit during peak hours; later, backups take half an hour to complete; plugins start conflicting with the provider’s limits; and the hosting support team feeds you boilerplate responses about exceeding CPU limits. Problems start piling up and snowballing.
At this point, many start thinking about how to solve all these problems - preferably in one fell swoop. Engineers start looking into moving to VPS hosting, and after reading a couple of articles, it feels like migrating WordPress requires a Kubernetes cluster, a Docker Registry, Helm charts, and a dedicated DevOps engineer with a nervous tic. YouTube channels especially love to scare people with this.
But there’s good news! In practice, most WordPress projects simply don’t need this, and a standard VPS server with Nginx, PHP-FPM, and MariaDB, which is capable of handling the vast majority of real-world sites, such as corporate websites, WooCommerce stores, LMS platforms, blogs, media sites, and services with tens of thousands of visitors per day. And you won’t need any containers, orchestration, or unnecessary complexity.
So in this article, let’s figure out how to properly migrate a WordPress site to a VPS manually, what to prepare in advance, what mistakes are most commonly made, and why a classic VPS remains one of the best options for WordPress in 2026 and will continue to be so for the long term.
Why VPS is better than shared hosting for WordPress and how to know when it’s time to move
Of course, shared hosting still has its place, as it works well for small and predictable sites, one-page sites, and business card sites. But WordPress rarely stays within the limits that allow it to be hosted on shared hosting.
Over time, you add WooCommerce, various SEO plugins, CRM integrations, caching, analytics, external APIs, and dozens of background tasks to your site. And since your site is currently hosted on a server with hundreds of other similar sites, it ends up sharing server resources with hundreds of other projects. In this scenario, any traffic spikes from neighboring sites directly impact the performance of your specific project.
With a VPS, the situation is completely different. You get an isolated environment and full control over your server, so you can choose the PHP version you need, configure OPcache, Redis, cron jobs, MariaDB settings, Nginx, and backups. And most importantly - neighbors will no longer be able to slow down or even bring down your project.
This is especially noticeable in modern WordPress projects, which have long since ceased to be mere static blogs. Today, WordPress powers all kinds of projects, from fairly simple online stores to full-fledged SaaS projects and B2B portals.
Usually, the need to switch to a VPS becomes apparent through very specific symptoms, which we’ve tried to summarize in this simple table.
| Symptom | What usually happens |
|---|---|
| Slow WordPress admin panel | PHP and MySQL hit shared hosting limits |
| 502/504 errors | The server cannot handle the load |
| WooCommerce becomes slow | Not enough CPU and RAM |
| High TTFB | Overloaded hosting server |
| Constant CPU limit warnings | The site started consuming more resources |
| Backup errors | Not enough disk space or inode limits |
| Cannot install Redis/Object Cache | The provider restricts the environment |
| The site slows down in the evening | The shared server is overloaded by neighboring websites |
WooCommerce stores outgrow shared hosting particularly quickly. Even a relatively small online store with a few thousand products can create a load that standard shared hosting can no longer handle while remaining stable.
In short, if you see and feel that your project has outgrown shared hosting, then start preparing for the move and the move itself.
Choosing and preparing a VPS
The actual migration of WordPress to a VPS usually takes less time than preparing for it. The main goal here is to avoid data loss and prolonged site downtime. Therefore, you need to prepare thoroughly before moving, which will save you a lot of time and stress in the future.
So, before you begin, it’s advisable to have the following ready:
- A VPS running Ubuntu 22.04 or Ubuntu 24.04;
- a domain name (which you probably already have);
- SSH access to the server and root privileges;
- a backup of your WordPress files;
- a MySQL or MariaDB database dump;
- access to the domain’s DNS records (usually in your domain registrar’s control panel).
For WordPress, the classic LEMP stack - which includes Linux, Nginx, MariaDB, and PHP-FPM - is usually sufficient.
Apache is also suitable as a web server, but in 2026, Nginx is increasingly becoming the standard for WordPress VPS due to its significantly lower memory consumption and good stability under high load.
Once you’ve set up your server, the first thing you should do is - of course… no, not celebrate with a beer, but update the system. This is done with these simple commands:
apt update && apt upgrade -y
Next, you need to install the basic set of packages required for operation:
apt install nginx mariadb-server php-fpm php-mysql php-cli php-curl php-xml php-mbstring php-zip unzip curl wget -y
The PHP version depends on the project itself. Some older WordPress sites still run on PHP 7.4, but for new installations, it’s better to aim for PHP 8.2 or PHP 8.3.
A few words about selecting server specifications. When choosing a VPS, it’s important to consider not only the amount of CPU included in the plan but also the type of project itself. After all, WordPress with WooCommerce, page builders, and dozens of plugins starts consuming resources much faster than it seems. Therefore, you should aim for specifications similar to those listed in the table below.
| Project Type | CPU | RAM | Disk |
|---|---|---|---|
| Blog or corporate website | 1–2 vCPU | 2 GB | 20–30 GB SSD or NVMe |
| WooCommerce store | 2–4 vCPU | 4–8 GB | NVMe |
| LMS or portal | 4+ vCPU | 8+ GB | NVMe |
| Media project | 4+ vCPU | 8–16 GB | NVMe |
Please note that this table is not a standard and is intended only as a rough guide. A major advantage of VPS hosting is its ease of scaling. Therefore, even while your site is live, you can easily adjust your server’s specifications to match the actual load.
Note that for WordPress, the performance of a single CPU core is particularly important - since the processor is responsible for performing all calculations - as is the amount of RAM, since the number of active sessions your site can support depends on the amount of RAM, and, of course, the speed of the disk subsystem.
This is precisely why NVMe drives have practically become the standard for WordPress VPS today. The difference in performance is especially noticeable on WooCommerce, LMS, and sites with a high volume of database queries.
So, our server has been selected, set up, and all necessary packages are installed. Now it’s time to move on to creating the database.
Database Migration
WordPress still stores almost everything in MySQL or MariaDB. Content, settings, plugins, and WooCommerce orders - the database is the heart of the entire system here. That’s why database migration usually becomes the most nerve-wracking stage of the process.
To start, we need to create a separate database and user for WordPress on the VPS. Yes, many people habitually connect to the site via root. And then one vulnerable plugin - and an attacker gains access to absolutely all databases on the server. It’s a story as old as time, but many administrators continue to make the same mistake.
Connect to MariaDB, which we installed earlier:
mysql -u root -p
Let’s create a database and a separate user:
CREATE DATABASE wordpress; CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'strong_password'; GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost'; FLUSH PRIVILEGES; EXIT;
After that, you can dump the database from the old hosting using the command:
mysqldump -u USER -p DATABASE > backup.sql
Transfer the backup file to the new server, for example using the scp command, and import the database onto the VPS:
mysql -u wpuser -p wordpress < backup.sql
Of course, you must substitute your own login, password, and database name values if they differ from the examples provided.
Once your site’s database has been successfully transferred to the new server, you can consider half the work done. Now let’s move on to transferring the WordPress files themselves.
Transferring WordPress Files
With the WordPress files themselves, things are usually much simpler than with the database. Although this is exactly where people regularly mess up the file permissions, after which the site starts behaving very strangely.
You can transfer the files however you like: via SCP, rsync, SFTP, or as archives using tar or zip. For a typical site without dozens of gigabytes of data, the simplest option SCP - is usually sufficient.
For example:
scp -r ./wordpress root@SERVER_IP:/var/www/site
This command simply copies the WordPress directory to the new VPS along with all its subfiles.
After the transfer, you almost always need to check the file permissions and ownership. WordPress is very sensitive to this. Sometimes a single directory with incorrect permissions is enough to trigger all sorts of issues. Images won’t load, plugins won’t update, or you’ll see a 403 Forbidden error, or even a blank screen with no errors at all (WordPress’s favorite mode).
So first, assign the file owner:
chown -R www-data:www-data /var/www/site
Here, www-data is the user under which Nginx and PHP-FPM typically run in Ubuntu. The -R flag recursively processes the entire directory.
Then set the permissions for directories:
find /var/www/site -type d -exec chmod 755 {} \;
And separately for files:
find /var/www/site -type f -exec chmod 644 {} \;
This is an old method, but it still works. For most WordPress sites, this is sufficient.
755 for directories means that the owner can modify the contents, while other users can only read and access them. 644 for files gives the owner the right to modify the file, while others can only read it.
It’s worth checking the following directory separately:
wp-content/uploads
This is where problems pop up most often. WordPress needs to save new images, previews, PDF files, and other media content there. But if the permissions for this directory are broken, the admin panel may appear to be fully functional, yet file uploads won’t work.
Also, after copying the files, you should usually double-check wp-config.php. Especially if the database has already been moved to a new server:
define('DB_NAME', 'wordpress');
define('DB_USER', 'wpuser');
define('DB_PASSWORD', 'strong_password');
define('DB_HOST', 'localhost');
The Error establishing a database connection error occurs constantly after migration. And almost always the reason is trivial: a typo in the password, an incorrect username, or MariaDB simply isn’t running. For some reason, people tend to suspect “broken WordPress” at first, even though the problem usually lies in a single line of the config.
Configuring Nginx for WordPress
So, the database has been migrated, and the files too. Now the server needs to be told what to do with this WordPress installation, and for this, the web server is configured - in most cases, Nginx.
The base config is usually placed in:
/etc/nginx/sites-available/your_domain.conf
The config itself might look something like this:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/site;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg)$ {
expires 30d;
}
}
After that, the site is activated by creating a link to this config file in the /etc/nginx/sites-enabled/ directory:
ln -s /etc/nginx/sites-available/site /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx
The nginx -t command checks the config before restarting, and it’s best to always run it. A single missing character in the config and Nginx simply won’t start. This is especially fun at night on a production server.
In general, WordPress has a funny quirk, and people often blame the VPS for having weak hardware, even though the problem lies in the web server configuration. For example, incorrect PHP-FPM settings, lack of static caching, or weird timeouts can cause the site to slow down even on a normal server. In this article, we covered the essential WordPress settings for the Nginx configuration in detail.
What else is worth adding to the site’s config
Almost any WordPress site on a VPS gets a small performance boost from a couple of additional settings.
For example, gzip compression, which allows you to efficiently compress site files when serving them to the client, thereby saving bandwidth and, consequently, time:
gzip on;
gzip_types text/css application/javascript application/json;
Limiting the size of uploaded files so your site doesn’t get overwhelmed by a bunch of large files:
client_max_body_size 128M;
Blocking access to wp-config.php:
location = /wp-config.php {
deny all;
}
And the simplest way to limit requests to wp-login.php:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
These may seem like a couple of simple instructions, but trust me, they will definitely not be useless and will save you time, effort, and stress in the event of an attack or simply a surge of visitors.
Once you’ve transferred all the site files and the database, and configured the web server, you can check if the site is up by going to the server’s IP address in your browser: http://{your_server_ip}. But in order to access the site via your domain - and in secure mode - we need to finally point your domain to the new server and configure an SSL certificate for HTTPS.
Domain Redirect and HTTPS Configuration
Usually, to point the domain to the new server’s IP address, you simply need to change the domain’s A record in your domain control panel, specifying the new VPS’s IP. But keep in mind that there is such a thing as a DNS cache, which does not update instantly, and updating the record for your domain across all DNS servers on the network can take anywhere from a few minutes to 24 hours, depending on the settings of each of these DNS servers and your domain’s TTL settings.
That’s why experienced administrators reduce the TTL of the DNS records that will be changed in advance - for example, to 300 seconds - so the switchover is almost imperceptible to users.
Also, before the public switch, it’s helpful to test the site locally, as we mentioned above.
After testing and switching the domain, it is advisable to configure HTTPS immediately, since running a WordPress site without an SSL certificate in 2026 means you are practically guaranteed to encounter:
- browser warnings;
- SEO issues;
- mixed content errors;
- and a loss of user trust.
And the simplest option is free certificates from Let’s Encrypt.
Install Certbot:
apt install certbot python3-certbot-nginx -y
Get the certificate:
certbot --nginx
Certbot will automatically issue an SSL certificate and reconfigure Nginx for HTTPS.
After migration, you should carefully check for mixed content, as it often happens that some images, scripts, or CSS continue to load via HTTP. As a result, the browser begins to block certain site elements, and security errors appear in the console.
Usually, the problem is related to old URLs within the WordPress database or caching plugins that have retained old HTTP links.
What to Do After Migrating WordPress to a VPS
Migrating the site to a VPS is just the beginning. WordPress won’t run at its fastest simply because the site has moved from shared hosting. However, there are far more possibilities after migration. After all, we migrated the site to gain the most important advantage of a VPS: full access to and control over server resources.
Therefore, after migrating the site, you can take a few more steps to speed up your WordPress, making it more stable and secure. Here’s what we recommend.
Enable PHP and Redis caching
After migration, the first steps are usually to enable OPcache and Redis Object Cache.
OPcache reduces the load on the CPU by caching PHP code, while Redis helps reduce the number of database queries. This is particularly noticeable on WooCommerce sites, LMS platforms, and sites with a large number of plugins.
Disable the built-in WP-Cron
By default, WordPress runs background tasks while users are visiting the site. On small projects, this is almost unnoticeable, but on high-traffic sites, this setup starts to create unnecessary load.
On a VPS, people usually disable the built-in WP-Cron and move tasks to the server’s regular system cron.
Set up backups
IMPORTANT! After moving to a VPS, backups become the responsibility of the site owner or administrator - that is, your responsibility!
Therefore, it is highly recommended to set up:
- regular database backups;
- site file backups;
- storage of all backups outside your VPS;
- periodic restoration testing.
There’s an old, well-worn but no less relevant saying that there are two types of administrators: those who don’t make backups and those who ALREADY make backups.
Unfortunately, many only think about backups after the first serious problem arises, and by then it’s usually too late.
Monitor load and memory usage
WordPress can start consuming more resources quite quickly, especially after installing WooCommerce, Elementor, SEO plugins, and various integrations. Therefore, after migration, it’s worth periodically checking:
- RAM usage;
- CPU load;
- database performance;
- disk usage.
This helps you spot issues early on before the site starts to slow down or crash under load.
Ensure server security
After migrating to a dedicated VPS, it’s advisable to perform basic server hardening right away, since security issues on shared hosting were handled by the provider, but now this is your responsibility. Of course, there are downsides to this, but there are even more upsides, because you can configure your system yourself and secure it however you see fit.
Here is a minimum list of tasks we strongly recommend you complete:
- disable root SSH;
- use SSH keys instead of passwords;
- configure UFW;
- install fail2ban;
- restrict access to wp-login.php;
- set up backups;
- update the system;
- connect Cloudflare CDN;
- enable automatic security updates.
You should know that absolutely every server on the network today is constantly scanned by bots. Therefore, as soon as a new public IP appears, attacks begin almost immediately, and you must be prepared for them and repel them. The list provided of simple steps significantly increases your server’s security and narrows the scope of potential attacks.
Common Mistakes When Migrating WordPress to a VPS
The most common mistake is migrating “live,” without a test run, without verifying backups, thinking, “I’ll just quickly move it over tonight”. But often, it’s precisely these kinds of migrations that end up with you searching for an old backup at 2 a.m. - if it even exists. So we’ll say it again: don’t ignore the importance of backups.
The next classic issue is a problem with file permissions after transferring the site’s files. WordPress is quite finicky about permissions, so after the transfer, things like image loading, plugin updates, or caching might suddenly stop working. Sometimes the site just opens to a blank white screen with no error messages at all. The wp-content and uploadsdirectories are particularly prone to breaking.
Various caching plugins also cause a lot of problems. After migration, they continue to store old paths, URLs, or bits of the old server configuration. And even though our WordPress is already running on the new VPS, the cache still thinks the site is on the old hosting. Because of this, the site may:
- get stuck in an endless redirect loop;
- load only partially;
- return a
500 Internal Server Error; - break CSS and JavaScript;
- display old versions of pages.
Sometimes it’s easier to temporarily disable the caching plugin completely than to try to figure out exactly which old setting it’s still pulling from the previous server.
There’s also the issue with PHP, which is especially relevant on older WordPress sites. Some themes and plugins there are still written for the outdated PHP 5.x or PHP 7.0. And on the new server, running PHP 8.2 or 8.3, they suddenly start throwing warnings, deprecation errors, or just crashing without explanation. At this point, the site owner usually says something like: “But it worked on the old hosting”. Of course it worked! Because they hadn’t updated PHP there in six years!
And one more thing people constantly forget after the move is email notifications.
WordPress stops sending emails, such as order notifications, contact form submissions, or password reset emails. The reason may simply be that SMTP isn’t configured on the VPS. On shared hosting, this is often set up “out of the box,” but on your own VPS, you have to configure these things separately.
How to tell what exactly broke after migration
Most WordPress issues after migration can be diagnosed fairly quickly. So we won’t dwell on this in detail; instead, we’ve put together a small but helpful table showing the likely problem and its possible cause.
| Symptom | Possible cause |
|---|---|
| 502 Bad Gateway | PHP-FPM is not running |
| 403 Forbidden | Incorrect file permissions |
| White screen | PHP fatal error |
| Infinite redirect | HTTPS or URL configuration issues |
| Images are not loading | Errors in wp-content/uploads |
| Database connection error | Incorrect wp-config.php settings |
| Slow website | OPcache or Redis is not configured |
Here are also some useful commands for system diagnostics in case of failures.
Viewing Nginx web server logs:
journalctl -u nginx
Or open the log files directly (default):
tail -50 /var/log/nginx/access.log
tail -50 /var/log/nginx/error.log
Viewing PHP-FPM logs:
tail -f /var/log/php8.2-fpm.log
Checking the status of key services, such as the web server, database, and PHP:
systemctl status nginx
systemctl status mariadb
systemctl status php8.2-fpm
Often, logs are the fastest way to pinpoint a problem, so don’t neglect working with them.
FAQ
Is it possible to migrate WordPress to a VPS without any administration experience?
Yes, especially if it’s a small website. Basic WordPress migration to a VPS has become much easier today thanks to pre-built packages, automatic SSL certificates, and extensive documentation. However, understanding what you’re doing, as well as skills in working with Linux and SSH, still greatly simplify the process.
How long does it take to migrate WordPress to a VPS?
A small website usually takes 1–2 hours to migrate, and most of that time is spent not on the migration itself, but on checking the site, DNS, and configuring the environment after the move.
Which is better for WordPress - Nginx or Apache?
Both options are suitable for WordPress, but Nginx generally uses less memory and handles high traffic better. That’s why it’s increasingly used as the primary web server on VPS.
Is it possible to migrate WordPress without any site downtime?
Yes. Usually, this is done by reducing the TTL of DNS records in advance and testing the site via the hosts file before switching the domain. With a careful migration, users may not even notice the move.
Why might WordPress run slower after migration?
Most often, the problem may be related to incorrect PHP configuration, lack of caching, Redis, or OPcache. Sometimes the cause is outdated plugins, permission errors, or an underpowered VPS.
Is Docker necessary for WordPress on a VPS?
In most cases, no. For a standard WordPress site, Docker only complicates the infrastructure and adds an unnecessary layer of abstraction. The classic Nginx + PHP-FPM + MariaDB stack is usually simpler and easier to maintain.
Which VPS is best for WordPress?
For a small site, 1–2 vCPUs and 2 GB of RAM are usually sufficient. If you’re using WooCommerce, an LMS, or a large number of plugins, it’s better to look for a VPS with NVMe drives and at least 4 GB of RAM right from the start.
Conclusion
So, migrating WordPress to a VPS without all that Docker and Kubernetes stuff isn’t an outdated approach, but a perfectly normal and practical setup that still powers a huge number of real commercial projects.
For most WordPress sites, what matters most isn’t trendy infrastructure, but predictable performance, reliable backups, stable PHP operation, and the ability to manage the server without add-ons or unnecessary complexity. And it is VPS hosting that provides this balance. You get an isolated environment, full access to server configuration, the ability to use Redis, OPcache, system cron, and the ability to manage website performance effectively without the limitations imposed by shared hosting architecture.
At the same time, the classic Nginx + PHP-FPM + MariaDB stack remains simple enough to maintain without a dedicated team of DevOps engineers. Six months down the line, you’ll still be able to open the Nginx config and quickly understand how the server is set up. And in real-world operation, that’s often more important than any trendy technology.
Of course, it’s important not to view a VPS as a magic solution to all your problems. After the migration, WordPress will still require your attention: backups, updates, load monitoring, and basic security. But in return, you get much more stability, flexibility, and opportunities for your project to grow.
That is precisely why most WordPress projects eventually switch to a VPS, simply because shared hosting can no longer handle the tasks for which WordPress is actually used today.