Back to Blog

How to Set Up a Cache Server

A caching proxy for your FiveM server dramatically reduces loading times for returning players and offloads asset bandwidth from your main game server. This guide covers the full nginx setup on a Linux VPS - the standard solution that even works for a Windows FiveM server - plus the matching server.cfg config.

When players connect to your FiveM server, they download all your custom resources (scripts, models, sounds, textures) from the FXServer. On a server with 200+ resources this can easily mean 1-5 GB of downloads per player. A caching proxy fronts your FXServer with nginx, caches every asset once, and serves it from the cache for every subsequent player - way faster than FXServer's built-in file delivery.

Our recommended FiveM hoster

For the CPU performance and DDoS protection FiveM needs, we recommend Avoro — German-based, Ryzen 9 7950X3D nodes, always-on DDoS, real unmetered traffic. See our FiveM hosting comparison.

Why Run a Cache Server?

FXServer's built-in HTTP server was never designed for concurrent high-bandwidth asset delivery. At 80+ players connecting in waves (server restart, big update) it becomes a serious bottleneck. nginx, on the other hand, is purpose-built for this and serves cached files at line-rate.

Pros of a Cache Server

  • Massively faster asset downloads for returning players (cached on the proxy)
  • Removes asset bandwidth load from the main FXServer
  • Optional DDoS layer - the proxy IP is what players see, not your game server
  • Works for both Windows and Linux FiveM servers (the cache itself runs on Linux nginx)
  • Pairs well with Cloudflare for an extra edge cache layer

Cons of a Cache Server

  • Extra monthly cost (around 5-10€ for a small Linux VPS)
  • You must clear the cache manually before restarting/updating resources
  • Requires basic nginx/Linux command-line knowledge
  • Adds one more moving part to your infrastructure

When Should You Set This Up?

If your server has fewer than 30 players and small resource folder, you can skip this. From 50+ players or a resource folder over 500 MB, a cache server starts paying off. At 100+ players it's basically mandatory if you care about connect times.

1. Cache Server Hardware

A caching proxy is mainly bound by network bandwidth and disk I/O. CPU and RAM requirements are modest. The disk just needs enough space to hold your full resource collection at least 2x over.

Cache server specs by player count
Up to 100 players:   1 vCPU · 2 GB RAM · 40 GB SSD · 1 Gbps
Up to 250 players:   2 vCPU · 4 GB RAM · 80 GB SSD · 1 Gbps
500+ players:        4 vCPU · 8 GB RAM · 160 GB SSD · 1 Gbps

A Hetzner CX22 or CPX21 (around 5€/month, 1 Gbps uplink, unlimited traffic) is perfect for servers up to 150 players. Avoid hosters with metered traffic - asset delivery can easily push several TB per month on a busy server.

Put the cache server close to your FiveM server

The cache proxies traffic from your FiveM main server. If both are in the same datacenter or at least same region, fetches from origin are near-instant. Cross-continent setups will feel slow on cache-misses.

2. Install nginx on a Linux VPS

This guide uses a fresh Ubuntu 22.04 or 24.04 VPS. nginx 1.17+ is required for the stream module that handles UDP forwarding.

  1. SSH into the cache VPS

    From your terminal, replacing YOUR.CACHE.IP with the IP from your provider email:

    ssh root@YOUR.CACHE.IP
  2. Update the system

    apt update && apt upgrade -y
  3. Install nginx

    apt install -y nginx

    Verify the version is 1.17 or higher:

    nginx -v
  4. Create the cache directory

    mkdir -p /srv/cache
    chown -R www-data:www-data /srv/cache

3. Configure nginx as a Caching Proxy

Create a new site config that proxies /files/ requests to your FiveM main server and caches the responses for a year:

/etc/nginx/sites-available/fivem-cache
upstream backend {
  # Replace with your FiveM main server IP and port
  server YOUR.FIVEM.IP:30120;
}

proxy_cache_path /srv/cache levels=1:2 keys_zone=assets:48m
                 max_size=20g inactive=7d use_temp_path=off;

server {
  listen 80;
  listen [::]:80;
  server_name cache.yourdomain.com;

  # Forward standard HTTP requests (info.json, dynamic.json, etc)
  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_pass_request_headers on;
    proxy_http_version 1.1;
    proxy_pass http://backend;
  }

  # Cache all asset downloads
  location /files/ {
    proxy_pass http://backend$request_uri;
    add_header X-Cache-Status $upstream_cache_status;
    proxy_cache_lock on;
    proxy_cache assets;
    proxy_cache_valid 1y;
    proxy_cache_key $request_uri$is_args$args;
    proxy_cache_revalidate on;
    proxy_cache_min_uses 1;
  }
}

Enable the site and reload nginx:

ln -s /etc/nginx/sites-available/fivem-cache /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

Use a domain and SSL in production

The example above listens on port 80 (HTTP) for simplicity. For production you should point a subdomain (like cache.yourdomain.com) to your cache server, get a free Let's Encrypt certificate via certbot --nginx, and switch the listen blocks to 443 ssl http2.

4. Configure FXServer to Use the Cache

On your FiveM main server, edit server.cfg and add these lines:

server.cfg (additions)
# Random secret string - clients only download from your cache if they have this key
adhesive_cdnKey "REPLACE_WITH_RANDOM_32_CHAR_STRING"

# Tell clients to fetch all resource files from the cache, not FXServer directly
fileserver_add ".*" "http://cache.yourdomain.com/files"

Generate a strong random string for adhesive_cdnKey - this prevents random people from filling up your cache with junk requests. On Linux: openssl rand -hex 16.

The URL must NOT end with a slash

FiveM's docs are explicit on this. Use https://cache.yourdomain.com/files - NOT https://cache.yourdomain.com/files/. A trailing slash will break the cache.

5. Restart FXServer and Test

Restart your FiveM main server. Connect from your game client and watch the cache server logs to confirm hits:

tail -f /var/log/nginx/access.log

You should see lines with X-Cache-Status: MISS on first connection (downloading and caching) and HIT on every subsequent connection of the same player. Once one player has cached an asset, every other player gets it served instantly.

6. Clearing the Cache (Important!)

FiveM does not invalidate cache by file hash. If you update or restart a resource, you must manually clear the cache, otherwise players will keep downloading the old (cached) version.

Clear nginx cache
rm -rf /srv/cache/*
systemctl reload nginx

Tip: write a small shell script that does this and trigger it from your txAdmin "before resource restart" hook, or run it manually whenever you push updates.

7. Windows FiveM Servers

If your main FiveM server runs on Windows, the cache server itself should still be a Linux VPS with nginx - it's by far the easiest and most performant option. The cache server just needs to be able to reach your Windows FiveM server on port 30120, that's the only requirement. Both servers can be in completely different datacenters as long as the network path between them is solid.

Native Windows caching alternatives

You could in theory run nginx on Windows or use IIS with output caching, but the community has converged on Linux + nginx for good reasons: better cache performance, better debugging tools, way more documentation. Stick with the standard setup unless you have a strong reason not to.

8. Pair with Cloudflare (Optional)

For an extra performance and DDoS layer, point your cache subdomain through Cloudflare. Create an A record cache.yourdomain.com → your.cache.ip with the orange-cloud proxy enabled, then add a cache rule:

  • URL: cache.yourdomain.com/files/*
  • Cache level: Everything
  • Edge TTL: 3 hours (or longer for stable resources)

Cloudflare's edge will cache asset chunks at their globally distributed PoPs - players nearest to a Cloudflare PoP download from there at near-zero latency, completely bypassing your origin cache.

9. Final Checklist

Before you call it done, walk through this:

  • Cache server has nginx 1.17+ installed and the config above deployed
  • Cache server firewall allows TCP 80 / 443 from the public internet
  • Cache server can reach FiveM main server on TCP 30120
  • nginx -t on the cache server returns "syntax is ok"
  • FiveM main server's server.cfg has both adhesive_cdnKey and fileserver_add set
  • FXServer restarted after config change
  • First test connection shows X-Cache-Status: MISS, second shows HIT

You're all set!

Returning players will now connect in a fraction of the time it used to take. First connection still requires downloading the assets once (to populate the cache), but every subsequent player gets the cached version.

Optimize your server further

Our scripts are built with the same performance-first philosophy. Browse the store.

Browse Store