How much RAM does a WordPress server need?
Add up four things: the system, the database, PHP, and room to spare. Then measure, because your plugins decide the PHP part.
A single WordPress site with a page cache runs well on 1 GB of memory. A WooCommerce shop, a busy membership site, or several sites on one server need 2 GB or more. Your plugins decide the rest, so measure before you pick a size.
The four parts of the bill
Memory on a WordPress server goes to four places.
- The system. Linux, SSH and the small services around them: about 200 to 300 MB.
- The database. MySQL or MariaDB often uses 150 to 500 MB on a small site. MySQL 8 sits at the high end, even when idle.
- PHP. Each PHP worker handles one visit at a time and loads WordPress and your plugins for it. That is usually 40 to 120 MB per worker.
- Room to spare. Backups, updates and imports need memory too. Keep a few hundred megabytes free on an ordinary day.
So the sum is roughly: system + database + (PHP workers × memory per worker) + room to spare.
Three worked examples
A blog with a page cache, on 1 GB. System 250 MB, database 300 MB, four PHP workers at 50 MB. That is 750 MB, leaving 250 MB, because the cache serves most visits without PHP.
A WooCommerce shop, on 2 GB. Carts and checkouts skip the cache. System 250 MB, database 450 MB, eight workers at 100 MB. That is 1.5 GB, leaving 500 MB.
Five small sites, on 2 to 4 GB. Start at 2 GB and move up when memory is short on most days.
These are starting points. One heavy page builder can double the size of a PHP worker.
Measure your own server
The biggest programs by memory, in kilobytes:
ps -eo rss,comm --sort=-rss | head -15
Each PHP worker (the name may carry a version, such as php-fpm8.3):
ps -eo rss,comm | grep php-fpm
Divide by 1024 to get megabytes. Check after the site has had some visits, since a fresh worker is smaller.
How much memory is left:
free -h
Read available, not free: Linux fills spare memory with cache, so free always looks low.
The setting that decides it: pm.max_children
PHP-FPM starts workers up to a limit called pm.max_children. On Ubuntu and Debian it lives in the pool file, for example /etc/php/8.3/fpm/pool.d/www.conf. The packaged default is 5.
That limit decides the PHP part of the bill: ten workers at 100 MB can take 1 GB. Set too high, the server runs out of memory at the busiest moment. Set too low, visitors queue while memory sits unused.
To pick it, take your memory, subtract the system, the database and a few hundred megabytes spare, and divide the rest by the size of one worker. On a 2 GB server with a 450 MB database and 100 MB workers, that gives about eight. Restart PHP-FPM after a change, and watch free -h on the next busy day.
Signs you guessed too low
You guessed too low if available stays at a few hundred megabytes for hours on ordinary days, if the server uses swap even when it is quiet, or if Linux has stopped a program because memory ran out (sudo journalctl -k | grep -i "out of memory"). That last one usually takes down the database: here is why MySQL keeps getting killed, and what to do before you pay for more memory.
Already thinking about a bigger plan? Read when to upgrade your VPS, and when not to.
Or let the server show you
Working this out once is useful. Watching it every day is tedious. PimiPulse watches the memory on your server, and when memory runs short its warning names what is using it, in plain English: “Most of the memory goes to your website (PHP), 4 processes, about 240 MB in total, and your database, about 180 MB.”
It only reads what the server reports. Changing a setting stays your call.
This post is about PimiPulse, part of Pimi.