Every online shooter runs at least three simulations of the same fight at once: the server’s, yours, and each opponent’s. They disagree constantly, because packets take time to cross the internet and arrive jittered, late, or not at all. Netcode is the machinery that stitches those disagreeing views into something that feels like a shared world, and every argument about tickrates, peeker’s advantage, or “desync” deaths is really an argument about how a studio chose to spend latency. This guide is built from primary engineering sources: Valve’s Source multiplayer networking documentation, Glenn Fiedler’s Gaffer On Games articles, and the netcode posts and developer updates from Riot’s VALORANT team and Blizzard’s Overwatch team.

What this covers: what a server tick is, how tickrate differs from packet rate, and how lag compensation, client-side prediction, and interpolation each trade one kind of fairness for another. Why it matters: being shot behind cover, rubberbanding, and peeker’s advantage are these mechanics working as designed — not bugs — and knowing the design tells you what your settings can fix and what only the server can. Who should care: competitive shooter players on any platform who want to understand hit registration instead of just blaming it.

What a tick actually is

A tick is the server’s simulation step. Valve’s Source multiplayer networking documentation defines it plainly: “The server simulates the game in discrete time steps called ticks.” During each tick the server processes incoming user commands, runs a physics step, checks the game rules, and updates every object’s state. Source’s default timestep is 15 milliseconds — 66.666 ticks per second — and shipped titles fixed their own rates: 66 ticks in Counter-Strike: Source and Team Fortress 2, 60 in Counter-Strike 1.6, 30 in the Left 4 Dead games, and 64 by default in CS:GO. Higher tickrates buy simulation precision at real cost; Valve notes that a tickrate-100 Source server generates about 1.5x the CPU load of the default 66.

Tickrate is not the same thing as packet rate. Source clients and servers exchange small packets 20 to 30 times per second by default: the client requests snapshot updates with cl_updaterate (default 20) and ships input commands at roughly 30 packets per second, while the server cannot send more than one update per tick. Delta compression keeps the payload down — the server sends only what changed since the last update the client acknowledged, not the whole world.

VALORANT pushes the fixed-step idea to its extreme. Riot’s engineers decouple movement simulation from render framerateframerate. How many images (frames) the game shows per second; higher = smoother motion. 60 fps is a common target. and update movement “with a fixed timestep: exactly 128 times per second” on both client and server, so a 30 FPS laptop and a 240 FPS desktop compute identical moves the server can compare move-for-move. That rate leaves 7.8125 milliseconds per server frame, and after a tuning campaign that started from 50ms frames, Riot’s team worked its actual per-frame budget down to roughly 2.34 milliseconds so three games could share one CPU core.

The four mechanisms at a glance

MechanismWhere it runsWhat it doesWhat it costs you
Ticks and snapshotsServerSimulate the world in fixed steps (15ms in Source, 7.8125ms in VALORANT) and broadcast state at a constant rate (20 snapshots/second in Source’s default)CPU and bandwidth; precision scales with tickrate
Entity interpolationClientDraw remote players between the two most recent snapshots instead of at the freshest oneA constant view delay — 100ms by default in Source, 7.8125ms of network interp in VALORANT
Client-side predictionClientApply your own inputs immediately, then reconcile against the authoritative serverRubberbanding and view snaps when the guess was wrong
Lag compensationServerRewind every other player to the instant you fired, trace the shot, then restore positionsYou can be killed after you already reached cover

Each mechanism spends a different currency: ticks spend CPU, interpolation spends constant view delay, prediction spends correction risk, and lag compensation spends the “I was behind cover” argument. The rest of this guide walks through what each one actually does inside a duel.

Lag compensation: the server rewinds time

You fire at a moving target at client time 10.5. Your shot command arrives at the server at time 10.6, and by then the target has kept moving — a server that only checked the present would miss even though your crosshair was dead on. Valve’s fix, and the industry standard since, is server-side lag compensation. The Source server keeps “a history of all recent player positions for one second,” and when your shot command executes it estimates when you fired:

Command Execution Time = Current Server Time - Packet Latency - Client View Interpolation

Then the server moves every other player back to that instant, runs the hit trace, and puts them back where they belong. Riot does the same in VALORANT with a historical buffer that stores player positions and animation state — “when the server receives a shot packet from the client, it rewinds the player positions and animation state using the historical buffer to calculate if the shot hit.” To fit that into a 128-tick budget, VALORANT only animates on the server every fourth frame and interpolates poses on rewind, which cut the animation system’s cost by 75 percent.

Why not let the client do hit detection? Because the server cannot trust it. Valve’s documentation is blunt about even a clean, VAC-protected client: a modified proxy on the network route could inject “hit” messages without the anti-cheat ever seeing it — what the doc calls a man-in-the-middle attack. Riot’s phrasing is shorter: “a server must never trust a client’s view of the world.” That same server-authority principle is why kernel-level anti-cheat exists at all — the client machine itself is treated as hostile territory, a topic covered in depth in Kernel Anti-Cheat Architecture: Ring 0 Drivers & Hypervisors.

Rewind has a price, and Valve’s documentation names it exactly: “you can be hit by an attacker you can’t even see anymore because you already took cover.” The server moved your hitbox back in time to where it was exposed. Riot caps how far the server will rewind for precisely this reason — “without limits, a player with 500ms latency could kill you a half second after you’d moved behind cover” — and both studios stress the results are not pixel-perfect: Valve notes hit-detection precision is bounded by tickrate and target speed, and errors of a few milliseconds in the time estimate can move a fast target by inches.

Peeker’s advantage, quantified

When you swing around a corner, your client applies your movement instantly through prediction. Your opponent only sees you after your input travels to the server, gets simulated, and streams back down their connection — plus their own interpolation and frame delay. That gap is peeker’s advantage, and Riot is the only studio that has published the full arithmetic. Its netcode article walks the chain (peeker input → server → holder’s screen) and, assuming two frames of server buffering and three of client buffering, concludes that “peekers have ~141ms longer to react than defenders” at baseline.

Cutting that number drove VALORANT’s entire server stack: Riot built its own backbone (Riot Direct) targeting 35ms round trips for 70 percent of players, standardized 128-tick servers, and tuned client and server buffering to roughly one frame and half a frame respectively. The result: those measures shave about 40ms — 28 percent — off the raw advantage, and a client running at 144 FPS brings it “down to ~71ms (a 49% reduction).” In the shipped game, David Straily put the figure at “an average of 40-70ms,” against an average human reaction time of about 247ms. Riot’s blind playtests with top-tier players found they could identify roughly 10ms changes, and that “a delta of 10ms of peekers advantage made the difference between a 90% winrate for the player holding an angle with an Operator and a 90% winrate for their opponent peeking with a rifle.”

Two clarifications from the same sources are worth keeping. High ping does not favor the high-ping player — “low latency is near always superior,” and their extra peeker’s advantage against you is mirrored by yours against them, degrading the fight for everyone rather than helping them. And the phenomenon cannot be engineered away, only minimized: as Straily wrote, “until humanity learns to move faster than the speed of light, peeker’s advantage is never going away.”

Blizzard tuned the same lever for Overwatch’s 2016 high-bandwidth update. Raising the server update rate toward 60Hz let the team cut the client’s interpolation delay — visible in-game as the “IND” stat — from around 54-55 down to about 20, with the direct consequence that “you will be shot around corners less.”

Prediction, reconciliation, and rubberbanding

The original Quake ran you as a dumb terminal: press forward, wait for the round trip, then move. John Carmack changed that in QuakeWorld — “I am now allowing the client to guess at the results of the users movement until the authoritative response from the server comes through” — and every shooter since has client-side prediction. The hard part is not the guess; it is the correction, which by definition describes the past. On a link with 100ms each way, any server correction describes a position 200ms behind where your client has already predicted itself to be.

The reconciliation trick, as Glenn Fiedler describes it, is a circular buffer of your past states and inputs: when a correction arrives, the client discards everything older than it and replays your stored inputs from the corrected position back up to the present — an invisible rewind-and-replay of the last few frames. The server stays authoritative throughout, because a client that simply reported its own position would let a cheater teleport behind you. Tim Sweeney’s old line still governs: “The Server Is The Man.”

When prediction and authority disagree, you feel it. Valve’s documentation says the correction “may cause the client’s view to jump erratically,” smoothed over a short window (cl_smoothtime) so it does not read as a hard teleport. VALORANT’s server, when a client’s update is late, predicts the missing moves by assuming held keys continue, commits its own result as truth, and corrects only the lagging player — “these corrections are rare, small in magnitude, and only seen by the player who encountered the underlying network issues.” That visible snap-back is what players call rubberbanding: prediction and authority disagreeing out loud. Notably, prediction only ever covers your own movement, because your client cannot know an opponent’s inputs before they arrive — Valve points out predicting other players “would require literally predicting the future with no data.”

Interpolation buffers: the delay you never see

Remote players are not drawn where the server says they are right now. They are drawn between the two most recent snapshots, which means deliberately in the past. Source defaults to 20 snapshots per second — one every ~50ms — and a 100-millisecond interpolation period (cl_interp 0.1), so the renderer always has a pair of snapshots to blend between; lose one packet and nothing visible happens, lose two in a row and the client briefly extrapolates (capped at 0.25 seconds in Source) before it runs out of history. That is a constant, built-in view lag of 100ms in the stock configuration, and it is why the moving player sees a stationary one a split second before the reverse — the price of smoothness on a jittery network.

Fiedler’s snapshot interpolation article gives the working rule: buffer about three send-intervals to survive two lost packets in a row at typical loss rates — 300ms at 10 sends per second, roughly 350ms once jitter is added. His conclusion is the one every studio acted on: the way to shrink interpolation delay is to raise the send rate — 30 snapshots per second needs only 150ms, 60 needs 85ms — and lost snapshots are simply skipped, never waited for. Overwatch’s high-bandwidth mode and VALORANT’s adjustable Network Buffering setting are both applications of this trade: smoothness on bad connections, freshness on good ones.

How shipped shooters handle it, and CS2’s sub-tick

GameServer modelPublished figure
Counter-Strike: Global OffensiveTick-based, default 6464-tick official default; 128-tick community servers split spray and grenade behavior
VALORANTTick-based, 1287.8125ms server frames; peeker’s advantage averages 40-70ms
Counter-Strike 2Sub-tickServer timestamps inputs between ticks; tick rate “no longer matters for moving and shooting”
Overwatch (high-bandwidth mode)~60Hz updates, adaptive per playerInterpolation delay stat (“IND”) fell from ~54-55 to ~20

Counter-Strike 2 replaced the discrete tick as the unit of truth for player actions. In Valve’s own framing, “previously, the server only evaluated the world in discrete time intervals (called ticks),” but with sub-tick updates “servers know the exact instant that motion starts, a shot is fired, or a ‘nade is thrown” — and so “the tick rate no longer matters for moving and shooting,” with grenades landing the same way regardless of rate. Inputs arrive stamped with the precise moment they happened, and the server computes results between ticks. The CS2 team later described the goal as “a consistent, tick-independent experience that’s better than CS:GO’s 64 or 128 tick experience,” noting that CS:GO’s community had been split between 64-tick matchmaking and 128-tick third-party servers, with tickrate affecting grenade simulation and spray patterns — CS2 matched its sprays to the 128-tick behavior.

Sub-tick shipped with its own turbulence. The team said early viral clips of missed shots traced to an animation-hitbox mismatch when looking down — a bug, not the architecture — and a subsequent update made sub-tick input feedback (movement acceleration, muzzle flashes) render on the next frame and synchronized the random numbers used for shooting spread between client and server, so tracers and decals match the server’s authoritative trajectory.

What you can actually change

Valve’s guidance survives every engine generation: match your rate to your real bandwidth, remember the snapshot rate can never exceed the server’s tickrate, and know your interpolation period is max(cl_interp, cl_interp_ratio / cl_updaterate). The documentation’s warning is categorical — do not turn off view interpolation or lag compensation, because “it will not improve movement or shooting precision”; it will only expose you to raw packet jitter.

Beyond console variables, the biggest personal lever is framerate, because your opponent’s frame time is part of their view of you: Riot’s own numbers show a 144 FPS client brings an enemy peeker’s total advantage down to ~71ms — a 49 percent cut from the ~141ms baseline. Wired beats wireless — Riot’s performance-monitoring advice specifically suggests “switching to a wired connection to reduce packet loss.” And the display-side half of the latency budget, from frame queues to anti-lag pipeline tuning, is covered separately in Frame Generation Latency: Reflex vs Anti-Lag 2 Frame Pacing.

None of it touches the parts only the server controls: the tickrate, the rewind window, the buffering targets. Those are studio decisions, made public in exactly the engineering posts cited above — which is why every “just fix netcode” argument eventually lands on a budget, not a bug.

Next read