Install the server and open the ports
The dedicated server is Steam app 4020, and SteamCMD downloads it with an anonymous login, so no Steam account is needed for the files. Running the same command again later updates the server, and adding validate checks every file. Facepunch notes that force_install_dir can cause problems on updates, so if an update fails, try installing into a fresh folder.
On Windows you start srcds.exe; on Linux you start srcds_run with -game garrysmod. Facepunch's Linux page points out that srcds_run brings the server back if it crashes, but not after the machine reboots or the terminal closes, so on a machine of your own you still need something that starts it at boot.
The server uses the standard Source ports. Valve lists 27015 over TCP and UDP for game traffic, pings and RCON, changeable with -port, plus 27005 UDP as the client port and 26900 UDP for outgoing Steam traffic. 27020 UDP is only for SourceTV. At home, forward 27015 on your router and allow it through the firewall.
There is also an x86-64 beta branch of the server. Switch to it with -beta x86-64 on the app_update line. Facepunch warns that simply removing -beta later is not enough, because SteamCMD keeps updating to the last branch you chose, so return to the normal build with -beta public.
- Install or update: steamcmd +login anonymous +force_install_dir ./gmodds +app_update 4020 validate +quit
- Start on Linux: ./srcds_run -game garrysmod +maxplayers 16 +gamemode sandbox +map gm_construct +sv_setsteamaccount YOURTOKEN
- Ports: 27015 TCP and UDP for the game and RCON, 27005 UDP client, 26900 UDP outgoing
- Back to the normal branch from a beta: app_update 4020 -beta public validate
The Game Server Login Token, and why the browser needs it
Since the May 2020 update, Facepunch says every Garry's Mod server should have a Game Server Login Token, and servers without one suffer a severe penalty in server list ranking. The token also gives the server a static Steam identity, helps players find it again if its IP address changes, and keeps fake servers out of the list. Facepunch's setup page calls it mandatory.
Create it on Steam's game server account page. The field labelled App ID of the base game must be 4000, which is Garry's Mod itself, not 4020, which is the dedicated server. Steam's own requirements are that your account is not community banned, locked or limited, has a qualifying phone number, and owns the game. Then add +sv_setsteamaccount followed by the token to the launch line and restart.
Each server needs its own token. Facepunch documents three failures worth recognising: an invalid or expired token stops the server from starting, two servers sharing a token print Connection to Steam servers lost (Steam error code 6) and disconnect players, and changing your Steam password invalidates every token you own, so each one must be regenerated on the same page.
- Create the token at steamcommunity.com/dev/managegameservers with app id 4000
- One token per server, with a memo so you can tell them apart
- Use +hide_server 1 on a development server you do not want listed
server.cfg essentials
The main config file is garrysmod/cfg/server.cfg. Valve's documentation says server.cfg runs when a dedicated server starts and again every time the map changes, so anything you put there is reapplied on each map. One exception: Facepunch notes that server.cfg runs too late for sv_lan, which has to be set on the command line before the server starts.
Keep the file to the settings you actually change. The server name, passwords and location matter on every server, and the rest depends on your gamemode.
- hostname "My Server": the name shown in the server browser
- sv_password "": a join password, empty for a public server
- rcon_password "long-random-string": the remote console password; leave it unset if you do not use RCON
- sv_location eu: the flag shown in the browser, an ISO 3166-1 alpha-2 code or eu; Facepunch's operator rules ask for a correct location
- sv_allowcslua 0: stops clients running their own clientside Lua addons, and overrides any gamemode setting
- sv_loadingurl "https://...": a custom loading screen, which must start with http:// or https://
- sv_downloadurl "https://...": your FastDL web server, if you use one
- sbox_maxprops and the other sbox_max settings: per-player limits on props, ragdolls, vehicles and other spawnables
Gamemodes: Sandbox, TTT and DarkRP
The gamemode is chosen with +gamemode followed by the gamemode's folder name, as it appears in garrysmod/gamemodes or inside an addon. The map is chosen with +map and the map's file name without .bsp. To switch either on a running server, set the gamemode convar and then run changelevel with a map, which also reloads the current one.
Sandbox and Trouble in Terrorist Town ship with the game. Sandbox's folder is sandbox. TTT's folder is terrortown, and its maps use the ttt_ prefix. TTT was created by Bad King Urgrain: a few players are secretly Traitors and everyone else has to work out who before they are killed.
DarkRP is a separate roleplay gamemode, built on Sandbox and maintained by FPtje on GitHub. Its README asks you to get it either with git or from the Workshop, item 248302805, and not by manual download. Its folder name, and so its +gamemode value, is darkrp. Do not edit DarkRP's own files. Customisation goes into the separate DarkRP modification addon, placed in garrysmod/addons, which holds the settings, jobs, shipments, entities and the MySQL configuration, so a DarkRP update never overwrites your changes.
- Sandbox: +gamemode sandbox +map gm_construct
- TTT: +gamemode terrortown with a ttt_ map
- DarkRP: add Workshop item 248302805 to your collection, or clone the repository into garrysmod/gamemodes/darkrp, then +gamemode darkrp
- DarkRP settings: lua/darkrp_config/settings.lua in the darkrpmodification addon
- DarkRP jobs: lua/darkrp_customthings/jobs.lua in the same addon
Workshop collections and getting content to players
Add +host_workshop_collection followed by a collection id to the launch line, and the server downloads the collection at startup, mounts every addon in it and checks for updates on each restart. The collection must be public or unlisted, or the server cannot read it. Collections can be nested, and sub-collections are downloaded too. Since version 2026.09.22 you can also list addon ids in cfg/srcds_workshop_ids.txt, instead of or alongside a collection. Older tutorials add a Steam Web API key with -authkey; Facepunch's current guide asks only for the collection id.
If an addon update ever brings unwanted or malicious changes, host_workshop_autoupdate 0 stops updates at startup. Facepunch warns of the cost: a map updated on the Workshop but not on your server can stop players joining.
Mounting is not the same as sending content to players. The server only marks two things for client download automatically: the current map, when it is in the collection, and the gamemode, when its .txt file names a Workshop id. Everything else players must see, such as models, materials and sounds, needs marking. Lua files are not content and reach players through a separate process.
- WorkshopDL, the fastest: upload content to the Workshop and call resource.AddWorkshop("id") from a file in garrysmod/lua/autorun/server/
- FastDL: a separate web server set with sv_downloadurl, files marked with resource.AddFile; clients try a .bz2 copy first
- ServerDL: downloads from the game server itself at a 64 kb/s limit; Facepunch calls it obsolete and warns that sv_allowdownload lets modified clients spam requests and lag the server
- Only mark addons that contain more than Lua: marking Lua-only addons lengthens join times for nothing
Mounting Counter-Strike: Source content
Many community maps use Counter-Strike: Source textures and models. A server mounts them through garrysmod/cfg/mount.cfg, which points a game key such as cstrike at a folder on disk. Garry's Mod then marks that game as mounted, which addons can check.
The content itself comes from the Counter-Strike: Source dedicated server, Steam app 232330, which SteamCMD downloads with an anonymous login. Facepunch's advice is to install it into its own folder and never into your Garry's Mod server directory, because doing so overwrites the server's files and breaks it. One shared content folder can serve several servers, and the server's user only needs read access to it.
- Download: steamcmd +login anonymous +force_install_dir ../content/css +app_update 232330 validate +quit
- mount.cfg: "mountcfg" { "cstrike" "/home/steam/content/css/cstrike" }
- No trailing slash on the path, as the comments in the shipped mount.cfg say, and Linux paths are case-sensitive
- Restart the server after editing mount.cfg
Admins with ULX, then performance and tickrate
ULX is the long-standing admin mod for Garry's Mod, and it needs ULib, a library from the same team. Install both, from the Workshop (ULX is 557962280, ULib is 557962238) or by extracting them into garrysmod/addons. Both projects stress that you must fully restart the server after installing: a map change is not enough. Then give yourself rank from the server console with ulx adduser followed by your name and superadmin. In game, ulx menu opens the interface and chat commands start with an exclamation mark.
The server's target tickrate is set with -tickrate on the command line. Facepunch gives the default as 66.6666 and recommends values between 30 and 128. A higher tickrate means more simulation work every second, so leave the default unless your gamemode benefits, and check the server keeps up with a full player count before you keep the change.
Most performance problems come from content and scripts rather than settings. Keep the collection to what the server uses, cap building on Sandbox with the sbox_max limits, and treat every addon as code running on your server. Facepunch also publishes server operator rules, and breaking them gets a server blacklisted from the list.
- ULX and ULib: Workshop 557962280 and 557962238, then a full restart
- Make yourself superadmin: ulx adduser YourName superadmin
- Tickrate: set with -tickrate on the launch line, default 66.6666, recommended range 30 to 128
- Updates: stop the server and run the same SteamCMD app_update 4020 line