# The FiveM server.cfg, line by line

> A complete, annotated FiveM server.cfg reference: endpoints, sv_licenseKey, OneSync, ACE permissions, resource start order and a working template.

Source: https://fam-tools.com/guides/fivem-server-cfg · FAM Tools · published 2026-02-03 · updated 2026-09-07 · about 14 min

**Short answer.** server.cfg is executed in order at startup. Put endpoints and convars first, ACE permissions second, resources third, and sv_licenseKey last so the server never starts half-configured.

server.cfg is read top to bottom, once, at start. That single fact explains most of the problems people have with it: a permission granted after the resource that needs it has already started does nothing, and a convar set after a resource has read it is ignored. This is the whole file, in the order it should be in.

## The order the file has to be in

FiveM does not parse server.cfg as a document. It executes each line as a console command, in sequence, the moment it reaches it. A resource started on line 40 cannot see a convar set on line 60, and a group granted a permission after that group has already been used will behave as though it never had it.

Keep the file in this order and an entire class of "it works on my other server" problems disappears.

1. **Endpoints and network** — endpoint_add_tcp / endpoint_add_udp, then sv_maxclients.
2. **Identity** — sv_hostname, sv_projectName, sv_projectDesc, tags, locale.
3. **Convars** — Everything a resource reads at start: OneSync, sv_scriptHookAllowed, custom convars.
4. **ACE permissions** — add_ace / add_principal, before the resources that check them.
5. **Resources** — ensure lines, framework first, dependants after.
6. **Licence key** — sv_licenseKey last, so a misconfigured server fails before it registers.

## Endpoints and player slots

FiveM needs both a TCP and a UDP endpoint on the same port. 0.0.0.0 binds every interface, which is what you want on a VPS; binding a specific address only makes sense when the machine has several and you want one of them.

sv_maxclients is capped by the OneSync mode you run. Thirty-two is where OneSync becomes compulsory, so without it the ceiling is 31. With OneSync Infinity the practical ceiling is 2048, but the number your hardware can actually carry is far lower and has nothing to do with this line.

```cfg
endpoint_add_tcp "0.0.0.0:30120"
endpoint_add_udp "0.0.0.0:30120"

sv_maxclients 48
```

> **The port has to be open twice** — A firewall rule for TCP 30120 alone gives you a server that appears in the list but that nobody can connect to — the game data itself is UDP. Open both, and remember that most VPS providers have a second firewall in their control panel on top of the one inside the machine.

## Identity: what players see in the server list

sv_hostname supports colour codes with ^0 to ^9. Use them sparingly — the server list strips some of them and a name that is 70% colour codes reads as noise. sv_projectName and sv_projectDesc appear in the connection screen and in the FiveM server browser detail panel.

Tags matter more than people expect: they are one of the few structured signals the server list has, and they feed the category filters players actually use.

```cfg
sv_hostname "^1High Life ^7| ^3Serious RP ^7| ^2Custom Minimap"
sets sv_projectName "High Life RP"
sets sv_projectDesc "Whitelisted economy roleplay, custom MLOs, EUP"
sets tags "roleplay, economy, whitelist, custom cars, qbcore"
sets locale "en-GB"
sets banner_detail "https://your-cdn/banner.png"
load_server_icon myLogo.png
```

> **note** — server_icon must be exactly 96 × 96 pixels and a PNG. Any other size is silently ignored and you get the default icon with no error in the console.

## OneSync: the setting that decides your ceiling

OneSync replaces the peer-to-peer state model with a server-authoritative one. It is the difference between a 32-slot server and a 128-slot server, and it is also what makes server-side entity creation, proper population control and reliable state bags possible.

There are three states you will see in guides, and only one of them you should use today.

```cfg
set onesync on
set onesync_population true
set onesync_enableInfinity true
set onesync_distanceCullVehicles true
set onesync_forceMigration true
```

*OneSync modes as of the current recommended artifacts.*

| Setting | Slots | When to use it |
| --- | --- | --- |
| onesync off | 31 | Never, on a new server. Legacy peer-to-peer sync. |
| onesync legacy | 64 | Only if a critical old resource genuinely breaks under Infinity. |
| onesync on (Infinity) | 2048 | The default answer. Culls entities by distance, server-authoritative. |

> **Infinity changes how scripts must be written** — Under Infinity a client can no longer see every entity in the world, so any resource that loops over GetGamePool on the client and assumes it has the full list will behave differently. This is the most common reason an old script "stops working" after enabling OneSync — the script is wrong, not the setting.

## ACE permissions in one page

ACE is FiveM's permission system. There are two verbs. add_principal puts an identifier or a group into another group. add_ace grants a group permission to do something. Everything else is a variation on those two.

Identifiers can be a licence, a Steam hex, a Discord id (if you run a Discord identifier resource), an IP or an FiveM account id. Licence is the usual choice because it survives a Steam change.

```cfg
# put a person into a group
add_principal identifier.license:1a2b3c4d5e6f7890abcdef1234567890abcdef12 group.admin

# nest groups so admin inherits everything mod has
add_principal group.admin group.mod

# what a group may do
add_ace group.admin command allow            # every console command
add_ace group.mod command.tp allow           # one command
add_ace group.mod command.kick allow
add_ace group.admin myresource.access allow  # your own resource can check this

# take something away explicitly
add_ace group.mod command.stop deny
```

> **add_ace after ensure does nothing useful** — Resources that cache permissions at start will have already read an empty set. Always put the whole permissions block above your ensure lines.

#### Checking a permission from a script

Server side, IsPlayerAceAllowed does the check. It returns true for anything the principal chain allows, including through nested groups.

```lua
RegisterCommand('wipe', function(src)
  if src > 0 and not IsPlayerAceAllowed(src, 'myresource.wipe') then
    return
  end
  -- ...
end, false)
```

## Resource start order

ensure is start plus restart-if-already-running, which is what you want in a config file. start is only meaningful for something you deliberately want to leave stopped and start by hand.

Order matters for anything with a dependency the manifest does not declare. The safe order is: database driver, framework core, framework dependants, standalone resources, maps and streams, then your HUD.

```cfg
ensure oxmysql
ensure qb-core

ensure [qb]           # a whole folder, in alphabetical order inside it
ensure [standalone]
ensure [maps]

# streams and textures can go anywhere, but early means the client has
# them before the HUD first draws
ensure pityus_minimap_orange_google

ensure qb-hud
```

> **Bracket folders are a real feature** — A folder named [qb] is not just a naming convention — ensure [qb] starts everything inside it. Use it to group resources so server.cfg stays readable, but keep anything order-sensitive on its own ensure line outside the bracket.

## The convars worth knowing

sv_enforceGameBuild is the one that catches people out. If you stream a vehicle or an MLO from a DLC newer than the build you pinned, it will simply not appear, with no error. Match the build to the newest content you actually stream.

| Convar | Value | What it does |
| --- | --- | --- |
| sv_scriptHookAllowed | 0 | Blocks single-player mod menus. Always 0 on a public server. |
| sv_enforceGameBuild | 3258 | Pins the DLC build. Required for newer vehicles and MLOs. |
| sv_endpointPrivacy | true | Hides player IPs from the players list. |
| sv_authMaxVariance | 1 | Stricter identity checks at connect. |
| sv_authMinTrust | 5 | Refuses low-trust accounts. 5 is a sane floor. |
| steam_webApiKey | "none" | Set to "none" unless you genuinely need Steam identifiers. |
| sv_requestParanoia | 1 | Rejects some malformed client requests. |
| gamemode / mapname | text | Cosmetic; shown in the browser. |

## A working template

Copy this, replace the licence key and the hostname, and you have a server that starts clean. Everything in it is explained above.

```cfg
# ---- network -------------------------------------------------------
endpoint_add_tcp "0.0.0.0:30120"
endpoint_add_udp "0.0.0.0:30120"
sv_maxclients 48

# ---- identity ------------------------------------------------------
sv_hostname "^3My Server ^7| ^1Roleplay"
sets sv_projectName "My Server"
sets sv_projectDesc "Serious roleplay, custom map, custom minimap"
sets tags "roleplay, qbcore, custom"
sets locale "en-GB"
load_server_icon myLogo.png

# ---- convars -------------------------------------------------------
set onesync on
set onesync_population true
sv_scriptHookAllowed 0
sv_enforceGameBuild 3258
sv_endpointPrivacy true
set steam_webApiKey "none"

# ---- permissions ---------------------------------------------------
add_ace group.admin command allow
add_ace group.admin command.quit deny
add_principal identifier.license:CHANGEME group.admin

# ---- resources -----------------------------------------------------
ensure oxmysql
ensure qb-core
ensure [qb]
ensure [standalone]
ensure [maps]
ensure pityus_minimap_orange_google
ensure qb-hud

# ---- licence (keep last) -------------------------------------------
sv_licenseKey "CHANGEME"
```

## Things that silently do nothing

- A comment started with // — server.cfg uses # for comments. // is parsed as a command and fails quietly.
- set instead of setr for a value the client needs to read. set is server-only; setr replicates to clients.
- sets for anything a script reads — sets writes to the server-list metadata, not to a convar your Lua can read.
- Quoting a number. sv_maxclients "48" works, but many convars are stricter; leave numbers unquoted.
- A resource folder name with a space or a capital letter mismatch. Linux is case sensitive; Windows is not, which is why it "worked locally".
- ensure on a folder that has no fxmanifest.lua — the console logs one line and moves on.

## Questions

### Where do I get sv_licenseKey?

From keymaster.fivem.net, signed in with the Cfx.re account that owns the server. One key per server instance; running two servers on the same key will get both dropped from the list.

### Why does my server not show in the server list?

In order of likelihood: UDP is not open, sv_licenseKey is missing or already in use elsewhere, the server crashed after start (check the console, not the process), or the IP in keymaster does not match. The server can be fully playable by direct connect and still be missing from the list — that is always a licence or UDP problem.

### Do I need OneSync for 48 players?

Yes. Without OneSync the hard cap is 32. Set onesync on, which is Infinity, and leave legacy alone unless something genuinely breaks.

### Can I split server.cfg into several files?

Yes — exec permissions.cfg loads another file at that point in the sequence. It is a good way to keep a long permission list out of the main file, as long as you exec it in the right place in the order.

## Related

- https://fam-tools.com/guides/fivem-artifacts-and-updates
- https://fam-tools.com/guides/fivem-server-performance
- https://fam-tools.com/guides/install-fivem-minimap
