Netcode

Connection settings

The hubmix servers are tuned so a shot that was correct on your screen is correct on theirs. Half of that lives on your PC — in settings the server can raise a ceiling for but can never set for you. This is the whole of the client half: what to set, why, and which famous settings do nothing at all.

Check this first

cl_lw 1 and cl_lc 1. At 0 the server stops rewinding the world to what you saw — every shot is judged against the present and you have to lead by your full ping. Plenty of “FPS boost” configs set them to 0.

Then paste the block

One copy, one paste, two minutes. Pick your frame rate below so the block is built for your PC rather than for an imaginary average one.

Nobody can set these for you

Not hubmix, not any server. The client has refused config commands from servers since 2013. Any plugin claiming to fix your rates is doing nothing — which is exactly why this page has to exist.

Build it for your machine

Frame rate your PC holds steadily

Not the number it peaks at on an empty server — the one it never drops below with ten players and a smoke on screen. Your frame rate is your input rate: one movement command per rendered frame.

What the engine does on its own. Needs no fps_override, and never fights vsync.

Your connection

This changes exactly one line — how many old commands are re-sent as insurance. It is bandwidth spent on every packet forever, so it is only worth paying when packets are genuinely being lost.

net_graph shows loss at 0. This is most people, most of the time.

Commands you create

100.5per second

One per rendered frame. The engine adds half a frame to whatever you cap it at.

Packets you send

100.0per second

Your frame rate or cl_cmdrate, whichever is lower.

Commands per packet

1.0of 16

Past the limit the surplus is discarded on your own PC, before it is sent.

Longest an input waits

10.0ms

How long a keypress can sit here before a packet carries it away.

At 100.5 frames a second, any cl_cmdrate below 7 starts discarding your input before it is sent. Counter-Strike ships with 30 — check yours first, because if it is still the default this single line is the whole problem.

recommended

Save as cstrike/hubmix.cfg, then type “exec hubmix” in the console. Survives restarts — which fps_override needs, because the engine does not save it.

// ===========================================================
//  hubmix - Counter-Strike 1.6 connection settings
//  Every line below is explained at hubmix.net/connection
//  Built for: fps_max 100 | a clean link
//  Save as cstrike/hubmix.cfg, then in the console:  exec hubmix
// ===========================================================

// -- What the server sends you --
rate 100000        // engine maximum bytes/sec the server may send you
cl_updaterate 102  // snapshots/sec - matches the hubmix server ceiling

// -- What you send the server --
cl_cmdrate 100     // packets/sec of input - one per frame, packed
cl_cmdbackup 2     // loss insurance only. Not a registration knob

// -- Lag compensation --
ex_interp 0        // resolves to 1/cl_updaterate and self-tracks it
cl_lw 1            // MANDATORY - 0 disables lag compensation entirely
cl_lc 1            // MANDATORY - the other half of the pair

// -- Frame rate --
fps_max 100        // steady is worth more than high (~100.5 fps in practice)
gl_vsync 0         // no effect at 100; matters if you raise it
Your Counter-Strike folder → cstrike → new file named hubmix.cfg.

Line by line

What each line does, why that value, and what the claim rests on. Paste it blindly if you like — but this section is here so you do not have to, and so you can tell us where we are wrong.

Engine source

Read off the engine’s own code or a constant in it. If this is wrong, the game is not doing what its source says it does.

Measured

Someone ran it and published numbers. Reproducible, and not just reasoning.

Mechanism, unmeasured

It follows from how the engine works, but nobody has measured the effect end to end. We say so rather than dressing it up.

Depends on you

Your hardware or your connection decides this one. Any page that gives you a single number here is guessing.

What the server sends you

How much, and how often.

  • rate 100000 Engine source

    The ceiling on how many bytes per second the server may send you.

    100,000 is the engine's own maximum — ask for more and it is clamped straight back to this. It matters because the ceiling is spent per snapshot: at roughly 100 snapshots a second the old habit of rate 25000 leaves about 217 bytes for each one, and a 5v5 firefight is bigger than that. The server then withholds part of the update — that is choke — and you aim at a world one beat behind the one it is judging you against.

    Evidence · MAX_RATE = 100000 and MIN_RATE = 1000 are constants in the engine networking header, unchanged since retail and identical in Xash3D’s independent reimplementation.

    Honestly · This is a request. The hubmix servers clamp it into their own band, and on a connection that genuinely cannot carry the stream, a high rate turns polite server-side choke into real packet loss on the wire. If your line is that thin, this line is not your problem.

  • cl_updaterate 102 Mechanism, unmeasured

    How many snapshots of the world you ask the server for each second.

    102 is the ceiling the hubmix servers run, and the client clamps anything higher with a console print — so nothing above it exists. It is 102 rather than 100 because the server can only send on its own frame boundaries: asking for exactly 100 puts you on the boundary, where a hair of overshoot costs a whole frame and drops you to about 91 snapshots a second. 102 lands in the same bucket without sitting on the edge.

    Evidence · The clamp is engine source. The 102-over-100 boundary argument follows from how the server quantises sends to its own frames, but hubmix has not published a measurement of it yet — so treat 102 as the right value and verify with net_graph 3 that you are actually served it.

What you send the server

Your input, and how it is packed.

  • cl_cmdrate 100 Engine source

    How many times a second your PC posts its input to the server.

    Your PC makes exactly one movement command per rendered frame, so this does not change how much input you produce — only how it is packed. Too low and a packet overflows the 16-command limit and the surplus is thrown away before it is ever sent: the stock cl_cmdrate 30 at 1000 fps needs 33 per packet and loses 17 of them. At your 100.5 fps, 100 carries 1.0 command per packet — well inside it — and never lets an input wait more than 10.0 ms for a ride.

    Evidence · One command per frame, and the per-packet command cap with its silent discard, are both in the client send path. The value is bounded from below by that cap and is inert above your frame rate, which leaves a narrow, uncontroversial band.

  • cl_cmdbackup 2 Depends on you

    How many previous commands ride along again in each packet, in case one is lost.

    Pure insurance against lost packets, charged on every packet whether or not you ever lose one. On a clean line 2 is enough. It is not a registration setting, and the configs that put it at 8 or 60 are paying upstream bandwidth for an event that is not happening to them.

    Evidence · The redundancy mechanism and the CMD_MAXBACKUP budget are engine source; whether you need more than 2 is a fact about your connection that only net_graph on your PC can answer.

    Honestly · Only raise this if net_graph 3 shows you actually losing packets. New commands plus this number must stay under 63 in one packet, and past that the server drops you.

Lag compensation

Whether the server rewinds the world to what you saw. Not optional.

  • ex_interp 0 Engine source

    How far in the past other players are drawn, so their movement is smooth.

    0 does not mean "off" — it means "track my updaterate", and the engine resolves it to exactly 1/cl_updaterate (9.80 ms at 102) and rewrites the cvar itself when you connect. That is the floor, and it is where you want to be: every millisecond above it is a millisecond further into the past that the server rewinds the person you are shooting at.

    Evidence · The resolution to 1/cl_updaterate and the server-side floor are both in the source. It is also why the famous interp-by-ping tables are meaningless: 0.01, 0.001 and -1 all land on the same floor.

    Honestly · Values ABOVE the floor are not tuning and hubmix does not treat them as such. ex_interp 0.1 makes the server rewind an extra tenth of a second on your behalf — you shoot where you saw them, and they die well after breaking cover. That is manufacturing a disagreement and billing it to your opponent.

  • cl_lw 1 Engine source Mandatory

    Predicts your own weapon firing on your PC instead of waiting for the server.

    This is not a smoothness preference. With cl_lw 0 the server switches lag compensation off for you completely — not reduced, off — so your shots are judged against where the enemy is NOW rather than where you saw them. You would have to lead every single target by your full ping while nobody else in the server does. It is 1 by default and a great many "FPS boost" configs on the internet set it to 0.

    Evidence · The server’s rewind routines return immediately when a client reports lw or lc as 0, and a client that omits the key entirely is read as 0. No server cvar can override it — it is yours, which is why it is on this page and not in the server config.

  • cl_lc 1 Engine source Mandatory

    Tells the server you want it to rewind the world to what you actually saw.

    The other half of the pair above, and it fails the same way: at 0 the server stops rewinding for you and every shot is judged against the present. Both must be 1. Check them together and check them first — no other line on this page can rescue a match played with these off.

    Evidence · Same condition in the same routines: lag compensation is skipped unless lw AND lc are 1.

Frame rate

Your hardware, not a netcode fact.

  • fps_max 100 Depends on you

    Caps how many frames your PC renders — and therefore how many inputs it creates.

    You chose 100, so the engine will run at about 100.5 and produce that many movement commands a second. Higher is not automatically better: what matters is a rate your PC holds STEADILY, because a frame rate that swings is an input rate that swings. No server can set this for you — the cvar to do it does not exist in GoldSrc — so it is yours to pick.

    Evidence · The clamps are engine source; which number suits your PC is not a netcode fact and this page will not invent one. Frame rate is also the simulation step for air acceleration, duck height and jump timing in this engine — documented by Valve’s own 2013 changelog entry about movement above 100 fps — so it is a hardware difference, not a neutral setting.

    Honestly · Pick the highest rate your PC never drops below in a full server, not the highest it can touch on an empty one.

  • gl_vsync 0 Engine source

    Locks your frame rate to your monitor’s refresh rate.

    You chose 100, which is what the engine does anyway, so this line changes nothing about what you send today. It is here so that the frame rate you set stays the frame rate you get if you ever raise it.

    Evidence · The client explicitly forces 100 fps when vsync is enabled and fps_override is not — one branch, in the frame gate.

Check it actually took

Do not take our word for any of this. Four console commands tell you what your client is really doing — and the third one has caught more broken configs than every guide on the internet combined.

  • net_graph 3

    Draws the live graph. The number to watch is choke: it should be 0. Loss should be 0 too. The red dots on the bottom row are normal and are explained below.

  • cl_updaterate

    Typed on its own with no value, the console prints what the cvar is right now. Do this while you are IN a match — the server clamps it on connect, and the clamped number is the one that counts.

  • rate

    Same idea. If it does not read back what you set, something on your PC is overriding it.

  • cl_lw

    Must print 1. So must cl_lc. If either reads 0, nothing else on this page matters until it does not.

Things that are not settings

If the block above is already in place and the game still feels wrong, the cause is almost always here. None of it has a cvar, and the first one is invisible while it is happening to you.

A jittery connection silently switches your lag compensation off

Engine source

The server averages your last four acknowledgements. If the spread between the fastest and the slowest of them exceeds 200 ms, it stops trusting the number entirely and rewinds nothing at all for you — no warning, no console line, nothing to configure. Steady ping beats low ping here, and it is the reason a connection that "only spikes occasionally" can feel like the game is broken during exactly those seconds.

Wired beats wireless, and it is not close

Mechanism, unmeasured

Wi-Fi does not usually raise your average ping much — it raises the SPREAD, which is the number that matters above. An ethernet cable is the single largest improvement most players can make, and it costs nothing to test for one match.

Anything downloading in the background is competing with you

Mechanism, unmeasured

Game updates, cloud sync, a stream in another window: each of them fills the same buffer your snapshots queue behind, and a full buffer is jitter by another name. Close them before you queue, not after you lose a duel.

Your frame rate is your input rate

Engine source

One movement command per rendered frame, always. A frame rate that swings between 300 and 90 in a smoke is an input rate doing the same thing. This is why a steady 100 is worth more than an unstable 500, and why it is worth capping to something your PC can genuinely hold.

Settings that do nothing

Every one of these is in configs being traded today, and every one is either clamped away, identical to a value the engine was already using, or below a floor it rounds to. We are publishing them because a page that only ever adds settings is indistinguishable from the twenty years of pages that added them for no reason.

  • cl_updaterate 102.00000381 Engine source

    Bit-identical to 102. It is exactly half an ULP away in 32-bit float and rounds straight back to it. It is in thousands of configs and it has never once done anything.

  • cl_cmdrate 100000 — or "your fps plus 5" Engine source

    Your PC sends at most one command per rendered frame, so every cl_cmdrate above your frame rate produces a bit-identical packet stream. 101, 105, 110, 999 and 100000 are the same setting at 100 fps. The "+5" rule has no mechanism behind it at all.

  • ex_interp 0.01 for LAN, 0.02 for 20 ping, 0.1 for 50 ping Engine source

    Everything at or below the floor resolves to 1/cl_updaterate — 0, 0.01, 0.001 and -1 are one value. The tables are folklore below a floor the engine applies anyway. Above the floor the numbers do something, and it is not something hubmix considers legitimate.

  • fps_max 101 (without fps_override 1) Engine source

    Hard-clamped to 100 before the engine uses it, so it is the same as fps_max 100. The twenty-year "101 fps" tradition is a value the engine throws away on the very next line.

  • cl_updaterate 128 / 1000, or rate 125000 Engine source

    Clamped to 102 and 100,000 respectively, and the client prints a line in the console when it does it. Typing a bigger number does not buy a bigger number.

  • "Raise cl_cmdrate until the red dots on net_graph go away." Engine source

    The red row is held-back commands — inputs waiting for the next packet, which are then bundled into it and fully simulated. It is the normal look of a frame rate above your cmdrate. It is not loss, not choke, and not a registration signal.

  • "Set cl_updaterate no higher than your FPS." Engine source

    Two unrelated directions. cl_updaterate paces what the server sends DOWN to you; your frame rate governs the commands you send UP. Neither constrains the other.

  • cl_cmdbackup 8 (or 60) "for better registration" Engine source

    Backup is duplicate copies of commands you already sent, for the case where a packet is lost. At 0% loss every extra copy is upstream bandwidth spent on nothing, forever.

  • "ReHLDS lifted the old 25000 rate cap." Engine source

    There was never a 25000 cap in the engine. The maximum has been 100000 since retail; 25000 was a Steam connection-speed slider convention from an era of dial-up. Nothing was lifted.

  • "This server forces the correct rates on you." Engine source

    It does not, and it has not been able to since 2013: the client filters rate, ex_interp, fps_max and the cl_* family out of anything a server tries to run on it. Every plugin still claiming to fix your config is either doing nothing or abusing something. Your settings are yours — which is precisely why this page had to exist.

Popular settings that actually cost you

Worse than placebo: widespread, confidently recommended, and they take something from you.

  • cl_lw 0 / cl_lc 0 — "removes delay", "boosts FPS", "fixes your reg" Engine source

    These turn lag compensation off entirely. The server stops rewinding the world to what you saw and judges your shots against the present, so you must lead every target by your full ping while nobody else in the match does. If exactly one thing on this page is worth checking before your next match, it is that both of these are 1.

  • rate 25000 — "the maximum" Engine source

    A quarter of what the engine allows. At about 100 snapshots a second it leaves roughly 217 bytes for each one, which a 5v5 firefight exceeds routinely, and the server starts withholding parts of updates. You experience that as registration that works fine until the moment it matters most.

  • cl_cmdrate 30 (the value Counter-Strike ships with) Engine source

    At 1000 fps that is 33 commands crammed into a packet that carries 16. The other 17 are discarded before the packet is sent — real input, lost on your own PC, every single packet.

  • ex_interp 0.1 — "so you can see people around corners" Engine source

    It works by making the server rewind an extra tenth of a second on your behalf: you shoot where you saw them and they die long after breaking cover. That is not compensating for a disagreement, it is creating one and charging it to the other player. hubmix reads it exactly that way.

Still convinced something is wrong?

Then it is worth reporting rather than re-pasting a config. Tell us the match, what you saw and what net_graph 3 read at the time — choke, loss and your frame rate. Every hubmix match is recorded, so a report with a match ID can be checked against what the server actually saw.

The other two things every hubmix match needs are on Help & downloads: the anti-cheat and TeamSpeak3. Neither of them touches the settings on this page.