FiveM Database Guide: MySQL & oxmysql Setup (2026)
Complete guide to setting up a MySQL/MariaDB database for your FiveM server with oxmysql. Covers installation, configuration, framework SQL imports, performance tuning, backups, and common errors.

A FiveM server without a properly configured database is a server waiting to fail. Persistent player data β money, vehicles, properties, jobs, inventories β all lives in MySQL. Get the database wrong and your players lose progress, your server crashes under load, or scripts throw errors on every interaction.
This guide covers everything you need: which database engine to use, how to install and configure it, how to connect it to your server via oxmysql, and how to keep it running reliably under real player loads.
MySQL vs MariaDB for FiveM
The short answer: use MariaDB. Here's why.
MariaDB is a community-driven fork of MySQL, originally created by the original MySQL developers after Oracle acquired MySQL in 2010. It is a drop-in replacement β every MySQL command, connection string, and client tool works identically. But it has several practical advantages for FiveM servers:
| Feature | MySQL 8.0 | MariaDB 10.11+ | |---|---|---| | Performance (OLTP) | Good | Better β especially under concurrent writes | | Reserved keywords | Expanded set (causes script conflicts) | Fewer reserved words | | Default storage engine | InnoDB | InnoDB (same) | | JSON support | Native | Native | | Community FiveM support | Widespread | Majority recommendation | | License | GPL + Oracle commercial | GPL only | | Connection overhead | Standard | Slightly lower |
The reserved keyword issue with MySQL 8 is a real problem for FiveM. Many legacy ESX scripts use column names like rank, groups, type, and status β all of which became reserved keywords in MySQL 8.0. MariaDB does not reserve these words in the same way, saving you from a flood of script errors on startup.
Most FiveM hosting providers use MariaDB by default. If you're running your own VPS or dedicated server, choose MariaDB.
Step-by-Step Installation
Windows: XAMPP or Standalone MariaDB
Option 1: XAMPP (easiest for local/development)
- Download XAMPP from apachefriends.org
- Install and open the XAMPP Control Panel
- Start the MySQL service (this actually runs MariaDB in recent XAMPP versions)
- Open phpMyAdmin at
http://localhost/phpmyadmin - Default credentials: user
root, no password β change this before exposing to any network
Option 2: Standalone MariaDB (production Windows)
- Download the MariaDB MSI installer from mariadb.org/download
- Run the installer β check "Use UTF8 as default server character set"
- Set a strong root password during installation
- MariaDB installs as a Windows service and starts automatically
- Add
C:\Program Files\MariaDB 10.11\binto your PATH environment variable - Verify installation:
mysql -u root -p
# Enter your root password β you should see the MariaDB prompt
Linux: Ubuntu/Debian
# Update package lists
sudo apt update
# Install MariaDB server
sudo apt install mariadb-server mariadb-client -y
# Run the security configuration wizard
sudo mysql_secure_installation
# Answer: set root password, remove anonymous users, disallow remote root login, remove test database
# Enable and start the service
sudo systemctl enable mariadb
sudo systemctl start mariadb
# Verify
sudo systemctl status mariadb
Linux: CentOS/RHEL/Rocky Linux
# Install MariaDB from the official MariaDB repository
sudo dnf install mariadb-server mariadb -y
# Enable and start
sudo systemctl enable --now mariadb
# Secure the installation
sudo mysql_secure_installation
Pterodactyl / Panel-Hosted Servers
If you're using Pterodactyl, most panels provide a built-in database manager. In the Pterodactyl admin panel:
- Go to Databases in the server panel
- Click Create Database
- The panel creates the database, user, and grants permissions automatically
- Copy the host, port, username, password, and database name β you'll use these in your connection string
For Docker-based setups, use the container's internal hostname (often mariadb or the service name) rather than 127.0.0.1.
Database and User Creation
Never run your FiveM server as the root database user. Create a dedicated database and user with only the permissions it needs.
Connect to MariaDB/MySQL as root:
mysql -u root -p
Then run these SQL commands:
-- Create the database (use utf8mb4 for full Unicode support including emojis)
CREATE DATABASE fivem_server CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Create a dedicated user (replace 'fivemuser' and 'StrongPassword123!' with your values)
CREATE USER 'fivemuser'@'localhost' IDENTIFIED BY 'StrongPassword123!';
-- Grant all privileges on the FiveM database only
GRANT ALL PRIVILEGES ON fivem_server.* TO 'fivemuser'@'localhost';
-- If your FiveM server runs on a different machine, use the server IP instead of localhost
-- CREATE USER 'fivemuser'@'192.168.1.100' IDENTIFIED BY 'StrongPassword123!';
-- GRANT ALL PRIVILEGES ON fivem_server.* TO 'fivemuser'@'192.168.1.100';
-- Apply the privilege changes
FLUSH PRIVILEGES;
-- Verify the user was created
SELECT user, host FROM mysql.user WHERE user = 'fivemuser';
-- Exit
EXIT;
Test the new user connection:
mysql -u fivemuser -p fivem_server
# Enter the password β you should be connected to the fivem_server database
oxmysql Installation and Configuration
oxmysql is the modern, maintained MySQL resource for FiveM. It replaces the older mysql-async and ghmattimysql resources with significantly better performance and an async/promise-based API.
Download
- Go to the oxmysql GitHub releases page
- Download the latest release ZIP (
oxmysql.zip) - Extract to your server's
resourcesdirectory:resources/[standalone]/oxmysql/
The folder structure should look like:
resources/
[standalone]/
oxmysql/
fxmanifest.lua
build/
mysql.js
server.cfg Configuration
Add the following to your server.cfg. oxmysql must be started before any resource that depends on it:
# oxmysql - must be first
ensure oxmysql
# Your framework and other resources below
ensure es_extended
ensure [esx]
Set your connection string using a convar. The format is a standard MySQL URI:
set mysql_connection_string "mysql://fivemuser:StrongPassword123!@localhost/fivem_server"
Connection String Format
mysql://[user]:[password]@[host]:[port]/[database]?[options]
Examples:
# Standard local connection
set mysql_connection_string "mysql://fivemuser:MyPassword@localhost/fivem_server"
# With explicit port (default MySQL port is 3306)
set mysql_connection_string "mysql://fivemuser:MyPassword@localhost:3306/fivem_server"
# Remote database server
set mysql_connection_string "mysql://fivemuser:[email protected]/fivem_server"
# With additional options (disable SSL for local connections)
set mysql_connection_string "mysql://fivemuser:MyPassword@localhost/fivem_server?ssl=false"
# Character set enforcement (recommended)
set mysql_connection_string "mysql://fivemuser:MyPassword@localhost/fivem_server?charset=utf8mb4"
If your password contains special characters (@, /, !, etc.), URL-encode them. For example, P@ss!word becomes P%40ss%21word.
Verify the Connection
Start your FiveM server and check the console output. You should see:
[ oxmysql ] Database server connection established.
If you see an error instead, jump to the Common Errors section below.
oxmysql vs mysql-async vs ghmattimysql
If you're inheriting an older server, you may find one of the legacy MySQL resources already installed. Here's a direct comparison:
| Feature | oxmysql | mysql-async | ghmattimysql | |---|---|---|---| | Actively maintained | Yes | No (archived) | No | | Performance | Highest | Moderate | Moderate | | Promise/async API | Native | Partial | Partial | | Callback API | Supported (backwards compat) | Yes | Yes | | Connection pooling | Yes, configurable | Basic | Basic | | ESX compatibility | Full | Full | Full | | QBCore compatibility | Full | Full | Full | | QBox/ox_core | Native (same team) | No | No | | Error reporting | Detailed | Basic | Basic | | TypeScript types | Yes | No | No |
The migration from mysql-async or ghmattimysql to oxmysql is straightforward in most cases because oxmysql provides backwards-compatible exports for the common function signatures (MySQL.Sync.execute, MySQL.Async.execute, etc.).
Use oxmysql. There is no reason to use the others for new or existing servers.
Framework Database Setup
Each major framework requires importing its SQL schema before starting the server. Do this once, after creating the database.
ESX (es_extended)
# Download es_extended from GitHub if you haven't already
# The SQL file is at: es_extended/sql/es_extended.sql
# Import via command line
mysql -u fivemuser -p fivem_server < /path/to/resources/[framework]/es_extended/sql/es_extended.sql
# Or import via phpMyAdmin:
# 1. Select your database in the left panel
# 2. Click "Import" tab
# 3. Choose the .sql file and click "Go"
Key ESX tables created: users, user_accounts, user_inventory, user_licenses, user_vehicles, jobs, job_grades, society_money, addon_account, datastore
After import, verify:
USE fivem_server;
SHOW TABLES;
-- You should see all ESX tables listed
QBCore
# QBCore SQL file location: qb-core/sql/qbcore.sql
mysql -u fivemuser -p fivem_server < /path/to/resources/[framework]/qb-core/sql/qbcore.sql
Key QBCore tables: players, player_vehicles, player_houses, player_outfits, bank_accounts, job_grades, gangs, gang_grades
QBox (ox_core)
QBox uses ox_core which has its own SQL schema, as well as ox_inventory if you use it:
# ox_core schema
mysql -u fivemuser -p fivem_server < /path/to/resources/[ox]/ox_core/sql/ox_core.sql
# ox_inventory schema (if used)
mysql -u fivemuser -p fivem_server < /path/to/resources/[ox]/ox_inventory/sql/ox_inventory.sql
Key ox_core tables: characters, character_groups, character_vehicles, ox_storage
After importing any framework's SQL, restart your server. If there are additional resource SQL files (phones, garages, banks), import those as well β each script's README will specify if it needs a SQL import.
Performance Tuning
Default MariaDB/MySQL settings are conservative and designed for minimal hardware. A FiveM server under real load needs different settings.
my.cnf / my.ini Configuration
Edit your MariaDB configuration file:
- Linux:
/etc/mysql/my.cnfor/etc/my.cnf.d/server.cnf - Windows:
C:\Program Files\MariaDB 10.11\data\my.ini
[mysqld]
# InnoDB buffer pool β the single most important setting
# Set to 50-70% of available RAM dedicated to the database
# Small VPS (2GB RAM): 512M
# Medium VPS (4GB RAM): 1G
# Dedicated DB server (16GB RAM): 8G
innodb_buffer_pool_size = 1G
# Allow multiple buffer pool instances for better concurrency
# Set to number of CPU cores, max 8
innodb_buffer_pool_instances = 4
# Log file size β larger = faster writes, longer recovery
innodb_log_file_size = 256M
# How often to flush logs to disk (2 = flush once per second, not per transaction)
# Setting 2 risks losing up to 1 second of data on crash β acceptable for FiveM
innodb_flush_log_at_trx_commit = 2
# Maximum simultaneous connections
# Size based on your player count β see table below
max_connections = 100
# Connection timeout
wait_timeout = 600
interactive_timeout = 600
# Character set (must match your database)
character_set_server = utf8mb4
collation_server = utf8mb4_unicode_ci
# Query cache (disable in MySQL 8 β removed entirely; useful in MariaDB for read-heavy workloads)
# query_cache_type = 1
# query_cache_size = 64M
Restart MariaDB after changes:
sudo systemctl restart mariadb
Connection Pool Sizing by Player Count
oxmysql maintains a pool of database connections. Too few connections and queries queue up; too many and you waste memory and hit max_connections.
Add this to your server.cfg:
# Connection pool size for oxmysql
set mysql_connection_string "mysql://user:pass@localhost/fivem_server"
# Set pool size via the connection string options
# set mysql_connection_string "mysql://user:pass@localhost/db?connectionLimit=10"
| Server Size | Max Players | Recommended Pool | max_connections | |---|---|---|---| | Small | 16 | 5-8 | 50 | | Medium | 32 | 10-15 | 75 | | Large | 64 | 15-25 | 100 | | XL | 128+ | 25-40 | 150 |
The connection limit in the URL (connectionLimit=10) controls how many simultaneous connections oxmysql can maintain. Set max_connections in MariaDB at least 20 higher than your pool size to leave room for admin connections and monitoring.
Indexing Tips
Slow queries are usually missing indexes. Check for slow queries by enabling the slow query log:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
Common FiveM tables that benefit from indexes:
-- If you have custom tables with frequent lookups
-- Example: looking up player data by identifier
CREATE INDEX idx_identifier ON players(identifier);
-- ESX users table β usually already indexed, but verify
SHOW INDEX FROM users;
Backup Strategy
Backups are non-negotiable. Player data loss is one of the fastest ways to kill a server's community.
Manual Backup with mysqldump
# Backup entire database to a file
mysqldump -u fivemuser -p fivem_server > /backups/fivem_server_$(date +%Y%m%d_%H%M%S).sql
# Backup with compression (much smaller files)
mysqldump -u fivemuser -p fivem_server | gzip > /backups/fivem_server_$(date +%Y%m%d).sql.gz
# Restore from backup
mysql -u fivemuser -p fivem_server < /backups/fivem_server_20260304.sql
# Restore from compressed backup
gunzip < /backups/fivem_server_20260304.sql.gz | mysql -u fivemuser -p fivem_server
Automated Daily Backups (Linux cron)
Create a backup script at /usr/local/bin/fivem-db-backup.sh:
#!/bin/bash
# Configuration
DB_USER="fivemuser"
DB_PASS="StrongPassword123!"
DB_NAME="fivem_server"
BACKUP_DIR="/backups/fivem"
RETENTION_DAYS=14
# Create backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"
# Filename with timestamp
FILENAME="$BACKUP_DIR/${DB_NAME}_$(date +%Y%m%d_%H%M%S).sql.gz"
# Run backup
mysqldump -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" | gzip > "$FILENAME"
# Remove backups older than retention period
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: $FILENAME"
Make it executable and schedule it:
chmod +x /usr/local/bin/fivem-db-backup.sh
# Add to crontab β run daily at 4:00 AM
crontab -e
# Add this line:
0 4 * * * /usr/local/bin/fivem-db-backup.sh >> /var/log/fivem-backup.log 2>&1
Avoiding Credentials in Shell Scripts
Using passwords directly in shell scripts is a security risk. Use a MySQL options file instead:
# Create /etc/mysql/backup.cnf
[client]
user=fivemuser
password=StrongPassword123!
host=localhost
# Secure it
chmod 600 /etc/mysql/backup.cnf
# Use in backup script with --defaults-file
mysqldump --defaults-file=/etc/mysql/backup.cnf fivem_server | gzip > "$FILENAME"
Common Errors and Fixes
| Error | Likely Cause | Fix |
|---|---|---|
| Access denied for user 'fivemuser'@'localhost' | Wrong password or user doesn't have access from this host | Re-run GRANT ALL PRIVILEGES ON fivem_server.* TO 'fivemuser'@'localhost'; FLUSH PRIVILEGES; |
| Connection refused / Can't connect to MySQL server | MariaDB isn't running, or firewall blocking port 3306 | Run sudo systemctl start mariadb and check sudo ufw status |
| Table 'fivem_server.users' doesn't exist | SQL schema not imported | Import the framework's SQL file as described in the Framework section |
| Too many connections | Pool size exceeds max_connections | Increase max_connections in my.cnf or reduce connectionLimit in connection string |
| You have an error in your SQL syntax near 'rank' | MySQL 8 reserved keyword conflict | Switch to MariaDB, or wrap column name in backticks: `rank` |
| Unknown column 'groups' in 'field list' | MySQL 8 reserved keyword | Same as above β switch to MariaDB or use backtick quoting |
| Lost connection to MySQL server during query | wait_timeout too low or network instability | Increase wait_timeout = 600 in my.cnf |
| Incorrect string value for a column | Database character set is not utf8mb4 | Recreate database with CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci |
| [oxmysql] Slow query (>100ms) in console | Missing index or inefficient query | Enable slow query log, identify the query, add appropriate index |
| ECONNRESET errors in oxmysql | Connection pool exhausted or MariaDB restarted | Increase pool size, check MariaDB stability, restart resource |
FAQ
Do I need a separate server for the database?
No. For servers under 64 players, running MariaDB on the same machine as FiveM is fine. With 128+ players and many active scripts, a dedicated database server reduces latency and resource contention β but it's optional, not required.
Can I use a remote database provider like PlanetScale or AWS RDS?
Yes. Use the remote host's connection string in oxmysql. Be aware that network latency (even a few milliseconds) adds up when scripts run many queries per tick. Local or same-datacenter databases always perform better.
How do I migrate from mysql-async to oxmysql?
- Download oxmysql and add it to your resources
- In
server.cfg, replaceensure mysql-asyncwithensure oxmysql - Most scripts use backwards-compatible exports and will work without code changes
- Test on a development server first before touching production
What's the difference between oxmysql execute and query?
execute is for statements that modify data (INSERT, UPDATE, DELETE). query is for SELECT statements that return rows. In practice, oxmysql handles both, but using the semantically correct function makes your code clearer.
How do I check which queries are slowest on my server?
Enable the slow query log in my.cnf with long_query_time = 0.5. After running your server for a session, check /var/log/mysql/slow.log. You can also use mysqldumpslow to summarize the log.
Can I use SQLite instead of MySQL?
Some small scripts support SQLite via oxmysql's compatibility layer, but no major FiveM framework (ESX, QBCore, QBox) supports SQLite for its core tables. Stick with MariaDB.
My server crashes when many players log in at once β is this the database?
Possibly. Check the FiveM server console for [oxmysql] errors during the crash. If you see Too many connections or slow query warnings spiking at login, increase your connection pool size and tune innodb_buffer_pool_size. Also check whether your framework has a login queue to stagger connections.
Do I need to back up the database if I use a hosted panel?
Yes. Hosting panel backups are not guaranteed to run on schedule or survive panel migrations. Always run your own mysqldump backups to a separate location you control.
Wrapping Up
A correctly configured database is invisible β it just works. A misconfigured one causes random errors, player data loss, and crashes under load. The steps here cover everything from first install to production-grade reliability.
For the framework scripts that rely on this database foundation, browse the VertexMods shop for premium ESX, QBCore, and QBox resources. For a broader look at what scripts your server needs, the FiveM scripts complete guide covers the essential resources for any roleplay server.
The most important things to walk away with: use MariaDB over MySQL 8, use oxmysql, create a dedicated database user, tune your buffer pool, and automate your backups. Everything else is detail.


