Almost every dedicated server you can rent, and every one you can run at home, was installed by the same small command-line program. Knowing what SteamCMD is doing makes the difference between an update that takes four minutes and an evening spent reinstalling.
What SteamCMD is
SteamCMD is the Steam client with the shop, the friends list, the overlay and the graphics removed. What is left is the part that downloads and verifies files, driven by typed commands instead of a window.
It exists because dedicated server binaries are distributed through Steam like everything else, and a headless Linux box cannot run the normal client. Valve publishes it and documents the commands on the SteamCMD page of the Valve developer wiki, which is the reference worth bookmarking rather than trusting a forum post from 2019.
The core of it is three commands:
login anonymous
force_install_dir /path/to/server
app_update <appid> validate
That is genuinely most of it. Everything else in a hosting panel's "reinstall" button is a wrapper around those lines.
App IDs, and the two-number problem
Every Steam product has a numeric App ID. The thing that catches people out is that a game and its dedicated server are usually different products with different IDs.
| Game | Game App ID | Dedicated server App ID |
|---|---|---|
| Counter-Strike 2 | 730 | 730 |
| Team Fortress 2 | 440 | 232250 |
| Garry's Mod | 4000 | 4020 |
| Left 4 Dead 2 | 550 | 222860 |
| Rust | 252490 | 258550 |
| ARK: Survival Evolved | 346110 | 376030 |
| 7 Days to Die | 251570 | 294420 |
| Valheim | 892970 | 896660 |
Install 440 on a server and you have downloaded the client, which will not run headless and is several gigabytes of assets you do not need. It is the single most common wasted hour in self-hosting, and the error it produces is unhelpful because nothing has technically failed.
Anonymous login works for most dedicated servers and not all. Some require an account that owns the game — historically Left 4 Dead 2 and a handful of others. If login anonymous gives you an access-denied on app_update, that is the reason, and no amount of retrying changes it.
What validate actually does
app_update 740 validate checks every file against Valve's manifest and re-downloads whatever does not match. It is the closest thing to a repair tool the platform has.
It is also slower than a plain update, sometimes dramatically, because it reads every file on disk. On a large game on a slow disk that is real minutes. The habit worth forming:
- Routine update after a patch: no
validate - Something is broken and you do not know why:
validate - First install:
validate, because a truncated download is invisible until it is not
The failure validate fixes best is the one where a server updated during a network hiccup and now has one corrupt file that crashes it on a specific map. Nothing in the logs points at a file; validation just quietly replaces it.
Betas and why your server is on the wrong branch
Some games ship server updates to a public beta branch before the default one. The syntax is app_update <appid> -beta <branchname>, and if a branch has a password, -betapassword.
This matters more than it sounds because clients and servers have to match. A game that pushes a client update to everyone while the server binaries sit on a beta branch produces a fleet of servers that no one can join, for as long as it takes operators to notice. When a game updates and your player count goes to zero within the hour, check the branch before you check anything else — and expect to see the same thing happen across every list at once, because it is affecting everybody.
To leave a beta and go back to the default branch, -beta with an empty value, or delete the .acf manifest and reinstall. The former usually works; the latter always does.
Automating it without breaking things
The obvious script is a cron job that runs app_update nightly. The obvious script is also how servers end up half-updated with players connected.
Three rules that hold up:
Stop the server first. SteamCMD will happily rewrite binaries under a running process. What happens next varies from nothing to a crash on the next map change, and the second one is hard to diagnose a week later.
Check whether an update exists before stopping anything. Taking a populated server down nightly to discover there was no patch is a self-inflicted uptime problem. app_info_print <appid> gives you the current build ID, and comparing that against the installed one in steamapps/appmanifest_<appid>.acf tells you whether the stop is warranted.
Announce it. A restart with thirty seconds of warning in chat costs you nothing and keeps players who would otherwise assume the server crashed. This is the same argument as scheduled events: predictable beats invisible.
Disk, and the thing nobody budgets for
force_install_dir sets where the files go. What it does not do is set where the temporary files go during a download, and SteamCMD writes a working copy before it commits.
A game whose server files are 12 GB can need substantially more than 12 GB free to update. On a VPS sized exactly to the installed footprint — which is a common way to save a few euros — the update fails partway, leaves a mixed state, and the fix is a validate that needs the same headroom you did not have.
Budget disk with the update in mind, not the install. It is the cheapest part of the spec and the one that fails most annoyingly. The rest of what is worth spending on is covered in what actually matters in server hardware.
The bit hosting panels hide
Every "Reinstall" and "Update" button in a control panel is running these commands with arguments you cannot see. That is fine until it is not — until the panel updates to the default branch when you needed a beta, or validates when you needed speed, or installs the client App ID because whoever wrote the template copied it from a wiki.
If your panel gives you SSH or a console, running the three commands by hand once is worth doing, purely to know what the button was doing. It is also the only way to read the actual error when the button says "Failed" and offers nothing else. Panels differ enormously here, which is one of the things worth checking before you commit — see dedicated versus VPS versus shared hosting for what each tier typically gives you access to.
The short version
One tool, one login, one command with an App ID. The ID for the server is usually not the ID for the game, validate is a repair tool rather than a routine, betas are the reason a fleet suddenly empties, and updates need more disk than installs.
None of it is complicated. All of it is the kind of thing that costs an evening exactly once, and then never again.
Published · 6 min read