Introduction
mysql-async était la référence il y a 5 ans. Aujourd'hui, oxmysql (par Overextended) est plus rapide, mieux maintenu, supporte les promesses async/await natives, et est devenu le standard de fait. Si tu démarres un serveur en 2026, c'est lui.
Prérequis
- Un serveur FiveM chez VeryCloud
- Une BDD MySQL/MariaDB accessible (voir le tuto fivem-sql sur la doc pour la BDD)
- Accès Files et Startup dans Wisp
Étape 1 : Télécharger oxmysql
oxmysql est sur GitHub :
Télécharge oxmysql.zip (le release officiel, pas le source).
Étape 2 : Uploader
Dans Wisp → Files → /resources/ :
- Crée le dossier
[mysql](organisation) si pas déjà - Upload + extract
oxmysql.zip→ renomme enoxmysql
Structure :
/resources/
└── [mysql]/
└── oxmysql/
├── fxmanifest.lua
├── lib/
├── dist/
└── README.md
Étape 3 : Configurer la connexion
Dans /server.cfg, ajoute la connection string AVANT le ensure oxmysql :
set mysql_connection_string "mysql://user:password@host:3306/database?charset=utf8mb4"
ensure oxmysql
Exemple concret :
set mysql_connection_string "mysql://fivem_user:[email protected]:3306/fivem_db?charset=utf8mb4"
💡 Échappement : si ton mot de passe contient
@,:,/,?, il faut l'URL-encoder. Préfère un mdp alphanumérique.
Étape 4 : Restart et vérifier
Restart le serveur. Console FXServer :
[oxmysql] Connection established
[oxmysql] Database 'fivem_db' is ready
Si erreur :
Access denied: mauvais credentials ou IP source pas dans les GRANT MySQLConnection refused: port 3306 firewallé ou MySQL downUnknown database: la BDD n'existe pas
Étape 5 : Vérifier les exports
oxmysql expose des fonctions globales via FiveM exports. Test en jeu (chat F8) :
exports.oxmysql:query('SELECT 1+1 AS result', {}, function(rs) print(json.encode(rs)) end)
Si tu vois [{"result":2}] dans la console, c'est bon.
Étape 6 : Les méthodes principales
oxmysql expose plusieurs méthodes selon l'usage :
| Méthode | Usage |
|---|---|
oxmysql:query | Query générique, retourne array de rows |
oxmysql:execute | INSERT/UPDATE/DELETE, retourne affectedRows |
oxmysql:single | SELECT qui ne retourne qu'une ligne (premier résultat) |
oxmysql:scalar | SELECT qui ne retourne qu'une seule valeur (premier champ première ligne) |
oxmysql:insert | INSERT, retourne insertId |
oxmysql:transaction | Wrapper pour transactions atomiques |
Étape 7 : Exemples Lua
SELECT simple :
exports.oxmysql:query(
'SELECT money FROM players WHERE identifier = ?',
{ 'steam:110000XXX' },
function(rs)
if rs and rs[1] then
print('Money:', rs[1].money)
else
print('Player not found')
end
end
)
INSERT :
local insertId = exports.oxmysql:insert_async(
'INSERT INTO logs (action, player, timestamp) VALUES (?, ?, NOW())',
{ 'login', 'steam:110000XXX' }
)
print('Inserted id:', insertId)
Async/await pattern (CitizenFX) :
local result = MySQL.query.await(
'SELECT * FROM players WHERE identifier = ?',
{ 'steam:110000XXX' }
)
-- result est dispo directement, pas de callback
Étape 8 : Migration depuis mysql-async
Si tu as un vieux code mysql-async, les API sont compatibles à 90% :
| mysql-async | oxmysql |
|---|---|
MySQL.Async.fetchAll | MySQL.query |
MySQL.Async.execute | MySQL.execute |
MySQL.Async.insert | MySQL.insert |
MySQL.Sync.fetchAll | MySQL.query.await |
Remplace mysql-async par oxmysql dans server.cfg et la majorité de ton code marche tel quel.
Étape 9 : Performance et pooling
oxmysql gère automatiquement un pool de connexions. Tu peux le tuner via :
set mysql_connection_string "mysql://user:pass@host:3306/db?charset=utf8mb4"
set mysql_debug "false" # true pour logger toutes les queries (debug only)
set mysql_slow_query_warning 250 # avertir si query > 250ms
⚠️
mysql_debug "true"en prod = log spam énorme et perf killée. Réservé au debug.
Étape 10 : Bonnes pratiques
- Toujours utiliser des placeholders (
?) : protection SQL injection - Indexer les colonnes sur lesquelles tu filtres souvent (
CREATE INDEX idx_identifier ON players(identifier)) - Connexion locale > distante : si possible, BDD sur le même node que FiveM (latence réseau divisée par 100)
- Monitoring : active
slow_query_warningpour détecter les queries lentes
Dépannage
Access denied for user
- Mauvais user/mdp
- L'IP du serveur FiveM doit être dans les
GRANT - Test depuis le node FiveM :
mysql -h HOST -u USER -p
Can't connect to MySQL server
- Port 3306 bloqué (firewall)
- BDD pas démarrée
Queries qui plantent silencieusement
- Active
set mysql_debug "true"temporairement - Regarde la console FXServer pour les erreurs SQL
Latence anormalement haute
- BDD géographiquement éloignée (préfère colocalisée)
- Trop de queries non-async qui bloquent
Commandes utiles
# Tester la connexion depuis le serveur FiveM (si shell)
mysql -h HOST -u USER -p
# Voir les processus MySQL en cours (cote BDD)
SHOW PROCESSLIST;
# Logs lents MySQL
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.5;
Conclusion
oxmysql = standard 2026 pour FiveM. Plus rapide, plus moderne, support natif async/await. Installation en 10 min, BDD bien indexée, queries préparées : tu as une base data layer solide pour tout ton serveur. Migrer depuis mysql-async est trivial.
Pour aller plus loin : transactions atomiques, prepared statement caching, monitoring des slow queries via Prometheus.



















