A Counter-Strike 2 server is configured in three places, and most of the confusion people have with it comes from not knowing which of the three wins. The launch line holds the things the engine needs before it has loaded anything - the port, the token, the tick rate. game/csgo/cfg/server.cfg holds the server's identity and its network settings. And the game mode config, executed after server.cfg on every map load, holds the round rules and overwrites whatever you put in server.cfg that it also sets. That last sentence is the answer to "why does my mp_maxrounds keep resetting".
This post is the reference for all three: the launch parameters worth using, the cvars that change something you can feel, and the commands you run live over RCON. It assumes you already have a server and a token - setting up a Counter-Strike 2 server covers getting there.
What the server reads, and in what order#
The CS2 dedicated server comes from Steam app 730, the same app id as the game, and installs to a tree with the interesting parts under game/csgo/:
game/ bin/linuxsteamrt64/cs2 the server binary csgo/ cfg/ server.cfg execed on every map load gamemode_competitive.cfg Valve's mode defaults gamemode_competitive_server.cfg your overrides gamemode_casual.cfg gamemode_deathmatch.cfg addons/ Metamod and plugins, if you add them maps/ installed and workshop maps gamemodes_server.txt map groups and per-mode convarsThe practical rule that falls out of this: anything beginning mp_ belongs in gamemode_<mode>_server.cfg, and anything beginning sv_, hostname, rcon_password or tv_ belongs in server.cfg. The _server files do not ship - you create them - and they are the supported place for overrides, which is why they survive a game update that rewrites Valve's own configs.
The launch line#
On your own Linux box, install and start looks like this:
$ steamcmd +force_install_dir /home/cs2/server +login anonymous \ +app_update 730 validate +quit$ cd /home/cs2/server$ ./game/bin/linuxsteamrt64/cs2 -dedicated -usercon \ -port 27015 -maxplayers_override 12 -tickrate 128 \ +game_alias competitive +map de_dust2 \ +sv_setsteamaccount YOUR_GSLT_TOKENOn a panel-based host you never type that; the same values appear as fields on the Startup tab, and the panel assembles the line. Either way these are the parameters that matter:
| Parameter | What it does |
|---|---|
-dedicated | Runs headless. Without it you are launching the game |
-usercon | Enables RCON. No RCON without this, whatever password you set |
-port 27015 | Game port, UDP, and the RCON port, TCP |
-maxplayers_override 12 | Slot count. Overrides whatever the mode wants |
-tickrate 128 | Simulation rate. Default is 64 |
-insecure | Disables VAC. Only for a closed test server |
+game_alias competitive | Sets the mode before the first map loads |
+map de_dust2 | The first map. The server idles without one |
+sv_setsteamaccount | Your Game Server Login Token |
+exec autoexec.cfg | Runs a config once at startup, before any map |
The token is the one people get wrong. sv_setsteamaccount has to be on the launch line, not in server.cfg, because the server logs in to Steam before it loads a map and therefore before it reads any config. Set it in both places and they will disagree. Valve issues the token to a Steam account that owns the game, one per server, and it is yours rather than your host's - Steam game server tokens explained covers creating one for app 730 and what gets a token banned. Without a token the server still runs and still accepts direct connections; it just does not appear in the public browser.
Game modes, and the map group#
CS2 keeps the CS:GO scheme of two integers. game_type picks the family, game_mode picks the variant inside it, and game_alias sets both from a name.
| Alias | game_type | game_mode | Mode |
|---|---|---|---|
casual | 0 | 0 | Casual |
competitive | 0 | 1 | Competitive, MR12 |
wingman | 0 | 2 | Wingman, 2v2 |
armsrace | 1 | 0 | Arms Race |
demolition | 1 | 1 | Demolition |
deathmatch | 1 | 2 | Deathmatch |
custom | 2 | 0 | Custom, for plugin-driven modes |
Setting the alias on the launch line is the reliable way in, because changing game_type or game_mode live needs a map change to take effect, and half-applied modes produce the strangest bugs you will ever debug. If you are running a plugin that implements its own rules - retakes, a deathmatch plugin, an arena mode - custom is the family that leaves the game rules alone for it.
Map rotation has two layers. The engine layer is mapcycle.txt in game/csgo/, one map name per line, read through the mapcyclefile cvar, plus changelevel <map> to move now and mp_match_end_changelevel 1 to advance when a match finishes. The Valve layer above it is gamemodes_server.txt, a KeyValues file you create from the gamemodes_server.txt.example that ships beside it; it defines map groups and lets you set convars per game mode in one place. Community servers with a vote system usually ignore both and let the plugin drive, which is covered in CS2 plugins with Metamod and CounterStrikeSharp.
Workshop maps load by id rather than by name:
host_workshop_map 3070596702ds_workshop_changelevel de_cacheThe first downloads and loads a single workshop map. Loading a whole collection has needed a Steam Web API key at various points in CS2's life and the requirement has moved more than once, so check the current behaviour before you build a rotation on it. A single-map server is unaffected.
Bots fill a mode that would otherwise be one person standing in spawn. bot_quota 8 with bot_quota_mode fill keeps the server at eight total players and removes bots as humans arrive; bot_quota_mode normal adds eight bots regardless. bot_difficulty takes 0 to 3, bot_kick clears them all, and bot_stop 1 freezes them for a practice session. Bots on a community server are a presentation choice rather than a technical one: a browser entry showing 2/10 gets skipped and one showing 8/10 gets clicked, and the people who join find bots. Decide which trade you want before someone else does.
server.cfg: the settings worth setting#
Here is a server.cfg with nothing decorative in it:
hostname "Longship 5v5 // EU"rcon_password "a-long-random-string"sv_password ""sv_lan 0sv_region 3// Networksv_maxrate 0sv_minrate 196608sv_hibernate_when_empty 1sv_hibernate_postgame_delay 30// Voice and chatsv_full_alltalk 0sv_deadtalk 1// Safetysv_cheats 0sv_allow_votes 1mp_endmatch_votenextmap 1// Logginglog onsv_logfile 1sv_logecho 1sv_logbans 1// GOTVtv_enable 1tv_port 27020tv_autorecord 1tv_delay 0| Cvar | Notes |
|---|---|
hostname | The browser name. Put the region in it, people filter on it |
rcon_password | Long and random. Empty means RCON is off, not open |
sv_password | Non-empty makes the server private |
sv_lan 0 | 1 skips Steam authentication. A private server, not a hidden one |
sv_region | Browser region: 0 US East, 3 Europe, 4 Asia, 255 world |
sv_minrate | Floor on a client's bandwidth. Stops a throttled client hurting itself |
sv_hibernate_when_empty | Drops CPU use to nothing when nobody is on |
sv_full_alltalk | Everyone hears everyone, both teams, alive or dead |
sv_visiblemaxplayers | Shows a lower slot count than you have, for reserved slots |
sv_cheats | Must be 1 for practice commands. Never on a public server |
sv_hibernate_when_empty 1 is worth a sentence of its own. An idle CS2 server with hibernation on uses almost no CPU, which matters when your plan buys a share of a core rather than a whole one. The cost is that GOTV disconnects while hibernating and any plugin doing work on a timer stops, so a match server that records demos between rounds wants it off and a community server wants it on.
The voice cvars were reorganised between CS:GO and CS2 and the old sv_alltalk is not the lever any more. If you are following a CS:GO guide and a cvar does not exist, the console says so plainly - see the find command below.
sv_visiblemaxplayers is the reserved-slot trick and it is worth knowing because it needs no plugin. Buy twelve slots, set sv_visiblemaxplayers 11, and the browser shows the server as full at eleven while the twelfth stays free for whoever you let in. It only hides the slot; enforcing who gets it needs a plugin that kicks the lowest-priority player. On a small community server the hidden slot alone solves the actual problem, which is an admin unable to join their own full server to deal with someone.
Round, money and match cvars#
These are the mp_ ones, so they go in gamemode_competitive_server.cfg (or the file matching whatever mode you run). The values below are a standard competitive setup.
mp_maxrounds 24mp_overtime_enable 1mp_overtime_maxrounds 6mp_overtime_startmoney 12500mp_halftime 1mp_match_can_clinch 1mp_maxmoney 16000mp_startmoney 800mp_afterroundmoney 0mp_freezetime 15mp_roundtime 1.92mp_roundtime_defuse 1.92mp_roundtime_hostage 1.92mp_buytime 20mp_buy_anywhere 0mp_friendlyfire 1mp_solid_teammates 1mp_death_drop_gun 1mp_death_drop_grenade 2mp_autoteambalance 0mp_limitteams 0mp_warmuptime 60mp_warmup_pausetimer 0mp_timelimit 0| Cvar | Meaning |
|---|---|
mp_maxrounds | Rounds in regulation. 24 is MR12, CS2's competitive length |
mp_overtime_maxrounds | Rounds per overtime. 6 is MR3 |
mp_halftime | Swap sides at the half. Off makes a one-sided match |
mp_match_can_clinch | End the match once a score is unreachable |
mp_roundtime_defuse | Round length in minutes. 1.92 is 1:55 |
mp_freezetime | Buy and talk time before a round starts |
mp_buytime | Seconds the buy menu stays open after freezetime |
mp_maxmoney | Money ceiling. 16000 is the competitive value |
mp_death_drop_gun | 0 nothing, 1 best weapon, 2 current weapon |
mp_free_armor | 0 none, 1 kevlar, 2 kevlar and helmet, free each round |
mp_autoteambalance | Off for any match. On for casual servers that fill unevenly |
mp_timelimit | Minutes per map. 0 means rounds decide it |
mp_roundtime is the fallback and the two specific ones win on the map types they name, so set all three or you will get 1:55 on defuse maps and something else on hostage maps. Warm-up is ended with the mp_warmup_end command rather than by waiting, and mp_warmup_pausetimer 1 freezes the warm-up clock indefinitely, which is how a match server waits for ten people to turn up.
Team names for a scrim are mp_teamname_1 and mp_teamname_2, with mp_teamflag_1 and mp_teamflag_2 taking two-letter country codes. They show in the scoreboard and in GOTV. The whole match-server arrangement, including a knife round and demo handling, is in a CS2 competitive match server.
Tick rate and sub-tick#
CS2 servers run at 64 tick unless you pass -tickrate 128. What that changes is smaller than it was in CS:GO, and it is worth understanding why before you pay for it.
Source 2 timestamps player inputs with the moment they happened rather than the tick they arrived in, so shooting and movement are evaluated at sub-tick resolution on a 64 tick server. Hit registration, which was the whole argument for 128 tick in CS:GO, is largely tick-independent now. What is still tick-bound is anything simulated per tick: grenade physics, the exact frames of a jump-throw, and the resolution of anything a plugin does in a tick handler. A 128 tick server also produces noticeably heavier GOTV demos.
The cost is roughly double the CPU per player. On a plan that buys a fixed share of a core that is a real constraint rather than an abstraction, and a 128 tick server at its CPU limit is worse than a 64 tick server that never reaches it. What tick rate actually means goes through the measurement; the short version for CS2 is to run 64 for a community server and 128 only for a competitive one where people will argue about jump-throws.
Rate cvars are simpler than they were. sv_minrate and sv_maxrate cap the bytes per second per client, with 0 for no maximum, and the CS:GO sv_maxcmdrate and sv_maxupdaterate pair no longer applies the way old guides describe. Leave rates alone unless you have measured a problem. Roughly 60 to 120 KB/s per player is normal for CS2.
RCON, kicks and bans#
RCON runs over TCP on the game port, needs -usercon on the launch line and a non-empty rcon_password. From a client console:
rcon_address 203.0.113.10:27015rcon_password a-long-random-stringrcon statusThe panel console is the safer route, because it is authenticated by your panel account instead of by a password that travels with every command, and it does not need the port exposed at all. RCON over the internet is a plaintext protocol - using RCON safely is short and worth the two minutes.
| Command | What it does |
|---|---|
status | Players, their user ids, Steam ids, ping and the current map |
users | Shorter player list |
kick <name> | Removes a player by name |
kickid <userid> <reason> | Removes by the id status printed. Reliable with odd names |
banid <minutes> <userid> | Ban. 0 minutes is permanent |
banip <minutes> <ip> | Address ban |
writeid | Saves id bans to banned_user.cfg |
writeip | Saves address bans to banned_ip.cfg |
removeid / removeip | Lifts one entry |
changelevel <map> | Changes map, keeping players connected |
mp_restartgame 1 | Restarts the game after one second |
mp_warmup_end | Ends warm-up now |
mp_pause_match / mp_unpause_match | Freezes and resumes play |
exec <file> | Runs a config from game/csgo/cfg/ |
say <text> | Speaks in chat as the server |
Engine bans are thin: they are stored in a flat file, they need writeid or they vanish on restart, and they carry no reason, no expiry you can read back and no shared list between servers. For anything more than throwing one person out, a plugin with a database behind it is the answer, and that is the main reason community CS2 servers install CounterStrikeSharp at all.
Logging and finding a cvar you half-remember#
log on plus sv_logfile 1 writes to game/csgo/logs/, one file per session, with connections, kills, chat and admin actions. sv_logecho 1 mirrors it into the console, which is what you want on a panel where the console is the thing you actually look at. sv_logbans 1 records bans in the same stream so you can answer "who banned them and when" six weeks later.
CS2 ships log forwarding over HTTP with logaddress_add_http "http://10.0.0.5:8080/", which is not the CS:GO UDP logaddress_add that older stats tools expect. If you are wiring up an external stats service, check which of the two it speaks before you spend an evening on a firewall rule.
Two console commands save more time than any guide:
find alltalkhelp mp_maxroundsfind <text> lists every cvar and command whose name or help text contains the text, with its current value. help <cvar> prints the description and the default. Between them you can settle any "does this cvar still exist in CS2" question in five seconds, which matters because a great deal of the CS2 advice on the internet is CS:GO advice with the numbers changed. Reading the console covers what else is worth watching in that output.
Troubleshooting#
The server does not appear in the browser. Almost always the token: no sv_setsteamaccount, a token that has been revoked, or the same token on two servers. Check the startup log for the Steam login lines. Direct connection working while the browser listing does not is the signature of a token problem, not a network problem.
RCON refuses the password. Confirm -usercon is on the launch line. Without it the server never opens the RCON listener and every password is wrong. Then confirm you are pointing at the game port over TCP - the same number as the UDP game port.
A cvar reverts after every round or map. The game mode config is resetting it. Move it into gamemode_<mode>_server.cfg.
`mp_maxrounds` has no effect. Either mp_timelimit is non-zero and ending the map first, or the mode is not competitive. Check game_type and game_mode with status and a find game_mode.
Players connect and drop immediately. Check sv_lan is 0, and check the log for VAC or Steam authentication errors. A server started with -insecure will not authenticate clients normally.
The console is full of "unknown command". A CS:GO config on a CS2 server. Work through it with find; roughly one cvar in ten changed name or disappeared.
High CPU with nobody on. sv_hibernate_when_empty is 0, or a plugin is holding the server awake. Watch the CPU graph across an empty period rather than guessing.
FAQ#
Where is server.cfg on a CS2 server?
game/csgo/cfg/server.cfg, inside the install directory. Note the doubled path: the CS2 tree has a game folder and the mod folder inside it is still called csgo. It is executed on every map load, so a config change takes effect on the next map without a restart.
Why does my CS2 server reset mp_ settings?
Because the game mode config runs after server.cfg and sets the same cvars. Put mp_ values in game/csgo/cfg/gamemode_competitive_server.cfg - the _server variant is Valve's supported override file and survives updates.
Is 128 tick worth it in CS2?
For a competitive server where people practise grenade line-ups, yes. For a community server, no. Sub-tick input timing removed most of the hit-registration argument, and 128 tick costs roughly twice the CPU per player.
Do I need a GSLT for a private CS2 server?
Only for the public browser. Without a token the server runs and friends can connect by address, which is enough for a private group. With a token it is listed, and the token must be yours and used on one server at a time.
How do I make one player an admin?
There is no engine concept of an admin in CS2 beyond the RCON password. Giving someone limited powers - kick, map change, mute - means installing Metamod:Source and a plugin framework that has an admin file with per-player flags.
How many players can a CS2 server hold?
Up to 64 with -maxplayers_override, but the practical answer is the mode. Competitive is 10, Wingman 4, casual 10 to 20 and deathmatch 16 to 24. Past about 24 the CPU cost per player and the map sizes stop making sense together.




Comments
Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.