Database · Overextended

oxmysql for FiveM

What it is

The MySQL wrapper the modern FiveM stack runs on: promise-based, prepared-statement aware and a drop-in replacement for mysql-async.

Every persistent thing on a FiveM server — characters, vehicles, inventories, bans, and the settings behind a hosted loading screen — ends up in MySQL. oxmysql is the current standard client: it uses real prepared statements, returns promises, and ships a compatibility layer so mysql-async and ghmattimysql scripts keep working while you migrate.

Official documentation Repository All resources

At a glance

MaintainerOverextended
Latest releasev2.14.1 · 2026-05-04
Last code change2026-07-03
LicenceLGPL-3.0
Written inTypeScript
GitHub stars360
StatusActive

Figures read from the repository on 2026-09-22.

How a query actually reaches MySQLA script calls the MySQL wrapper, which uses a pooled connection and a prepared statement to reach the database. Old scripts reach the same wrapper through a compatibility shim.Modern scriptMySQL.query.awaitLegacy scriptMySQL.Async.fetchAllmysql-async shimtranslates the old APIoxmysqlprepared statements, poolMySQL / MariaDByour data, on diskThe `?` placeholder is what makes it a prepared statement. String concatenation is how servers get emptied.
How a query actually reaches MySQL

Why servers run it

  • Prepared statements by default, which closes the SQL injection hole the older wrappers left wide open.
  • Promise-based with await support, so database code reads top to bottom.
  • Drop-in shims for mysql-async and ghmattimysql, so migration is incremental rather than a big bang.
  • A built-in slow-query log, which is usually how you find the script quietly costing you 40ms a tick.

Installing oxmysql

  1. 1. Start it first

    oxmysql has to be the first resource in server.cfg that touches the database.

  2. 2. Set the connection string

    set mysql_connection_string in server.cfg, in either URI or key=value form. Do not put it in a config.lua that ends up in a public repository.

  3. 3. Turn on the slow-query log

    set mysql_slow_query_warning 150 prints anything over 150ms with the query attached.

  4. 4. Use the shim while migrating

    Old scripts keep working through the compatibility layer; convert them as you touch them rather than all at once.

Working examples

server.cfg — the connection string

set mysql_connection_string "mysql://user:password@localhost:3306/fivem?charset=utf8mb4"
set mysql_slow_query_warning 150
set mysql_debug false

Reading and writing, the modern way

-- Single row
local row = MySQL.single.await(
    'SELECT citizenid, charinfo FROM players WHERE license = ?', { license })

-- Many rows
local screens = MySQL.query.await(
    'SELECT slug, title FROM loading_screens WHERE owner = ?', { userId })

-- Insert, returning the new id
local id = MySQL.insert.await(
    'INSERT INTO loading_screens (owner, slug, title) VALUES (?, ?, ?)',
    { userId, slug, title })

A transaction that either all lands or none does

MySQL.transaction.await({
    { query = 'UPDATE accounts SET balance = balance - ? WHERE id = ?', values = { 500, from } },
    { query = 'UPDATE accounts SET balance = balance + ? WHERE id = ?', values = { 500, to } },
})

What goes wrong

Never build a query by concatenating player input. Use ? placeholders. The whole reason oxmysql exists is that the previous generation made this easy to get wrong.

`.await` blocks the coroutine it runs in. Inside a per-frame loop that is a stall; inside an event handler it is fine.

The connection string lives in server.cfg, which means server.cfg contains a database password. Keep it out of version control.

Two MySQL resources at once — oxmysql and mysql-async both started — gives you two connection pools and a confusing set of errors.

oxmysql — questions people ask

Is oxmysql faster than mysql-async?
Meaningfully, yes — prepared statements are cached and the connection pool is better managed. The larger win is correctness: parameterised queries by default.
Can I migrate gradually?
Yes. Start oxmysql, keep the mysql-async shim enabled, and convert scripts one at a time.
Where are the oxmysql docs?
coxdocs.dev/oxmysql, with the full API and the convar list.

Runs alongside

mysql-async

The original FiveM MySQL wrapper: still installed on a very large number of live servers, no longer the right choice for new code.

ox_lib

The shared library half the modern FiveM ecosystem depends on: menus, notifications, progress bars, zones, callbacks and a cache.

txAdmin

The web panel bundled with every FXServer build: process management, recipes, players, bans, scheduled restarts and live console.