--- title: "sys_ticrate Explained: The Truth About 1000 FPS Servers" excerpt: "What sys_ticrate really controls, why '1000 FPS' is mostly marketing, how server FPS caps updaterate, and how to measure and set it honestly on Linux." category: "optimization" tags: "sys_ticrate, fps" image: "" read_time: "8 min read" ---
Every CS 1.6 host advertises "1000 FPS servers" as if it were a feature you can buy. sys_ticrate is the cvar behind that number, and the reality is more nuanced than the marketing: it sets a ceiling on how often the server loop runs, the machine has to actually deliver it, and past a certain point more FPS buys you nothing. Here is what the cvar does, why the number matters up to a point, and how to measure what you are really getting.
sys_ticrate sets the maximum frames per second the dedicated server's main loop targets. Each "frame" is one pass where the server simulates physics, processes inputs, and sends snapshots. Higher FPS means the server can react and send updates more frequently. It is set as a launch parameter or in config:
./hlds_run -game cstrike +sys_ticrate 1000 +map de_dust2 +maxplayers 20
The key word is maximum. Setting sys_ticrate 1000 does not make the server run at 1000 FPS — it permits up to 1000 if the CPU and the OS timer can keep up. On a loaded or poorly-timed box you might ask for 1000 and get 300.
The reason server FPS matters at all is that it caps the update rate you can send clients. The server cannot send more snapshots per second than it runs frames:
sv_maxupdaterate 100 — clients ask for 100 updates, the server produces 60, and the difference shows up as choke on the scoreboard.Above roughly 100–500 FPS the returns diminish sharply. The client cannot request more than sv_maxupdaterate updates regardless, and CS 1.6 netcode does not meaningfully improve at 1000 versus 500. The jump from 60 to 500 FPS is real and felt; the jump from 500 to 1000 is mostly a number on a listing. See choke and loss for the client side.
Stock HLDS on Linux historically could not hold high, stable FPS because of how it slept between frames — the OS timer resolution and the sleep method capped it. Two things address this:
-pingboost selects the timing method. -pingboost 1, 2 and 3 use different sleep/timer strategies; -pingboost 3 is the one people use to chase high FPS, but it can raise CPU usage. Test each on your box:./hlds_run -game cstrike -pingboost 3 +sys_ticrate 1000 +map de_dust2
Do not chase 1000 FPS by pinning the CPU with a busy-loop trick on a shared box — you will get throttled or evicted, and the jitter makes the high average worthless.
A reasonable configuration for a public server:
+sys_ticrate 1000 // with matched client-rate ceilings sv_maxupdaterate 101 sv_maxrate 25000
Request 1000, then measure what you actually get and set sv_maxupdaterate to something the server can truly sustain. Promising 101 updates on a server that dips to 70 FPS under load is worse than promising 66 and always delivering it.
The console stats command is the truth:
stats
It prints CPU%, in/out bandwidth, and — the column you want — the server's actual FPS. Watch it with a full server, not empty; FPS under 20 players tells you what your clients experience, an idle reading does not. If the sustained FPS is far below sys_ticrate, you are timer- or CPU-limited, and no bigger number in the launch line will fix it.
sv_maxupdaterate exceeds real server FPS. Lower it to match measured FPS.-pingboost 3 or a busy-loop on shared hardware. Back off; see HLDS at 100% CPU.Fill the server (or add bots to load it), run stats, and read the sustained FPS column. Set sv_maxupdaterate at or below that number, confirm clients show near-zero choke on the scoreboard, and stop there. A server that honestly holds 500 FPS with no choke beats one that claims 1000 and stutters — tune with the essential cvars and measure, never guess.