Skip to content
Database setup: MariaDB, HeidiSQL and oxmysql

Database setup: MariaDB, HeidiSQL and oxmysql

Install MariaDB on Windows or Linux, manage it with HeidiSQL, connect FiveM with oxmysql and mysql_connection_string, import SQL files and back up your data.

Last updated

Frameworks like QBCore, Qbox and ESX store characters, money, vehicles and inventories in a SQL database. FiveM talks to it through a resource, almost always oxmysql. A plain vMenu server does not need any of this.

Plays from youtube-nocookie.com after you click.

Use MariaDB, not XAMPP

  • MariaDB is what the frameworks target. The oxmysql docs say MariaDB is “highly recommended for compatibility and improved performance” over MySQL 8 (which has reserved keyword and default value differences that break some scripts).
  • Qbox requires at least MariaDB 10.9 and recommends a current LTS release. The ESX docs say to use MariaDB only.
  • XAMPP bundles an old MariaDB with a web server you don’t need. Both the ESX and Qbox docs tell you not to use it. If you’re on XAMPP now, dump your database and move it to a real MariaDB install.

Install on Windows

  1. Download the MSI from mariadb.org/download (pick the current LTS).
  2. Run it. Set a root password and keep “Install as service” checked. Leave “Enable access from remote machines for root” unchecked.
  3. The Windows installer includes HeidiSQL, a free GUI for the database. Keep it selected.
  4. Default port is 3306. Keep it unless something else uses it.

Install on Linux

Terminal
sudo apt install -y mariadb-server
sudo mariadb-secure-installation

Then create a dedicated user in the MariaDB shell (sudo mariadb):

SQL
CREATE USER 'fivem'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON *.* TO 'fivem'@'localhost';
FLUSH PRIVILEGES;

The broad grant lets the txAdmin deployer create a database. After deploying, you can restrict it to one database: GRANT ALL PRIVILEGES ON qbox_4f2a.* TO 'fivem'@'localhost'; and revoke the rest. Manage it from your PC with HeidiSQL over an SSH tunnel (HeidiSQL supports “MariaDB or MySQL (SSH tunnel)”) instead of opening port 3306.

HeidiSQL basics

  1. Open HeidiSQL, click New, network type MariaDB or MySQL (TCP/IP), host 127.0.0.1, user root (or fivem), your password, port 3306. Save and Open.
  2. Create a database: right click the connection > Create new > Database. Collation utf8mb4_unicode_ci or utf8mb4_general_ci.
  3. Import a .sql file (a resource’s install SQL): select the database, then File > Run SQL file… and pick the file.
  4. Browse data: click a table, then the Data tab. Handy for checking a player’s money or job while testing.
  5. Back up: right click the database > Export database as SQL, tick “Create” for tables and “Insert” for data.

Let txAdmin create it

When you deploy a framework recipe in txAdmin, the deployer asks for host, port, user and password and creates the database for you if you leave the name empty (it generates a random name like QBCore_A1B2C3). It also imports the framework’s SQL and writes the connection string into server.cfg through the {{dbConnectionString}} placeholder. That’s the easiest path.

Connect with oxmysql

oxmysql reads one convar. Put it in server.cfg (or better, in a secrets.cfg you exec) before ensure oxmysql:

server.cfg
set mysql_connection_string "mysql://fivem:password@localhost:3306/qbox_4f2a?charset=utf8mb4"

ensure oxmysql

Both formats from the oxmysql docs work:

server.cfg
# URI
set mysql_connection_string "mysql://root:12345@localhost:3306/fivem"
# key=value
set mysql_connection_string "user=root;password=12345;host=localhost;port=3306;database=fivem"

Warning

Don’t use these characters in the database password: ; , / ? : @ & = + $ #. They break the connection string parsing. Use a long password made of letters and numbers instead.

Useful oxmysql convars:

server.cfg
set mysql_slow_query_warning 150      # warn about queries slower than 150 ms
set mysql_debug false                 # true, or a list like ["ox_inventory"] to log queries

Using the database in your own resource

Add oxmysql’s library to your manifest:

fxmanifest.lua
server_scripts {
    '@oxmysql/lib/MySQL.lua',
    'server/main.lua',
}
dependency 'oxmysql'

Then query from server scripts. Always use placeholders (?) for values, never string concatenation:

server/main.lua
-- one row
local row = MySQL.single.await('SELECT money FROM my_accounts WHERE identifier = ?', { identifier })

-- one value
local count = MySQL.scalar.await('SELECT COUNT(*) FROM my_accounts')

-- many rows
local rows = MySQL.query.await('SELECT * FROM my_accounts WHERE money > ?', { 1000 })

-- insert, returns the new id
local id = MySQL.insert.await('INSERT INTO my_accounts (identifier, money) VALUES (?, ?)', { identifier, 500 })

-- update, returns affected rows
local changed = MySQL.update.await('UPDATE my_accounts SET money = money + ? WHERE identifier = ?', { 250, identifier })

Caution

Never build SQL from strings a client sent you: '... WHERE name = "' .. name .. '"' is an SQL injection waiting to happen. Placeholders escape values for you.

Database code only runs on the server. Clients must never talk to the database directly. They ask the server with an event or callback, and the server checks and queries. See Client, server and events.

Backups

Set these up before you have players, not after the first disaster.

Windows: a scheduled task that runs mariadb-dump (or mysqldump, both ship with MariaDB) every night:

backup-db.bat
@echo off
set STAMP=%DATE:~-4%-%DATE:~3,2%-%DATE:~0,2%
"C:\Program Files\MariaDB 11.4\bin\mariadb-dump.exe" -u root -pYOURPASSWORD --single-transaction qbox_4f2a > C:\Backups\db-%STAMP%.sql

Adjust the MariaDB folder and date format to your system.

Linux: a cron job for the fivem user:

Terminal
crontab -e
# every night at 04:30, keep 14 days
30 4 * * * mariadb-dump --single-transaction qbox_4f2a | gzip > /home/fivem/backups/db-$(date +\%F).sql.gz && find /home/fivem/backups -name 'db-*.sql.gz' -mtime +14 -delete

Put credentials in ~/.my.cnf (mode 600) so they don’t appear in the crontab:

~/.my.cnf
[client]
user=fivem
password=a-long-random-password

Copy backups off the machine too (another server, object storage). A backup on the same disk doesn’t help when the disk dies.

Common database errors

Error / symptom Fix
ECONNREFUSED 127.0.0.1:3306 MariaDB isn’t running, or it’s on another port. Start the service.
ER_ACCESS_DENIED_ERROR Wrong user or password in mysql_connection_string, or the user has no rights on that database.
ER_BAD_DB_ERROR: Unknown database The database name in the string doesn’t exist. Create it or fix the name.
ER_NO_SUCH_TABLE You didn’t import the resource’s .sql file.
Emojis or special names turn into ???? Use utf8mb4 for the database and add ?charset=utf8mb4 to the URI.
Framework loads, but nothing saves oxmysql started after the framework. Put ensure oxmysql first.

Next: Common errors and fixes.