Hardware & Performance·8 min read·

Choosing the Right Instance Size for Your Application Workload

A practical method for sizing a VPS by measuring memory, CPU, and concurrent connections under real traffic, instead of guessing from the dashboard.

NB

Netbay Infrastructure Team

Netbay Engineering

On this page

Instance sizing fails when it is a guess made once at creation and never revisited. The right size derives from the workload: how many concurrent connections, how much resident memory per request, how bursty the CPU demand is. Measure those three numbers under real traffic and the correct plan falls out of the arithmetic, no intuition required.

Work out the three demand numbers

Three numbers drive almost every VPS size: peak concurrent connections, resident memory per worker, and peak CPU demand. They are independent, and each maps to a resource.

  • **Peak concurrency** sets how many processes or threads must exist at once.
  • **Resident memory per worker** times peak concurrency is the minimum anonymous memory.
  • **Peak CPU demand** tells you how many cores stay genuinely busy.

Get them from the application and the OS, not from the marketing page. If you cannot observe yet, instrument on a small instance and scale up from data.

Measure memory per connection

For a stateless web tier, the dominant term is memory per concurrent request. Sample your process tree at peak and divide resident memory by active workers:

bash
ps -eo rss,comm --sort=-rss | head -n 20
# total anonymous memory for your app processes
pgrep -f node | xargs -I{} pmap -x {} | tail -n 1

Sum the resident set sizes of your worker processes at peak. If three workers each hold 220 MB, plan for roughly 660 MB of anonymous memory just for the app. Add the OS, the datastore, and cache, and you have the floor for RAM.

Size to the concurrency curve

Most frameworks configure a worker cap, and that cap is a sizing lever, not a fixed constant. Nginx has worker_connections, PHP-FPM has pm.max_children, uwsgi its threads. The number that matters is max_children times per-child memory, because that is the worst case.

ini
# php-fpm pool
pm = dynamic
pm.max_children = 16
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.max_requests = 500

Sixteen children times 40 MB each is 640 MB at worst case. If you only bought 512 MB of RAM, the pool will thrash before the OOM killer ever gets involved. That arithmetic is the whole sizing exercise for a PHP or Python tier.

Verify the headroom with a load test

Arithmetic is a hypothesis; a load test confirms it. Push the instance to the forecast peak with a tool and watch memory, CPU, and error rate under that exact concurrency. The gap between the plan and the peak is where oversizing hides.

bash
# hammer the endpoint at forecast peak concurrency
ab -n 5000 -c 150 http://127.0.0.1:8080/ 2>&1 |   grep -E '(Requests per second|Failed|Total:|Percentage of the requests)'
# in a second terminal watch the floor
free -m
mpstat -P ALL 1 3

Read the numbers together. If memory barely dips into swap and CPU parks below half, the plan has headroom and traffic can grow. If memory climbs to the ceiling or error count reads non-zero at the forecast peak, the plan is too small regardless of how idle it looks on the daily average.

Leave a margin for traffic you cannot predict

No forecast is exact. A marketing post, a news mention, or a seasonal spike doubles traffic overnight. Plan so the worst measured case plus two standard deviations of your own week sits inside the box. The margin is not waste; it is the difference between a blip and an incident. You can always scale down when the peak passes, but you cannot serve a surge from a plan you never had.

The burst budget on CPU

Web traffic is bursty. A four-core plan that runs at 5 percent average can still run out of cores at 09:15 when traffic triples. Size CPU to the worst ten minutes of the day, not the daily average. Watch the utilisation column in mpstat across a slow period and record the sustained peak, then leave headroom so the burst does not land you at 100 percent parked.

sizing formula three numbers drive the plan concurrency peak active requests mem / worker resident set size peak CPU demand worst ten minutes RAM = concurrency x mem cores = peak demand + headroom revisit monthly choose smallest plan above the floor then scale up from real data

Revisit, because traffic changes

A size decided once is almost always wrong a month later. Set a calendar reminder to re-measure concurrency and memory after any traffic jump or feature release. The cost of a wrong plan is two-sided: oversizing pays for idle cores, undersizing pays in latency and error spikes at peak.

Takeaway

Pick the smallest plan whose arithmetic satisfies your measured worst case, then verify under real load and resize when the data says to. You can change instance size on Netbay on demand from the dashboard or the API at netbayhosts.in any time traffic shifts.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance