Configuration
Everything vSQL reads is a FiveM convar in server.cfg. The only thing you have to set is how to reach the database - every other option ships with a sensible default, so add convars only when you want to change something.
Rather keep your settings in one file? Edit config.lua in the resource. Each field maps to the matching convar and is applied before vSQL boots; it's optional and starts empty, so a server.cfg-only setup is unaffected. A field left nil falls back to the convar and then the default. The convar names below are the source of truth; config.lua is just a convenient front end for them.
Connecting
There are two ways to point vSQL at the database. If you set both, the connection string wins.
Connection string
# URL form
set vsql_connection_string "mysql://user:password@host:3306/database"
# oxmysql-style key=value form (copy your old string across verbatim)
set vsql_connection_string "host=localhost;user=root;password=;database=fivem"Discrete options
set vsql_host "localhost"
set vsql_port 3306
set vsql_user "root"
set vsql_password ""
set vsql_database "fivem"
# optional: connect over a unix socket / named pipe instead of TCP
set vsql_socket "/var/run/mysqld/mysqld.sock"TIP
No vsql_database? vSQL still starts, but every query then has to fully-qualify its table names (schema.table). It'll warn you about this once on startup.
Full convar reference
Connection
| Convar | Default | Description |
|---|---|---|
vsql_connection_string | (empty) | URL (mysql://...) or key=value;... form. Overrides the discrete options below. |
vsql_host / vsql_port | localhost / 3306 | Server address. |
vsql_user / vsql_password | root / (empty) | Credentials. |
vsql_database | (empty) | Default schema. |
vsql_socket | (empty) | Unix socket or named-pipe path (skips TCP). |
vsql_server_hint | auto | Force the server type: auto, mysql, or mariadb. |
Pool
| Convar | Default | Description |
|---|---|---|
vsql_pool_size | 8 | Max pool connections. |
vsql_max_idle | (pool size) | Max idle connections kept open; extras are closed. Set below vsql_pool_size to let idle connections drain. |
vsql_idle_timeout | 60000 | Ms an idle connection lingers before being reaped. |
vsql_connect_timeout | 30000 | Connection timeout in ms. |
vsql_queue_limit | 0 | Max requests waiting for a free connection; 0 is unbounded. Set it to fast-fail under extreme load instead of queueing without limit. |
Session
| Convar | Default | Description |
|---|---|---|
vsql_charset | utf8mb4 | Connection charset. |
vsql_collation | utf8mb4_unicode_ci | Session collation. |
vsql_timezone | Z | mysql2 timezone handling. |
vsql_wait_timeout | 0 | If > 0, sets session wait_timeout and interactive_timeout. |
vsql_query_timeout | 0 | If > 0, caps statement runtime (ms) server-side. MariaDB caps all statements; MySQL only caps read-only SELECTs. |
Caching
| Convar | Default | Description |
|---|---|---|
vsql_cache | false | Enable the TTL + LRU result cache. |
vsql_cache_size | 500 | Max cached result sets. |
vsql_cache_ttl | 30000 | Cache entry TTL in ms. |
vsql_cache_adaptive | false | Scale each read's TTL by how often its tables are written: a rarely-written table caches for longer (up to vsql_cache_ttl_max), a hot one stays near vsql_cache_ttl. Every write still invalidates the exact entries it touches, so no read goes stale from a write that goes through vSQL; the cap bounds staleness from writes that bypass vSQL entirely. |
vsql_cache_ttl_max | 300000 | TTL ceiling (ms) applied to a quiet table under adaptive caching. |
vsql_coalesce | true | Collapse identical concurrent reads into one round-trip, so a spawn storm of the same query hits the database once and fans the result out. Locking reads (FOR UPDATE / FOR SHARE) are never coalesced. |
Reliability & profiling
| Convar | Default | Description |
|---|---|---|
vsql_tx_retries | 2 | Extra attempts for a transaction/batch that hits a deadlock or lock-wait timeout. 0 disables retrying. |
vsql_breaker_threshold | 10 | Consecutive failed reconnects (after the first successful connect) before the circuit breaker opens and queries fast-fail instead of queueing. 0 disables it. |
vsql_breaker_reset | 30000 | Ms the breaker stays open before allowing a probe. |
vsql_slow_query_warning | 150 | Slow-query threshold in ms (logged and surfaced in vsql top). |
vsql_explain_slow | false | When a slow query is a SELECT, run EXPLAIN on it and log the plan (e.g. players: ALL, key=NULL, rows=48210), so a full table scan or a missing index shows up right next to the slow-query warning. Best-effort: the EXPLAIN runs on the same pool and never adds latency to the original query. |
vsql_advisor | true | Record the full scans those EXPLAINs turn up, keyed by query shape, so vsql advise can suggest a CREATE INDEX for the hot ones. Runs the same best-effort EXPLAIN as vsql_explain_slow even when plan logging is off; the advisor never runs DDL itself. |
vsql_debug | 0 | 0 off, 1 lifecycle events, 2 logs every query with timing. |
Read replicas
| Convar | Default | Description |
|---|---|---|
vsql_read_replicas | (empty) | Comma-separated replica connection strings. Reads round-robin across them; writes, locking reads, and transactions stay on the primary. |
vsql_replica_hosts | (empty) | Comma-separated host[:port] replicas reusing the primary's user/password/database (the common "same creds, different host" case). |
vsql_replica_cooldown | 10000 | Ms a replica that failed a query stays out of rotation before being retried. |
# reuse the primary's credentials, just point at the replica hosts
set vsql_replica_hosts "10.0.0.2,10.0.0.3:3307"If a replica errors with a connection failure, it's dropped from rotation for the cooldown and the read quietly falls back to the primary - a replica going down never blocks reads or trips the primary's reconnect.
Migrations
| Convar | Default | Description |
|---|---|---|
vsql_migrations | true | Run pending migrations on resource start. |
vsql_migrations_dir | migrations | Migrations directory, relative to the resource. |
Compatibility & casting
| Convar | Default | Description |
|---|---|---|
vsql_compat | false | Claim the oxmysql / ghmattimysql / mysql-async export namespaces so existing scripts route into vSQL. Enable only with those resources removed. See Compatibility. |
vsql_typecast | false | oxmysql-compatible result casting: dates → epoch ms, TINYINT(1) / BIT(1) → boolean. Override per call with { typeCast: true | false }. |
Logging to Fivemanage
Ship vSQL's own log lines (connection lifecycle, slow queries, errors, migrations) to Fivemanage's Logs service. Lines are filtered by level, batched, and POSTed best-effort, so shipping never adds latency or blocks a query, and a failed upload is dropped rather than retried into a loop.
| Convar | Default | Description |
|---|---|---|
vsql_fivemanage_token | (empty) | Your Fivemanage Logs API token. Setting it is enough to turn shipping on. |
vsql_fivemanage | (auto) | Whether to ship logs. Defaults on once a token is set; set false to force it off. |
vsql_fivemanage_level | warn | Minimum severity to ship: debug, info, warn, or error. |
vsql_fivemanage_url | (v3 logs endpoint) | Override the ingest URL (for a proxy or a future API version). |
Updates
| Convar | Default | Description |
|---|---|---|
vsql_version_check | true | Check GitHub for a newer release on start. |
vsql_version_repo | valerisn/vSQL | owner/repo to check against (useful for forks). |
Per-call options
A few settings can be overridden for one query at a time by passing an options object as the last data argument (before any callback):
// skip the result cache for this read even if caching is on globally
await exports.vSQL.single('SELECT money FROM players WHERE id = ?', [id], { cache: false });
// cancel server-side if this report runs longer than 3s
await exports.vSQL.query('SELECT ... big aggregate ...', [], { timeout: 3000 });
// force oxmysql-style casting on (or off) just here
await exports.vSQL.query('SELECT created_at FROM players', [], { typeCast: true });Recommended starting points
set vsql_connection_string "mysql://root:pw@localhost:3306/fivem"
set vsql_pool_size 8set vsql_connection_string "mysql://root:pw@localhost:3306/fivem"
set vsql_pool_size 16
set vsql_max_idle 4 # let idle connections drain between peaks
set vsql_slow_query_warning 100
set vsql_cache true # only if your read/write mix benefits - see the warning belowset vsql_connection_string "mysql://root:pw@localhost:3306/fivem"
set vsql_debug 2 # log every query with timing
set vsql_slow_query_warning 50WARNING
Result caching is opt-in and global: any write clears the entire cache so you never read stale data. It pays off on read-heavy workloads with repeated identical reads, and costs you on write-heavy ones. Measure before switching it on in production, and reach for cacheClear("table") when you want targeted invalidation.