The FiveM server.cfg, line by line
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.
- 01 Endpoints and network
endpoint_add_tcp / endpoint_add_udp, then sv_maxclients.
- 02 Identity
sv_hostname, sv_projectName, sv_projectDesc, tags, locale.
- 03 Convars
Everything a resource reads at start: OneSync, sv_scriptHookAllowed, custom convars.
- 04 ACE permissions
add_ace / add_principal, before the resources that check them.
- 05 Resources
ensure lines, framework first, dependants after.
- 06 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. Without OneSync you cannot exceed 32. 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.
endpoint_add_tcp "0.0.0.0:30120"
endpoint_add_udp "0.0.0.0:30120"
sv_maxclients 48#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.
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#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.
set onesync on
set onesync_population true
set onesync_enableInfinity true
set onesync_distanceCullVehicles true
set onesync_forceMigration true| Setting | Slots | When to use it |
|---|---|---|
| onesync off | 32 | 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. |
OneSync modes as of the current recommended artifacts.
#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.
# 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 denyChecking a permission from a script
Server side, IsPlayerAceAllowed does the check. It returns true for anything the principal chain allows, including through nested groups.
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.
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#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.
# ---- 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?
Why does my server not show in the server list?
Do I need OneSync for 48 players?
Can I split server.cfg into several files?
Ready to pick a map?
Twelve themes on three base map styles, $8 each, instant download.