Sizing a Game Server: Where CPU, RAM, and NVMe Actually Run Out at 50, 100, and 200 Players

A 200-slot Battlefield or Rust server will exhaust a 4.5 GHz core before it exhausts 32 GB of RAM — usually somewhere between 130 and 170 connected players, and the symptom is a tick rate that slides from 60 to 34 without a single error in the log. That ordering is predictable. It is not the ordering most spec sheets assume.

This breakdown treats the server as four budgets — single-thread CPU time, resident memory, storage queue depth, and uplink capacity — and shows which one closes first as player count climbs. The numbers below assume a modern dedicated box in the 3.8–4.5 GHz class, 64 GB DDR4/DDR5 ECC, and a PCIe 4.0 NVMe device.

Why One Core Closes Before Anything Else

A game server is a fixed-timestep loop. At 60 Hz the server has 16.6 ms per tick; at 30 Hz, 33.3 ms. The loop runs on one core: entity movement, collision, physics, AI budgets, and the replication pass that decides what each client is told. Adding cores does not split that loop. It only gives you more room to run ancillary work — chunk generation, anti-cheat scans, database writes — on separate threads.

Entity replication scales roughly linearly with connected players, and it is the most expensive part of the tick. A rough working figure for a source-engine title is 0.06–0.12 ms of tick budget per player once you include per-client visibility filtering. At 0.08 ms, 150 players consume 12 ms of a 16.6 ms budget before AI or physics runs. That is the cliff: not a crash, just overruns that the client renders as rubber-banding.

Virtualization makes this worse in a way the panel never shows. CPU steal and memory ballooning both land on whichever core is busiest. If the plan is shared or oversubscribed, the tick spikes are your neighbour’s fault, not the game’s. Machines with committed cores and no ballooning are the baseline for anything above 64 slots — the same argument that makes dedicated hardware with disclosed clocks and committed cores the usual answer once a VPS stops holding 60 Hz.

CPU Selection: Clock, Cache, and the Boost Ceiling

Rank in this order: single-core boost that holds, L3 cache per core, then core count. A part that advertises 4.7 GHz but settles to 3.1 GHz all-core after ten minutes of AVX load is a 3.1 GHz part for your purposes. Ask for sustained all-core frequency under load, not the turbo number on the marketing page.

Cache matters more than usual here. Ryzen 7000 and Xeon Sapphire Rapids both carry large L3 slices, and the replication pass walks the same entity tables every tick. Where L3 per core falls below roughly 2 MB, you see measurable tick inflation at high player counts even when clocks match.

Player countTick targetBudget per tickReplication costHeadroom left
5060 Hz16.6 ms~4 ms~12 ms
10060 Hz16.6 ms~8 ms~8 ms
15060 Hz16.6 ms~12 ms~4 ms
20030 Hz33.3 ms~16 ms~17 ms

The last row is the honest reason some large-capacity servers run 30 Hz. Dropping to 30 Hz does not reduce the work, it doubles the deadline. Shooters feel that drop; survival games usually do not.

RAM: Size From the World, Not the Slots

Player count sets CPU load. World size and entity density set memory. A vanilla Minecraft world holds roughly 1.5–3 GB resident; a 200-mod pack lands between 8 and 16 GB once chunk caches fill. Rust peaks near 12–16 GB for a full 200-player wipe cycle. ARK with cluster transfers is the outlier, regularly crossing 20 GB.

Budget for the JVM or runtime overhead on top — on a heap-allocated server, an 8 GB heap can mean 11–12 GB resident because of off-heap structures, JIT code cache, and direct buffers. Leaving 8 GB of the physical box free is the practical rule; swap should be off entirely. A server that swaps its world state has already lost, because the page fault lands inside the tick loop.

NVMe: IOPS and Queue Depth Beat Throughput

Sequential numbers are marketing. What matters is random 4K write latency at queue depth 1, because world saves and log flushes are synchronous from the server process’s point of view. A SATA SSD sits around 40–60 µs at QD1; a decent NVMe device sits at 15–25 µs. On a save-heavy lobby that difference shows up as a 200–400 ms stall every autosave.

Consumer QLC drives are the trap. Once the SLC cache fills — often after 30–60 GB of sustained writes, which a log-heavy modded server can reach in an evening — write latency climbs by an order of magnitude. Ask for TLC or enterprise-grade endurance, and check the TBW rating against your daily write volume.

Network: The Budget Nobody Checks

A 100-slot shooter at 60 Hz with 30 KB/s of upstream replication per client needs about 3 MB/s, or 24 Mbit/s. That sounds trivial against a 1 Gbit/s port, and it usually is — until a DDoS mitigation layer or an oversubscribed ToR switch eats the headroom. Port size is not the metric; sustained per-connection throughput and packet loss under load are. That is why port speed alone rarely decides which uplink and port commitment is worth paying for.

Voice chat changes the arithmetic. Add 40 kbit/s per speaker on top of replication and a 100-slot server with 30 concurrent talkers needs another 1.2 Mbit/s upstream, plus a jitter buffer that absorbs 200 ms of variance without dropping frames.

A Sizing Table You Can Hand to a Provider

TargetSustained clockCoresRAMStorageUplink
50 players3.6 GHz+416 GBNVMe TLC 500 GB100 Mbit/s
100 players4.0 GHz+632 GBNVMe TLC 1 TB250 Mbit/s
200 players4.3 GHz+864 GBNVMe TLC 2 TB500 Mbit/s

What to Measure After the First Week

Track three things: p99 tick duration, resident memory growth per hour, and NVMe write latency at QD1. Tick p99 above 1.5× the median means the core is saturating. Memory that climbs without levelling out means a leak, not missing RAM. Write latency that triples after an hour means the drive’s cache is exhausted.

Sizing is not a one-time decision. Mod packs grow, patches add entities, and a server that ran clean at 120 slots in spring can become a 90-slot server by autumn without any hardware change. Re-measure at each wipe, and treat the contract’s hardware disclosure as a document you can audit rather than a promise.

Leave a Reply