Diagnosing Lag on Source Engine Servers: Reading net_graph Choke, Loss, sv, and var
Players rubber-band but ping looks fine? Learn to read net_graph choke, loss, sv, and var on a Source engine server to isolate whether the cause is client rates, server tick instability, or the network path.
29 Aug 2026, 21:33 UTC

The recognizable condition
Players on your srcds server (CS:S, TF2-class Source titles) report rubber-banding, delayed hit registration, or shots that "should have hit." Ping looks normal. The instinct is to blame the host, but the useful first step is reading net_graph on an affected client and the server console stats output at the same moment. Four values do most of the diagnostic work:
- choke — updates the server wanted to send but couldn't, usually because a rate limit capped the bandwidth. Choke points at configuration, not hardware.
- loss — packets that never arrived. Loss points at the network path or an overloaded server dropping traffic.
- sv — the server's frame time (how long the last simulation tick took, in ms).
- var — variance in that frame time. High var means the server tick is unstable even if average sv looks fine.
Note that net_graph layout and field names differ between Source branches and games. Confirm the fields on your specific title before trusting a label; the underlying concepts (choke, loss, server frame time) are consistent.
Cause table
| Symptom pattern | Likely cause | First check |
|---|---|---|
| Choke rising, sv/var low and stable | Client rate limits (rate, cl_updaterate, cl_cmdrate) below what the server tick needs, or sv_maxrate too low for everyone | Compare client rates against server min/max cvars |
| var spiking, ping stable | Server CPU saturation, heavy plugins, or entity overload making ticks run long | Server console stats; reproduce without plugins |
| Loss with healthy sv/var | Routing/ISP path, packet filtering, or host network congestion | Continuous ping/traceroute during symptoms |
| Choke for all players regardless of client config | Server-side sv_maxrate / sv_maxupdaterate clamping everyone | Read actual cvar values from server console |
Ordered checks
- Confirm the server's real tickrate and stability. In the server console (or via RCON), run
statsand watch CPU and FPS over a minute of live play. Tickrate is fixed per game build (commonly 64, or 128 where the title supports it) and cannot be changed at runtime — verify what you actually have rather than trusting the listing. - Capture sv/var on an affected client. Have the player enable net_graph during symptoms and note whether var spikes coincide with the rubber-banding. Screenshotting both net_graph and the server
statsoutput at the same moment lets you correlate the two views. - Compare client rates against server clamps. Client cvars are clamped by
sv_minrate/sv_maxrateandsv_maxupdaterate, so a client raisingratemay have zero effect. Check the server values first, then align clients to them. A mismatchedcl_updateratesilently caps effective update frequency no matter how much bandwidth is available. - Remove the network path. Connect a client from the same LAN or host. If choke and loss vanish locally while sv/var stay flat, the server is healthy and the problem is between host and players.
- Profile the path. During symptoms, run a continuous ping and traceroute/mtr from an affected player's connection to the server IP. Loss appearing at the first hop is the player's ISP; loss appearing only at the final hops points at the hosting provider.
Fixes tied to findings
Universal choke: raise sv_maxrate (and check sv_maxupdaterate) in server.cfg, then restart the map and confirm with sv_maxrate in the console that the value took effect. If only some players choke, fix their client rates to sit inside the server's min/max window instead.
var spikes: reproduce on a clean server — default config, no SourceMod plugins, one local client. Third-party plugins are a frequent cause of tick variance, so reintroduce plugins one at a time until var returns. If var spikes persist on a clean server with confirmed CPU headroom, suspect the hardware or virtualization layer (shared CPU steal on a cheap VPS is a common culprit).
loss with healthy server metrics: this is not fixable in config. Take your traceroute evidence to the host and ask about routing/peering changes, or test a server in a different location.
Escalation criteria
Escalate to the hosting provider when either is true: (1) var spikes persist after plugin removal and you've confirmed CPU headroom, indicating a hardware or hypervisor problem; or (2) loss is reproducible from multiple players on different ISPs, indicating a provider-side network fault. In both cases, attach the captured stats output and traceroute logs — "it feels laggy" tickets get deprioritized, correlated evidence does not.
Limitations and verification
These readings are per-moment snapshots; a single capture can mislead. Always correlate client net_graph with server stats at the same instant, and prefer the A/B approach (clean server, one variable reintroduced at a time) over changing three cvars at once. Behavior described here reflects established Source engine networking; field names and default rate limits vary by game and branch, so verify against your title's console before documenting values for your community.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.