FastDL Setup: sv_downloadurl with Nginx or Apache

September 24, 2025 Daemon666 8 min read 11 Aufrufe

Without FastDL, custom content downloads through the game server at a crawl — a few KB/s over the old UDP transfer, so a 20 MB map map-change empties the server. FastDL moves those transfers to a normal HTTP server via sv_downloadurl. The setup is not hard, but one detail — where exactly the URL points relative to the cstrike folder — accounts for the overwhelming majority of "FastDL not working" reports.

1. How it works

When a client joins and is missing a file the server references (a map, model, sound, sprite), it fetches that file over HTTP from sv_downloadurl instead of the game channel. Your web server just serves static files; the client reconstructs the path from the game-relative filename.

2. Set the server cvars

// server.cfg
sv_allowdownload 1
sv_allowupload 1
sv_downloadurl "http://dl.example.com/cs"

sv_allowdownload 1 lets clients download at all; without it they join with missing textures and errors. Clients also need cl_allowdownload 1 on their end (the default), so you cannot fix a client that disabled it.

3. Get the path right (the part everyone breaks)

The engine builds the download URL as sv_downloadurl + the game-relative path, and that path includes the cstrike/ folder. So if a client needs cstrike/maps/de_rats.bsp and your sv_downloadurl is http://dl.example.com/cs, it will request:

http://dl.example.com/cs/cstrike/maps/de_rats.bsp

Therefore your web root must contain a cstrike/ directory that mirrors the server's, not the contents of cstrike/ dumped loose. The correct layout on the web host:

/var/www/fastdl/          <- sv_downloadurl points here (http://dl.example.com/cs)
  cstrike/
    maps/
      de_rats.bsp
    sound/
    models/
    sprites/
    gfx/
    overviews/

If you point the URL inside cstrike you get a doubled or missing segment and every download 404s. This is the single most common mistake; see FastDL not working for the diagnostic version.

4. Add bzip2 compression

The engine can fetch a bzip2-compressed copy and decompress it client-side, which roughly halves map transfer size. For each file, place a .bz2 alongside it:

cd /var/www/fastdl/cstrike/maps
bzip2 -k de_rats.bsp        # produces de_rats.bsp.bz2, keeps the original

The client requests de_rats.bsp.bz2 first and falls back to the plain file if it is absent. Compress the big content — maps, models, sounds. Keep the uncompressed files too; some clients still ask for them.

5. Nginx configuration

server {
    listen 80;
    server_name dl.example.com;
    root /var/www/fastdl;

    location / {
        autoindex off;
        # serve unknown types as raw bytes so .bsp/.bz2 download cleanly
        default_type application/octet-stream;
        types {
            application/octet-stream bsp bz2 mdl spr wav;
        }
    }
}

Turn autoindex off so the mirror is not browsable, and make sure the server sends the files rather than trying to interpret them.

6. Apache configuration

<VirtualHost *:80>
    ServerName dl.example.com
    DocumentRoot /var/www/fastdl

    <Directory /var/www/fastdl>
        Options -Indexes
        Require all granted
        AddType application/octet-stream .bsp .bz2 .mdl .spr .wav
    </Directory>
</VirtualHost>

HTTPS works fine for sv_downloadurl and is worth it; just make sure the certificate is valid, because a TLS error makes the client silently fall back to the slow in-game transfer.

7. Keep the mirror in sync

The web mirror is a separate copy of your content, and it drifts. Every time you add a map to the rotation or install a new model pack, the same files must land on the FastDL host, or clients download everything except the new content and join with missing textures. The lowest-friction fix is to make the mirror the same filesystem — bind-mount or symlink cstrike/maps, cstrike/sound and the rest into the web root — so there is only one copy to maintain. If the mirror is a different machine, script an rsync after every content change and re-run bzip2 -k on new files. A stale mirror is the second most common FastDL failure after the path mistake, and it is entirely self-inflicted.

Common errors

  • Every download 404s — the cstrike/ level is missing or doubled in your web root. The client requests <url>/cstrike/maps/...; that exact path must resolve.
  • Downloads are still slowsv_downloadurl is empty or unreachable and the server fell back to the UDP transfer. Test the URL in a browser.
  • Files download but are corrupt — the web server rewrote or compressed them (gzip on the fly, an HTML error page served with a 200). Serve as application/octet-stream and confirm the byte size matches.
  • .bz2 ignored — wrong filename (de_rats.bz2 instead of de_rats.bsp.bz2) or the web server refuses the extension. The compressed name is the full original name plus .bz2.
  • Client gets missing textures anywaysv_allowdownload 0 on the server, or the file is not actually on the mirror.

Verification

Open the exact URL of one map in a browser and confirm it downloads with the right size:

http://dl.example.com/cs/cstrike/maps/de_rats.bsp

Then join the server from a client that does not have that map and watch it pull over HTTP in seconds rather than minutes. A clean test is to delete a map locally, connect, and confirm it re-downloads fast. Pair this with a well-ordered mapcycle so the mirror always holds every map you rotate.

Mitwirkende: Daemon666 ✦
Teilen: