Skip to main content
    VPS

    How Many Websites Can I Host on a VPS? Do the Math

    September 13, 2026
    21 min read
    How Many Websites Can I Host on a VPS? Do the Math

    There is no fixed number, and anyone who gives you one is guessing. The honest answer to how many websites can I host on a VPS is that a 4 GB machine might run forty small brochure sites without breaking a sweat, or fall over with two. The difference has almost nothing to do with how many sites you installed.

    What actually sets the limit is peak concurrent uncached requests. Every site you add contributes some number of requests per second that must be rendered by PHP rather than served from cache. Add those up, multiply by how long each one takes, and you get the number of PHP workers you need running at the same instant. That number, checked against your CPU and your memory budget, is your capacity. Site count is just a proxy people use because it is easier to say.

    This guide gives you the arithmetic, the commands to measure your own numbers instead of borrowing someone else's, a plan-by-plan table with the assumptions written out next to every figure, and an ordered list of what actually fails when you push too hard.

    Key Takeaways

    • Capacity is a function of concurrency and cache hit rate, not site count. Ten cached brochure sites can be lighter than one WooCommerce store.
    • The formula that matters is concurrency equals request rate multiplied by request duration. Everything else is bookkeeping.
    • Most small sites need a fraction of one PHP worker at peak. A site doing 120,000 pageviews a month averages roughly 0.05 requests per second.
    • RAM is the number providers advertise, but single-thread CPU and disk latency usually saturate first. Extra RAM never makes one request faster.
    • Failures arrive in a predictable order: PHP-FPM worker exhaustion, then database connection limits, then swap thrashing, then the kernel OOM killer.
    • Multiple sites on one box need one system user and one PHP-FPM pool per site, or a single compromised plugin hands over every other site's database credentials.

    Why "How Many Websites" Is the Wrong Unit

    A website at rest costs you disk space and nothing else. It does not consume CPU. It does not hold memory. A WordPress install sitting untouched on your server for a month is a directory of files and a few tables. You could put five hundred of them on a Mega plan and the load average would stay at zero.

    Cost appears only when a request arrives. So the real unit is requests per second that reach PHP, and the multiplier that converts pageviews into that number is your cache hit rate. A site with full-page caching and a 95 percent hit rate sends one request in twenty to PHP. The other nineteen are served by nginx from memory or disk in a couple of milliseconds and are, for capacity purposes, nearly free.

    This is why the forum answers vary so wildly. Someone running twenty static portfolio sites and someone running two membership sites are describing genuinely different machines, and both are telling the truth about their own experience. Neither number transfers to you.

    The other reason site count misleads: workloads are not additive in a friendly way. Twenty sites that each need 0.1 workers at peak do not need two workers. They need enough headroom that when one of them gets crawled aggressively at 3am while another is running a plugin update, the other eighteen do not time out. Capacity planning is about the tail, not the average.

    VPS Capacity Planning: The Arithmetic That Actually Works

    Here is the method. It takes about twenty minutes on a live server and it replaces every rule of thumb you will read elsewhere.

    Step 1: Measure what one PHP worker actually costs

    Do not use the number from a blog post. Measure yours, because it depends entirely on your plugin stack.

    ps --no-headers -o rss -C php-fpm8.3 | awk '{ s += $1; n++ } END { print s/n/1024, "MB average RSS" }'

    That gives you resident set size, which is the figure most guides use. It is also slightly wrong, because RSS counts shared memory once per process. OPcache, for example, is a shared segment: every worker reports it, but it exists once. The accurate figure is proportional set size, which divides shared pages across the processes using them:

    awk '/^Pss/ { s += $2 } END { print s/1024, "MB PSS" }' /proc/PID/smaps_rollup

    Run that against a handful of busy worker PIDs and take the average. The PSS number is the true marginal cost of adding one more worker, and on a well-tuned PHP 8.3 stack it is meaningfully lower than RSS. Using RSS is the conservative choice, which is fine, but know that you are leaving capacity on the table.

    For reference on the ceiling rather than the typical: PHP's default memory_limit is 128M, and WordPress raises its own WP_MEMORY_LIMIT to 40 MB for single sites and 64 MB for multisite. Those are per-request caps, not allocations. A worker that handles a cached-miss homepage render does not touch its limit.

    Step 2: Measure how long an uncached request takes

    Add upstream timing to your nginx log format. In http context, append rt=$request_time urt=$upstream_response_time to the log format string, reload nginx, then let it run for a day.

    You want two numbers: the median uncached response time and the 95th percentile. The median tells you what capacity you have in normal conditions. The p95 tells you how deep your queue gets when something goes wrong. If your p95 is five times your median, you have a slow query or an external API call hiding in a plugin, and that is a bigger capacity problem than any hardware choice.

    Also enable the PHP-FPM slow log in your pool config with slowlog and request_slowlog_timeout = 5s. Anything that appears there is stealing a worker for five seconds, which on a small box is the same as taking a chunk of your capacity offline.

    Step 3: Convert traffic into peak concurrency

    A month has 2,592,000 seconds (30 days times 86,400). So:

    • Average requests per second equals monthly pageviews divided by 2,592,000.
    • Peak requests per second equals average multiplied by your peak factor.

    Do not guess the peak factor if you can avoid it. Pull the busiest single hour from the last 30 days of your access log and divide by 3,600:

    awk '{ print $4 }' /var/log/nginx/access.log | cut -d: -f1-2 | sort | uniq -c | sort -rn | head -5

    If you have to guess, a site with an audience concentrated in one timezone typically peaks somewhere between five and ten times its 24-hour average, because nobody is reading it at 4am. A globally distributed audience flattens that considerably. State whichever assumption you use and revisit it once you have log data.

    One warning that catches everyone: your analytics tool undercounts server load. JavaScript analytics miss crawlers, uptime monitors, RSS readers, security scanners and wp-cron hits, and on a small site those can rival human traffic. The access log is the source of truth for capacity. Analytics is the source of truth for humans.

    Step 4: Apply the cache hit rate

    Only the misses cost you. Requests reaching PHP equals peak requests per second multiplied by (1 minus your cache hit rate).

    Measure the hit rate rather than assuming it. If you use nginx FastCGI caching, add $upstream_cache_status to your log format and count:

    awk '{ print $NF }' /var/log/nginx/access.log | sort | uniq -c | sort -rn

    You will see HIT, MISS, BYPASS and EXPIRED. A well-configured brochure or blog site sits high in the nineties. A WooCommerce store is a different animal: cart, checkout, my-account and any page with a session cookie must bypass the cache entirely, so its effective hit rate on the pages that matter can be close to zero.

    Step 5: Take the lower of the two ceilings

    You now have two independent limits.

    The memory ceiling. Available RAM for PHP divided by per-worker memory equals your maximum pm.max_children across all pools combined.

    The CPU ceiling. vCPU count multiplied by 1,000, divided by CPU milliseconds consumed per request, equals your maximum sustainable uncached requests per second. Note that this uses CPU time, not wall-clock time. A request that waits 300 ms on a database query and burns 80 ms of CPU costs you 80 ms of your budget, not 380.

    Your real capacity is whichever is lower, and on almost every VPS under 16 GB it is the CPU ceiling. That fact is the single most useful thing in this article.

    A Worked Example on a 2 vCPU / 4 GB VPS

    Let us size a Starter plan (2 vCPU, 4 GB RAM, 75 GB NVMe) running nginx, PHP-FPM 8.3 and MariaDB, with all numbers stated as assumptions so you can substitute your own.

    Memory budget. Start from 4,096 MB and subtract:

    • Operating system, systemd, sshd, monitoring agent: about 400 MB
    • MariaDB with a 512 MB InnoDB buffer pool plus per-thread buffers and overhead: about 900 MB
    • nginx worker processes: about 50 MB
    • Redis object cache with a modest maxmemory: about 200 MB
    • Headroom for page cache, backups, package updates and the occasional import: about 600 MB

    That leaves roughly 1,946 MB for PHP-FPM. If you measured 55 MB per worker, the memory ceiling is 1,946 divided by 55, or about 35 workers.

    CPU budget. Suppose you measured that an uncached WordPress page render burns about 120 ms of CPU. Two vCPUs give you 2,000 ms of CPU per second. So 2,000 divided by 120 is about 16 uncached requests per second at 100 percent CPU, which you never want to run at. Call the practical ceiling 11 or 12 requests per second.

    Reconcile them. At 12 requests per second with a 400 ms wall-clock render time, concurrency is 12 times 0.4, which is about 5 workers busy at any instant. You have room for 35 and you will use 5. Setting pm.max_children to 35 on this box does not give you more capacity. It gives the machine permission to accept 35 simultaneous renders onto 2 cores, at which point every request slows down together, wall-clock time balloons, more workers spawn, and you have converted a slow site into a dead one.

    The correct move is to cap pm.max_children near where the CPU saturates plus a modest buffer, somewhere around 12 to 16 here, so the queue forms in nginx where it is cheap rather than in the kernel run queue where it is not. Requests wait a little instead of everything failing at once. This is the opposite of the advice you will find in most tuning guides, which tell you to raise max_children until the warnings stop.

    Now convert to sites. A cached WordPress site doing 120,000 pageviews a month averages 120,000 divided by 2,592,000, or 0.046 requests per second. At a peak factor of 8, that is 0.37 requests per second at its busiest. At a 92 percent cache hit rate, only 0.03 of those reach PHP.

    Divide the 12 requests per second budget by 0.03 and the arithmetic says 400 sites. Obviously you should not do that, and the reasons are the interesting part: disk space, inode count, MariaDB memory across hundreds of schemas, overlapping backup windows, and the fact that one bot storm or one uncached search page on one site can eat the entire budget. Target 25 to 35 percent utilisation of your calculated ceiling and you land at roughly 6 to 10 sites of that size on this plan, which is where the table below comes from.

    Need more power? Move up to a VPS

    Dedicated resources, full root access, and NVMe storage. From $3.49/mo, ready in minutes.

    Compare VPS plans

    How Many Websites Can I Host on a VPS at Each Plan Size?

    These figures are derived from the method above, not measured on a test rig. Treat them as a starting point to check your own arithmetic against. The assumptions are stated below the table and they matter more than the numbers.

    Plan Specs Brochure / static sites Cached WordPress sites WooCommerce stores What runs out first
    Nano 1 vCPU / 1 GB / 25 GB 3 - 5 1 Not recommended RAM. MariaDB plus PHP on 1 GB needs swap and careful tuning.
    Micro 1 vCPU / 2 GB / 50 GB 8 - 12 2 - 4 1 very small The single vCPU. One slow render blocks the next.
    Starter 2 vCPU / 4 GB / 75 GB 15 - 25 6 - 10 1 - 2 CPU under uncached load, or RAM if pools are left at defaults.
    Basic 3 vCPU / 6 GB / 100 GB 25 - 35 10 - 15 2 - 3 CPU, then disk latency during overlapping backups.
    Advanced 4 vCPU / 8 GB / 125 GB 35 - 50 15 - 20 3 - 4 Disk IOPS and the nightly backup window.
    Pro 6 vCPU / 12 GB / 150 GB 50 - 75 20 - 30 5 - 6 Disk space and inodes once sites carry real media libraries.
    Elite 8 vCPU / 16 GB / 175 GB 75 - 100 30 - 40 6 - 8 Disk space, and the operational load of patching that many stacks.
    Mega 10 vCPU / 24 GB / 200 GB 100 - 150 40 - 60 8 - 12 Disk space almost always. 200 GB across 60 sites is 3.3 GB each.

    Assumptions behind every number above:

    • Brochure site means static HTML or a WordPress site with full-page caching, under roughly 5,000 pageviews a month, no logged-in users, no on-site search.
    • Cached WordPress site means full-page caching with a hit rate in the low nineties, up to roughly 25,000 pageviews a month, a modest plugin count, PHP 8.3 with OPcache enabled.
    • WooCommerce store means a catalogue under about 1,000 products with modest order volume, where cart, checkout and account pages bypass cache entirely. These are the expensive tenants.
    • All figures assume nginx, PHP-FPM and MariaDB on the same machine, one PHP-FPM pool per site with pm = ondemand for the quiet ones, and no other workload competing (no CI runners, no Docker image builds, no media transcoding).
    • They assume you configured per-pool limits. Ship the distro defaults across ten pools and you will get materially worse results.
    • Any single site that grows past the others invalidates the row. Capacity is set by the loudest tenant, not the average one.

    Full specs and pricing for each tier are on the VPS hosting page, and if you are still deciding between tiers there is a longer breakdown of what each price band buys in our guide to cheap VPS hosting in 2026.

    Why RAM Is Usually the Wrong Thing to Optimise

    RAM is the number every host puts on the pricing page, because it is the easiest spec to compare and the cheapest to advertise. It is also, for most web workloads, the third most important thing on the box.

    Here is the uncomfortable truth: adding RAM never makes a single request faster. If your homepage takes 800 ms to render, it takes 800 ms on 1 GB and 800 ms on 64 GB. Memory only lets more requests run at the same time. If you are not hitting your concurrency ceiling, buying more of it changes nothing you can perceive.

    What binds first, in practice:

    Single-thread CPU performance

    A PHP request runs on one thread from start to finish. There is no parallelism inside a page render. That means your time-to-first-byte is governed by how fast one core is, not by how many cores you have. Eight slow cores will lose a TTFB comparison to two fast ones every single time, and TTFB is what Core Web Vitals and your users actually feel.

    Core count buys you concurrency, which is a different product. You need cores when many people arrive at once. You need clock speed and instructions-per-cycle when one person waits. Devoster VPS instances run on Intel Xeon Gold 6138 hardware, which Intel specifies as 20 cores and 40 threads with a 2.00 GHz base and 3.70 GHz max turbo frequency. The relevant number for your TTFB is the turbo clock and the microarchitecture, not the 20.

    Disk latency and IOPS

    NVMe is fast, but on a virtualised host you are sharing a device. The metric that matters is not throughput in MB/s, it is latency under concurrency, and the tool is iostat -xz 1. Watch two columns: %util and await. On NVMe, service times should be well under a millisecond in normal operation. If await is consistently sitting in the tens of milliseconds, something is queueing and no amount of RAM will help.

    What consumes IOPS on a multi-site box, roughly in order: MariaDB writes (binary log, InnoDB redo log, doublewrite buffer), file-based page caches being written and purged, PHP session files, log writes across every vhost, and backups. Backups are the one that catches people. Ten sites each running a nightly backup plugin at 03:00 will produce an IO storm that makes every site slow for twenty minutes, and it will look like a mystery because nobody is awake to see it.

    Where RAM genuinely does matter

    To be fair to RAM: it matters enormously for the InnoDB buffer pool. If your database working set fits in the buffer pool, reads come from memory. If it does not, they come from disk, and you have converted a memory problem into an IOPS problem. It also matters for OPcache, for a Redis object cache, and for the simple fact that swapping is catastrophic. Just size it from the calculation, not from anxiety.

    What Actually Breaks First When You Overload a VPS

    Overload does not arrive as a single event. It arrives as a sequence, and each stage has a distinct signature. Learning to recognise them turns a two-hour outage into a five-minute fix.

    1. PHP-FPM worker exhaustion

    The first thing to break, nearly always. All workers are busy, new requests queue in the listen backlog, and once that fills nginx returns 502 Bad Gateway or, if the request eventually times out, 504 Gateway Timeout.

    The signature is unmistakable in the PHP-FPM log. You will see either server reached pm.max_children setting (N), consider raising it or listening queue is not empty, #N requests are waiting to be served, consider raising pm.max_children setting (N). Both come straight from the PHP-FPM process manager.

    Resist the advice in the message. Raising max_children is right only when you have spare CPU and RAM. If you are already CPU-bound, raising it makes the outage worse by admitting more work to a machine that cannot do it. Enable pm.status_path in the pool, poll it, and watch listen queue and max children reached. If the queue is growing while CPU sits at 40 percent, raise the limit. If CPU is at 95 percent, fix the slow code or buy more cores.

    2. Database connection limits

    Next in line. Each active PHP worker typically holds one database connection, so the sum of pm.max_children across all your pools sets your peak connection demand. MySQL 8.0 ships with max_connections at 151 and returns error 1040, "Too many connections", when you exceed it. MySQL reserves one extra connection above the limit for accounts holding CONNECTION_ADMIN or SUPER, which is how you can still get in to run SHOW PROCESSLIST during the incident.

    Check your actual high-water mark rather than waiting for the error:

    SHOW GLOBAL STATUS LIKE 'Max_used_connections';

    Two traps here. First, if the sum of your pools exceeds max_connections, a traffic spike on one site can lock every other site out of the database. Second, do not fix that by setting max_connections to 1000. Each connection allocates its own sort, join and read buffers on demand, so a high limit on a small box is a direct route to the OOM killer. Fix the pool sizes instead.

    3. Swap thrashing

    When memory runs short, Linux reclaims pages before it kills anything, and reclaim under pressure means paging to disk. The classic signature is vmstat 1 showing continuous non-zero values in the si and so columns, load average climbing while CPU utilisation stays low, and a high %wa figure in top.

    On modern kernels there is a better signal. Read /proc/pressure/memory and look at the some avg10 value: it tells you the percentage of the last ten seconds in which at least one task stalled waiting for memory. Zero is healthy. Sustained double digits means you are already in trouble and the OOM killer is next.

    A modest swap file is worth having as a shock absorber, especially on Nano and Micro plans. Relying on it as working memory is not.

    4. The OOM killer

    The last resort. When reclaim cannot free enough memory for the kernel to continue operating, it selects a process and terminates it, choosing whichever task it judges most expendable for overall system health. In practice that scoring usually lands on the largest resident process, which on a web server is MariaDB.

    So the visible symptom of a memory overload is rarely "out of memory". It is every site on the box simultaneously showing "Error establishing a database connection", which sends people hunting for a database problem that does not exist.

    Confirm it in one command: dmesg -T | grep -iE "killed process|out of memory" or journalctl -k | grep -i oom. Also make sure MariaDB actually comes back. Add a systemd drop-in with Restart=on-failure and a sensible RestartSec, or your five-minute incident becomes an overnight one.

    5. Disk space and inodes

    Less dramatic, more common than people expect on multi-site boxes. Logs, backups and cached files grow quietly until a write fails, and a full disk breaks MariaDB in confusing ways.

    Check both df -h and df -i. The second one is the trap: a WordPress install with plugins is tens of thousands of small files, and on ext4 the inode count is fixed when the filesystem is created. It is entirely possible to exhaust inodes with 40 percent of your disk free, at which point everything fails with "No space left on device" while df -h insists you are fine.

    How to Host Multiple Websites on One VPS Properly

    The technical capacity is the easy half. The hard half is making sure that hosting site number seven does not put sites one through six at risk.

    One system user per site

    This is the single most important decision, and the one most tutorials skip. If every site runs as www-data, then a single vulnerable plugin on any site gives an attacker read access to every other site's wp-config.php, which means every other site's database credentials.

    Create a dedicated unprivileged user per site, own the docroot with it, and set the docroot to mode 750 so other site users cannot traverse into it. It costs ten minutes per site and it converts a total compromise into a contained one.

    One PHP-FPM pool per site

    Give each site its own pool file, its own socket and its own user:

    • user and group set to that site's system user
    • listen pointing at a per-site Unix socket, with listen.owner set to the nginx user
    • php_admin_value[open_basedir] restricting the pool to its own docroot plus a private temp directory
    • php_admin_value[memory_limit] set per site, so one runaway import cannot claim the whole box
    • php_admin_value[disable_functions] covering exec, passthru, shell_exec, system and proc_open unless a site genuinely needs them

    Choose the process manager per site, not globally. The PHP-FPM configuration manual defines three modes: static keeps a fixed number of children, dynamic scales between spare-server thresholds, and ondemand spawns children only when a request arrives and kills them after pm.process_idle_timeout, which defaults to 10 seconds.

    For a multi-site box this distinction is the whole game. Use ondemand for the quiet sites, and they cost you zero memory while nobody is visiting. Use dynamic or static for the one or two busy sites where the fork latency of ondemand would show up in TTFB. The common failure is setting every pool to dynamic with pm.max_children = 20: ten sites configured that way is a theoretical 200 workers, which at 55 MB each is 11 GB of demand on a 4 GB machine.

    The rule to write on a sticky note: the sum of pm.max_children across every pool, multiplied by your measured per-worker memory, must fit inside your PHP memory budget. Not each pool. The sum.

    Per-site resource limits

    Pool-level pm.max_children and memory_limit give you soft partitioning, which is enough for most people. They are advisory in the sense that a site can still monopolise CPU within its worker allowance.

    If you need hard limits, the honest answer is that PHP-FPM pools cannot give them to you directly, because cgroup limits apply to the whole php-fpm service. To get real enforcement you run a separate PHP-FPM systemd unit per site and apply MemoryMax, CPUQuota and IOWeight to each unit, or you move to containers. That is more moving parts, and for a personal portfolio of sites it is over-engineering. For paying clients on the same box, it is not.

    Also give each site its own database and its own database user with grants scoped to that schema only. A shared database user across sites undoes everything else you just did.

    Rate limiting is capacity management

    A surprising share of "my VPS is overloaded" incidents are one badly behaved crawler or a login brute-force against wp-login.php. Both hit PHP, both bypass your page cache, and both can consume your entire worker budget with no human traffic involved.

    An nginx limit_req zone on login and XML-RPC endpoints, plus fail2ban, is cheaper than the next plan tier and fixes the actual problem.

    Backups, Blast Radius and the Agency Problem

    Consolidating sites onto one VPS consolidates their failure modes too. This is a business decision dressed as a technical one.

    Backups scale linearly, and they collide. Ten sites means ten times the backup volume and ten times the restore time. If every site runs its own backup plugin on its own schedule, they will overlap, and the IO contention will be blamed on the host. Stagger them, or better, back up at the server level with one process and keep copies off the machine. A backup stored on the same VPS is not a backup, it is a second copy waiting to be deleted alongside the first.

    One mistake reaches everything. A bad kernel upgrade, a full disk, a mistyped rm, an expired payment method: on separate hosting accounts these take down one site. On a consolidated VPS they take down all of them, on the same afternoon, and you will be explaining it to every client at once.

    One IP address is shared reputation. Every site on the box sends mail from the same IP. One compromised contact form that starts relaying spam gets that IP listed, and suddenly every site's password reset emails land in spam. Send transactional mail through a dedicated provider with proper SPF, DKIM and DMARC rather than from the VPS, and this stops being your problem.

    Restore testing is not optional at this scale. Pick one site a quarter and actually restore it somewhere else. An untested backup across ten sites is ten untested backups.

    When One VPS Is the Wrong Answer

    We sell VPS hosting, so take this section as intended: there are several situations where consolidating onto one box is a mistake, and one where a VPS is the wrong product entirely.

    • You do not want to run system updates. A VPS hands you an unmanaged Linux box. Patching, firewall rules, TLS renewal and log rotation are now your job across every site on it. If that does not appeal, managed shared hosting will serve you better for less effort, and our comparison of shared hosting versus VPS lays out the trade in detail.
    • One site is 80 percent of the load. Give it its own machine. Sizing a box for your busiest tenant means overpaying for the quiet ones, and one traffic event takes everything down with it.
    • Clients with contractual uptime obligations. Shared blast radius is a liability you cannot engineer away with cgroups. Separate VPS instances per significant client, or a reseller arrangement, is the right structure.
    • Traffic is genuinely spiky and unpredictable. A fixed VPS cannot absorb a 50x spike. Put a CDN in front of it, or use a platform that scales horizontally.
    • Your audience is far from the datacentre. Devoster VPS instances are in US-South. If your visitors are all in Europe or the Middle East, physics adds round-trip latency that no amount of tuning removes. A CDN handles static assets, but uncached HTML still makes the trip.

    None of these are edge cases. They are the four or five reasons most consolidation projects get unwound a year later.

    The Answer, Restated

    So, how many websites can you host on a VPS? As many as your peak concurrent uncached request rate allows, which you now know how to calculate: measure your per-worker memory, measure your uncached response time, pull your busiest hour from the access log, apply your real cache hit rate, and take the lower of your CPU and memory ceilings.

    For most people running small cached WordPress sites, that number is a lot higher than they expect, and the practical limits turn out to be disk space, inode count, backup windows and their own patience for patching. For anyone running an uncached application, it is a lot lower, and no plan upgrade substitutes for fixing the slow query.

    Start one tier below where you think you need to be, measure for two weeks with the commands above, and resize with real numbers. Upgrades take a reboot. Guessing takes a year.

    Have questions? Get in touch

    Not sure which plan fits or how crypto billing works for you? We're here to help.

    Contact us

    Frequently Asked Questions

    How many websites can I host on a 2GB VPS?

    Realistically 8 to 12 small brochure sites, or 2 to 4 cached WordPress sites, assuming nginx, PHP-FPM and MariaDB on the same box with one pool per site set to ondemand. The binding constraint on a 2 GB plan with a single vCPU is usually the CPU, not the memory: one slow uncached render blocks the next one.

    How many WordPress sites can one VPS handle?

    It depends almost entirely on cache hit rate. A WordPress site with full-page caching sends roughly one request in twenty to PHP, so dozens can share a modest box. A WooCommerce or membership site bypasses cache on cart, checkout and account pages, so it can consume more capacity than ten cached blogs combined.

    How much RAM do I need for a VPS running several sites?

    Calculate it rather than guessing: operating system overhead, plus your InnoDB buffer pool, plus nginx and any object cache, plus the sum of all PHP-FPM pools multiplied by your measured per-worker memory, plus around 15 percent headroom. For most small multi-site setups that lands between 4 and 8 GB. Extra RAM never makes an individual request faster.

    Is it safe to host client websites on the same VPS?

    Technically yes, with one system user and one PHP-FPM pool per site, separate database users, and open_basedir restrictions. Commercially it is riskier: a full disk, a failed upgrade or a compromised plugin affects every client at once, and you own that conversation. Above a certain client value, separate instances are worth the extra cost.

    Do I need a control panel to host multiple sites on a VPS?

    No. Multiple sites is just multiple nginx server blocks, multiple PHP-FPM pools and multiple databases, all configurable by hand. A panel saves time and enforces some isolation defaults, but it also consumes RAM and adds an attack surface. On a 1 or 2 GB plan, a panel can easily cost you a quarter of your usable memory.

    What happens when a VPS runs out of memory?

    Linux reclaims pages first, which means swapping to disk, so the machine gets slow before it gets broken. If reclaim cannot keep up, the kernel OOM killer terminates a process, usually the largest one, which on a web server is typically the database. The symptom you see is every site showing a database connection error at the same moment.

    Ready to Experience Devoster?

    Join thousands of satisfied customers with transparent pricing and lightning-fast hosting.

    We value your privacy

    We use essential cookies to make our site work, and optional analytics cookies to understand how you use Devoster and improve our services. You can accept all cookies, or adjust your preferences.

    Read more in our Cookie Policy and Privacy Policy. You can change your choices at any time.