On a game panel, CPU is counted in percent of one core: 100% is one core fully busy, 250% is two and a half. Most game servers do the bulk of their work on one main thread, which can use at most one core, so a server reading a steady 100% on a 250% plan is usually not "at 40%" - it is a main thread that has run out of time, and the players feel it as lag. Adding more cores does nothing for that. A reading at the plan's own limit means something different again: the container is being throttled to the share it was given. Telling those two cases apart, and both of them from healthy load, is the whole skill of reading a game server's CPU graph, and it takes about a minute once you know what to look at.
This post is about reading the number. Whether CPU or memory is the thing to buy more of is covered in CPU or RAM: which one is holding your server back, and how a host divides a physical CPU between tenants is in shared CPU and noisy neighbours.
How CPU percentage is counted#
There are two conventions for CPU percentage and they produce wildly different numbers for the same load.
| Convention | Used by | Four busy cores on an 8-core machine |
|---|---|---|
| Percent of one core | top on Linux, Docker, Pterodactyl and most game panels | 400% |
| Percent of the whole machine | Windows Task Manager, many cloud dashboards | 50% |
Game panels use the first. A server with a limit of 250 can show anything from 0% to 250%, and the number is directly "how many cores' worth of work happened in that second". RE:NODE's catalogue states the limit this way too - cpu is percent of one core and a hard limit, so a plan listed at 2.5 vCPU is a ceiling of 250%.
The convention matters because people arriving from a Windows desktop read 100% as "maxed out" and 25% as "plenty of headroom". On a panel, 100% on a 250% plan can be the worst reading on the graph, and 250% may be perfectly fine.
Why most game servers are single-threaded where it counts#
A game server runs a loop. Each pass through it - a tick - reads player input, moves every entity, runs AI, resolves physics and combat, and sends the result back out. The tick has to finish inside a fixed time budget for the game to run at its intended speed.
| Game | Target rate | Budget per tick |
|---|---|---|
| Minecraft | 20 ticks per second | 50 ms |
| Counter-Strike 2 | 64 ticks per second | 15.6 ms |
| Factorio | 60 updates per second | 16.7 ms |
| Terraria | 60 updates per second | 16.7 ms |
| Source games on 66 tick (TF2, Garry's Mod default) | 66 ticks per second | 15 ms |
The work inside a tick is mostly sequential: the zombie's move depends on where the player went, which depends on the input received, which has to be processed in order. Game engines can and do push some work to other threads - chunk generation and lighting in Minecraft, saving, networking, pathfinding in some Unity games, physics in some Unreal titles - but the core simulation lives on one thread. When that thread needs more than its budget, the server falls behind, and no number of idle cores beside it can help.
This is why the specification that matters most for game hosting is single-thread speed - how fast one core finishes one stream of work - and why what tick rate actually means is a useful companion to this post.
Reading the graph: the four shapes#
With the convention and the tick in mind, a CPU graph on a game server falls into one of four shapes.
Low and spiky
Average well under 100%, with spikes when players join, chunks generate or the world saves. This is healthy. A save spike to 150% for two seconds is a background thread doing its job, and it is exactly what extra cores are for.
Flat at about 100% on a plan with more
The server shows a steady 95-105% on a plan that allows 200% or 300%. This is the important one. It almost always means the main thread is using an entire core continuously - it is never idle between ticks because it never finishes a tick early. Players see lag, rubber-banding, or a falling tick rate. The fix is less work per tick or a faster core, not more cores.
There is one innocent version: some engines spin in a busy loop between ticks rather than sleeping, and so show close to a full core even when idle. If the graph sits at 100% with nobody online and the game's own tick metrics are perfect, that is the engine, not a problem.
Flat at the plan's limit
The graph is pinned at exactly the limit - 250% on a 250% plan - and the line is flat on top as if cut with a knife. The container is asking for more CPU than it is allowed and is being throttled. Every thread, including the main one, gets paused for part of each scheduling period. This is the case where more CPU on the plan genuinely helps, or where you have to find what is using all those threads - often world generation, a map renderer or a misbehaving plugin with its own thread pool.
On RE:NODE a server pinned at its limit is slow, not in trouble: CPU is a hard throttle to the share bought, and a server sitting at 100% of its allocation is never suspended for it.
Rising steadily over days
A slow climb that only resets on restart is not a CPU problem in itself. It is usually something accumulating - entities, dropped items, a growing list a plugin iterates every tick - and the CPU curve is the symptom. Find what is growing; game server memory leaks covers the memory side of the same pattern.
Finding the main thread yourself#
The panel graph is a total across all threads. To see whether one thread is pinned, you need per-thread figures. With a shell on your own server or a VDS:
# per-thread view of one process; press H in top to toggle threads$ top -H -p "$(pgrep -f server.jar)"# a one-off list of threads sorted by CPU$ ps -L -o tid,pcpu,comm -p "$(pgrep -f server.jar)" --sort=-pcpu | head# per-thread CPU every second (needs the sysstat package)$ pidstat -t -p "$(pgrep -f server.jar)" 1On Minecraft the main thread is called Server thread; in a Unity game it is usually the process's first thread; in a Source server it is the process itself with very few others beside it. If one thread sits at 95-100% and the rest are low, the server is main-thread bound, regardless of what the total says.
Without a shell, which is the normal case on a panel, the game's own tools are the way in. Minecraft has the best: spark (bundled with recent Paper builds, otherwise a plugin) shows per-thread CPU and a profile of exactly what the main thread was doing. Reading a spark report walks through one.
The game's own numbers are better than the CPU graph#
The CPU graph says how busy the machine is. Players care about whether ticks finish on time, and almost every game reports that directly.
| Game | Command or tool | Healthy reading |
|---|---|---|
| Minecraft (Paper) | /mspt, /tps, spark | MSPT under 50, TPS at 20 |
| Source games | stats in the server console | FPS at or above the tick rate |
| Rust | fps in the server console | Close to server.fps target, not falling |
| Factorio | UPS in a client's debug overlay | 60 |
| FiveM | resmon in the client, txAdmin's performance chart | Server thread hitches rare |
| Unreal-based servers | Server FPS if the game exposes it, otherwise player reports | Steady |
MSPT - milliseconds per tick - is the clearest of these. A Minecraft server at 20 TPS can be using 5 ms of its 50 ms budget or 49 ms of it, and the TPS number cannot tell those apart. MSPT can: 45 ms means one busy evening away from lag, whatever the CPU graph says. Where your game offers a per-tick figure, watch that instead of the CPU percentage.
Throttling, and how to prove it#
On a container, the CPU limit is enforced by the kernel's CPU controller. With cgroups v2, the limit and the throttling counters are visible from inside the container if you have a shell, for example on a VDS running Docker:
$ cat /sys/fs/cgroup/cpu.max250000 100000$ cat /sys/fs/cgroup/cpu.statusage_usec 81234567890user_usec 70123456789system_usec 11111111101nr_periods 4211230nr_throttled 18822throttled_usec 912345678cpu.max reads as "250,000 microseconds of CPU per 100,000-microsecond period" - two and a half cores. In cpu.stat, nr_throttled counts the periods in which the container hit that ceiling and was paused until the next one. Divide by nr_periods for a rate: here it is under half a percent, which is noise. A rate of several percent during peak hours, matching moments of lag, is real throttling. throttled_usec growing quickly while players complain is the same story in time.
Throttling interacts badly with tick-based games because it is bursty. A server that uses its whole quota in the first 70 ms of a 100 ms period is then paused for 30 ms, and a tick that needed 20 of those milliseconds arrives late. That is why a server can show an average well below its limit and still stutter: short bursts from background threads exhaust the quota and the main thread waits.
What to actually do about high CPU#
Once you know which case you are in, the fix follows.
Main-thread bound (flat at about 100%). Reduce the work per tick. This is game-specific and usually the most effective thing you can do:
- Minecraft: lower
simulation-distancebeforeview-distance, cap entities and redstone in Paper's configs, pre-generate the world so chunk generation is not happening during play - see the Paper optimisation guide. - Valheim: fewer building pieces and less terraforming in one place; the cost is concentrated where players gather.
- Rust: entity count and map size drive server frame time more than player count.
- Factorio: megabase UPS is a design problem, not a hosting one - fewer inserters, belts and biters per tick.
- Source: lower tick rate where the game allows it, fewer bots, fewer plugins hooking every frame.
If the work is already reasonable, the remaining fix is a faster core. More cores will not help.
Throttled at the limit. Something is using many threads at once. Common causes are world pre-generation (Chunky in Minecraft uses several threads at full speed), map renderers such as Dynmap and BlueMap, compression during backups, and plugins with their own pools. Schedule the heavy jobs for quiet hours, cap their thread counts where they allow it, or move up a plan. Moving up on RE:NODE changes the limit on the same server; nothing is rebuilt.
Spiky but players complain. Check whether the spikes line up with saves, backups or scheduled tasks. A backup compressing a large world can briefly take every core the plan allows, and a save on a big Valheim or Minecraft world blocks the main thread for its duration. Move those to quiet hours, and on Valheim consider the save-interval trade-off described in the Valheim server guide.
A worked example#
A Paper server for twenty players on a plan with a 300% limit. Complaints of lag every evening from about eight o'clock.
- The panel graph shows 105-115% from 20:00 to 23:00, and 30-40% during the day. Nowhere near the limit, so not throttling.
/msptat 21:00 shows averages of 48 ms with spikes to 90. The main thread is at its budget.- A spark profile shows 40% of tick time in entity ticking, mostly in two chunks, and 15% in hoppers.
- The two chunks are a mob farm and a villager breeding hall, both built the previous week.
- Paper's per-chunk entity limits and a hopper rate change bring MSPT to 28 ms at peak. The CPU graph now sits at about 70% in the evening.
Buying a plan with more cores would have changed nothing in step 1's graph and nothing for the players, because the problem was always one thread. Buying a plan with a faster core would have helped a bit and cost more each month for as long as the farm existed.
FAQ#
Why is my server lagging when CPU is only at 100% of 300%?
Because 100% is one core fully busy, and the game's main thread can only use one core. The thread is out of time, and the other two cores sit idle because the simulation cannot be split across them. Reduce the work per tick or move to a faster core.
Does a game server need more cores or a faster CPU?
Usually a faster core. Extra cores help with background work - world generation, saving, networking, compression - and with running more than one server. They do not speed up the main simulation loop.
Will my host suspend my server for using 100% CPU?
On RE:NODE, no. CPU is a hard throttle to the share you bought, so a server at its limit just runs slower. That is a reason to look at what is using the CPU, not a fault on the account.
Why does my server use CPU with nobody online?
Most games keep ticking empty - entities, crops, weather and AI in loaded areas still run. Some engines also busy-wait between ticks. Low, steady idle use is normal; idle use near a full core with nobody connected is worth checking against the game's own tick figures.
Is CPU percentage on the panel the same as in Task Manager?
No. The panel counts percent of one core, so 200% means two cores. Task Manager counts percent of the whole machine. The same load can read 200% on the panel and 25% in Task Manager.




Comments
Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.