A server lagging with 32 players is a bandwidth story; a server lagging with 10 is almost always a server-FPS story. GoldSrc simulates the whole world on a single loop, and if that loop is not running fast and steadily, every player feels rubber-banding, hit registration goes soft, and jumps stutter — regardless of how much bandwidth you have. This walks through diagnosing it properly instead of blaming the players' pings.
1. Measure the actual server FPS
Do not guess. From the server console (or RCON), run:
stats
You get a line like CPU In Out Uptime Users FPS Players. The number that matters is FPS — the frames-per-second of the server loop, not anyone's client. On a healthy box this should sit close to your sys_ticrate target (500 or 1000) and stay steady. If it swings between 100 and 900, or sits far below your ticrate, that instability is your lag. A server pinning 1000 FPS with 10 players feels perfect; one bouncing around 200 feels broken even on a LAN.
2. Set sys_ticrate correctly
The server loop's target rate is sys_ticrate, set on the command line, not in a config:
./hlds_run -game cstrike +sys_ticrate 1000 +ip 0.0.0.0 +port 27015 +map de_dust2
This is a ceiling, not a guarantee — on stock HLDS the loop rarely holds a steady 1000 and often will not exceed a few hundred no matter what you set. That is a known HLDS limitation, covered in why sys_ticrate does not change your FPS. If stats shows the FPS stuck far below your ticrate, the engine itself is the bottleneck and you need ReHLDS.
3. Switch to ReHLDS for a stable loop
The single biggest fix for stutter on a low-population server is replacing Valve's HLDS with ReHLDS, the reverse-engineered engine that actually holds a steady, high server FPS. On ReHLDS the loop stays pinned at your ticrate instead of oscillating, which is exactly what smooths movement and hitreg. Follow the ReHLDS install guide; it is a drop-in replacement for the engine binaries and keeps your existing cstrike/ content.
4. Give clients enough rate
Even with a fast loop, a player whose rate is throttled will feel choppy. Set sane server-side ceilings in server.cfg:
sv_maxrate 25000 sv_maxupdaterate 101 sv_minupdaterate 20 sv_maxcmdrate 101
These let modern clients request cl_updaterate 101 and a high rate. If your sv_maxrate is left at an old default like 10000, you are strangling every client to dial-up speeds — a classic cause of "lag" that has nothing to do with CPU. Note some of these cvars only take effect on ReHLDS/ReGameDLL; see when sv_maxrate is ignored.
5. Rule out a busy or throttled CPU
The CPU column in stats is the fraction of the loop's time budget being consumed. If it is riding near 100 with only 10 players, something is eating the loop: a heavy plugin running an expensive task every frame, a runaway set_task, or the box being oversold on a cheap VPS that steals CPU. Check for stolen time on Linux:
top # look at the %st (steal) column
High %st means the hypervisor is giving your CPU cycles to other tenants — no config fixes that, only a better host. Also audit plugins: pause them one at a time with amxx pause <plugin>.amxx and watch whether stats FPS recovers.
Troubleshooting
- FPS in
statsis fine but players still lag — it is bandwidth or a client-side rate, not the server loop. Raisesv_maxrate/sv_maxupdaterateand have players setrate 25000; cl_updaterate 101. - FPS oscillates wildly on HLDS — expected on Valve's engine. Move to ReHLDS for a stable loop.
- CPU column near 100 with few players — a plugin or a stolen-CPU VPS. Pause plugins to find the culprit; check
%stintop. - Lag spikes exactly on map change or when a player connects — disk I/O or a slow precache, not the loop. See stuck on verifying resources.
- Only high-ping players lag — that is normal geography, not a server fault. Consider
sv_maxupdateratetuning, not a rebuild.
Verification
Run stats repeatedly under a live 10-player load and confirm the FPS number holds near your sys_ticrate target and the CPU column stays comfortably under 100. Have one player run net_graph 3 and watch for a flat, gap-free graph — steady fps and no choke or loss. If the server FPS is steady and rates are correct but a player still rubber-bands, the problem is that player's connection, not your server. Once the loop is stable, lock in the rate cvars in server.cfg so they survive restarts.









