Skip to content
Server Setup 11 min read

How to Set Up a Garry's Mod Server with Workshop Addons

Install Workshop addons on a Garry's Mod dedicated server using host_workshop_collection, an -authkey, and resource.AddWorkshop. Includes a working start script.

Getting Workshop addons onto a Garry's Mod dedicated server catches people out because there are two separate problems hiding behind one goal. The server has to mount the addons so they exist in the game world, and connecting players have to download them so they can see what the server is running. Different mechanisms handle each, and doing only the first is the classic mistake.

How GMod servers load addons

A dedicated server has no Steam client and no Workshop interface. It gets content three ways:

  • +host_workshop_collection <id> — at startup the server reads a Workshop collection, downloads every item in it, and mounts them. This is the main mechanism and what you will use for almost everything.
  • Files in garrysmod/addons/ — .gma files or extracted folders you place yourself. Useful for pinning a version or running something that is not on the Workshop.
  • resource.AddWorkshop() — this one does not install anything on the server. It tells clients to download an addon when they connect. This is the half people forget.

Mounting and client downloads are separate

A server can be running an addon perfectly while every player sees errors and missing models, because nothing told the clients to fetch it. If your server "works" but players report missing content, you have mounted without distributing.

Step 1: install the server with SteamCMD

Get SteamCMD first. On Linux:

# Linux
mkdir -p ~/steamcmd && cd ~/steamcmd
curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxvf -

On Windows, download the SteamCMD zip from Valve and extract it to something like C:\steamcmd.

Then install the Garry's Mod Dedicated Server. Note the app ID: the server is 4020, not 4000. App 4000 is the game you play; 4020 is the server binary.

./steamcmd.sh +force_install_dir ../gmod-server \
  +login anonymous \
  +app_update 4020 validate \
  +quit

Put +force_install_dir before +login — SteamCMD applies these in order, and reversing them installs to the default location instead of where you asked.

Step 2: build a Workshop collection

The server loads addons as a collection, not individually, so you need one collection containing everything the server should run.

  1. Go to the Garry's Mod Workshop and open Browse → Collections → Create Collection.
  2. Set visibility to Public or Unlisted. Private will not work — srcds cannot read it.
  3. Add every addon you want: gamemodes, maps, weapons, playermodels, tools.
  4. Copy the collection's ?id= number from its URL.

Unlisted is usually the right choice. The server reaches it by ID, and it stays out of public Workshop browsing.

Keep the collection small at first

Bring up a server with three or four addons and confirm the whole pipeline works before adding fifty. Debugging a broken mount is far easier when there are four candidates rather than fifty.

Step 3: get a Steam Web API key

To read a collection's contents the server calls Steam's Web API, and that call needs a key. If you skip this, the server console prints Fetching Workshop Addons.. No -authkey at startup and mounts nothing at all.

Request a key from Steam's community developer API key page while logged into your Steam account. Any domain will do for the registration field. You get a long hexadecimal string.

Treat the key as a secret

An API key is tied to your Steam account. Keep it out of public repositories, screenshots and pasted console logs. If you host with a provider that offers a key field in their panel, use that rather than embedding it in a script you might share.

Step 4: write the start script

On Linux, save this as start.sh in your server directory:

#!/usr/bin/env bash
# start.sh — Garry's Mod dedicated server

AUTHKEY="YOUR_STEAM_WEB_API_KEY"
COLLECTION="123456789"

./srcds_run \
  -game garrysmod \
  -console \
  -usercon \
  +maxplayers 24 \
  +gamemode sandbox \
  +map gm_construct \
  -authkey "$AUTHKEY" \
  +host_workshop_collection "$COLLECTION"

The Windows equivalent:

@echo off
REM start.bat — Garry's Mod dedicated server

set AUTHKEY=YOUR_STEAM_WEB_API_KEY
set COLLECTION=123456789

srcds.exe -game garrysmod -console -usercon ^
  +maxplayers 24 ^
  +gamemode sandbox ^
  +map gm_construct ^
  -authkey %AUTHKEY% ^
  +host_workshop_collection %COLLECTION%

What the flags do:

  • -game garrysmod — required; tells srcds which game to run.
  • -console — run in console mode rather than opening a window.
  • -usercon — enable RCON so you can administer remotely.
  • +maxplayers — slot count.
  • +gamemode — the gamemode folder name, e.g. sandbox, terrortown, darkrp.
  • +map — the starting map. It must be one the server actually has, either from the base game or from your collection.
  • -authkey — your Steam Web API key.
  • +host_workshop_collection — the collection ID.

Start it and watch the console. You should see the server fetching Workshop addons and mounting them. Lines mentioning that a Workshop map or gamemode is being made available for client download are the ones you want to see.

To pin the mounted versions and stop addons updating on restart:

host_workshop_autoupdate 0

Step 5: make clients download addons

Now the part that gets skipped. The collection mounts content on the server, and the server automatically marks the current map and the gamemode for client download. Nothing else is covered. Weapons, playermodels, props and tools all need to be declared explicitly.

Create garrysmod/lua/autorun/server/sv_workshop.lua:

-- garrysmod/lua/autorun/server/sv_workshop.lua
-- Tells connecting clients to download these addons from the Workshop.
-- Server-side mounting is handled separately by host_workshop_collection.

resource.AddWorkshop("105982362")
resource.AddWorkshop("128089118")
resource.AddWorkshop("128091208")

One resource.AddWorkshop() call per addon, using the addon's own Workshop ID — not the collection's. On connect, players are prompted to download those items from the Workshop before entering.

This is a Workshop-side transfer, so players get proper compressed downloads straight from Steam rather than crawling through the game's own file channel. It is the preferred route for anything published on the Workshop.

FastDL and why joins are slow without it

For content that is not on the Workshop — custom sounds, a map you compiled yourself, loose materials — the server falls back to its built-in file transfer, which is deliberately throttled and painfully slow. A player can sit on a loading screen for minutes.

FastDL fixes this by pointing clients at an ordinary web server holding the same files. Configure it in garrysmod/cfg/server.cfg:

// garrysmod/cfg/server.cfg
hostname "My Sandbox Server"
sv_password ""
rcon_password "change-this"

sv_allowdownload 1
sv_allowupload 0

// Point clients at a web host for faster asset transfer
sv_downloadurl "https://cdn.example.com/gmod/"
net_maxfilesize 64

The host at sv_downloadurl needs to mirror your server's folder layout — maps/, materials/, sound/ — and files are commonly stored bzip2-compressed to save bandwidth. Any static host works: a small VPS with nginx, or an object store with public read access.

Adding addons by file instead

Sometimes a collection is the wrong tool. You might need a version the author has since replaced, or an addon that was pulled from the Workshop, or you may simply want the server to boot without calling out to Steam at all.

In those cases, put the .gma directly into garrysmod/addons/ on the server. It gets mounted at startup exactly like collection content. Our guide on downloading Garry's Mod addons without Steam covers getting hold of the file, and extracting .gma files covers looking inside one before you trust it on a live server.

One caveat: a manually placed addon is invisible to clients. You still need resource.AddWorkshop() with its Workshop ID, or FastDL hosting the assets, or players will see missing content.

Troubleshooting

"No -authkey" in the startup log

The key is missing or malformed. Confirm -authkey uses a single dash (it is a launch parameter, not a console command, so it is not +authkey), and that the value is not wrapped in stray quotes from a copy-paste.

The collection downloads but addons do not appear

Check the collection is public or unlisted, and that it contains Garry's Mod items specifically — a collection can technically hold items for other games, which will be skipped. Also confirm the gamemode you set with +gamemode matches a folder that actually exists.

Players see missing textures and ERROR models

The classic mount-without-distribute problem. Add resource.AddWorkshop() entries for every content addon, restart, and reconnect with a fresh client.

The server starts on the wrong map or fails to find one

+map runs before Workshop content finishes mounting in some setups. Start on a base game map such as gm_construct and change to your custom map afterwards, either through RCON or a mapcycle.

An addon update broke everything

Set host_workshop_autoupdate 0 to freeze versions, then reintroduce addons one at a time to find the culprit. Keeping local .gma copies of critical addons is the reason version pinning matters.

Joins take several minutes

Content is going through the slow in-game transfer. Move Workshop items to resource.AddWorkshop() and everything else to a FastDL host.

Frequently Asked Questions

What app ID is the Garry’s Mod dedicated server?

The server is app 4020, which is separate from the game itself at app 4000. Install 4020 with SteamCMD; use 4000 only when downloading individual Workshop addons.

Why does my server say "No -authkey"?

The server needs a Steam Web API key to read a Workshop collection’s contents. Without it, srcds prints that message at startup and mounts nothing. Generate a key and pass it with -authkey on the command line.

Does host_workshop_collection make players download addons too?

Only partly. It mounts addons on the server, and it automatically marks the current map and gamemode for client download. Everything else — weapons, playermodels, props — needs resource.AddWorkshop so clients know to fetch it.

Does my collection have to be public?

It must be public or unlisted. A private collection cannot be read by the server, and the startup fetch will fail. Unlisted is the usual choice: reachable by ID, but not shown in Workshop browsing.

How do I stop addons updating and breaking my server?

Set host_workshop_autoupdate to 0 to freeze the mounted versions. This protects against a bad addon update, but it also means a map update on the client side can stop players joining, so treat it as a deliberate trade-off rather than a default.

Can I mix a collection with manually placed .gma files?

Yes. Files in garrysmod/addons are mounted alongside collection content. Just do not include the same addon both ways, or its content gets mounted twice, which causes conflicts that are painful to diagnose.

Why are players stuck on a long download when joining?

Without a FastDL host, assets transfer through the game’s own channel, which is deliberately rate-limited and very slow. Setting sv_downloadurl to an HTTP host that mirrors your content is the standard fix.

Summary

Install app 4020 with SteamCMD, bundle your addons into a public or unlisted collection, generate a Steam Web API key, and pass both -authkey and +host_workshop_collection on the command line. That gets the server running the content.

Then add a resource.AddWorkshop() call per addon in a server autorun file so players actually receive it, and put a FastDL host behind anything that is not on the Workshop. Mount and distribute are two jobs — do both and the server behaves.

Ready to download a Workshop item?

Paste any public Steam Workshop URL and get the item details in seconds. Free, no account, no Steam client needed.

Open the Downloader