Changelog

DBSync: Install and Configure

Use this guide to install and configure DBSync when FiveNet should pull characters, vehicles, and other data from your gameserver database without requiring direct database access from the FiveNet server itself.

Use this guide to install and configure DBSync when FiveNet should pull characters, vehicles, and other data from your gameserver database without requiring direct database access from the FiveNet server itself.

Complete Configure FiveNet first so the FiveNet server has a working database, NATS connection, public URL, and Sync API token.

Why DBSync Is Required

DBSync is the component that transfers characters, vehicles, and other gameserver data from your gameserver database into FiveNet.

Without DBSync, FiveNet cannot keep its own data in sync with the data generated by your gameserver.

This is the standard setup for FiveNet, including FiveNet Cloud deployments.

Requirements

FiveNet's DBSync (fivenet cli) is available on:

  • Windows (only the latest version of Windows Server and Windows 11 are supported)
    • amd64 - Your typical Windows server will run on this architecture.
  • Linux
    • amd64 - Your typical Linux server will run on this architecture.
    • arm64 - The newer 64-bit ARM architecture commonly found in Raspberry Pi 4 and other ARM-based servers.

Database

DBSync currently supports MySQL-compatible databases only. If your gameserver uses a different database system, such as MongoDB, DBSync cannot be used at the moment.

Quick Setup Flow

  1. Install the fivenet binary.
  2. Create and edit dbsync.yaml.
  3. Enable the FiveNet Sync API and configure at least one sync token in your main config.yaml.
  4. Test fivenet dbsync manually.
  5. Once the sync works reliably, run it as a service.

Architecture

Installation

This guide assumes you have already installed FiveNet and have a working config.yaml file for the main FiveNet server. If you haven't done that yet, please follow the installation guide first.If you are using Docker for your FiveNet deployment, you can also run DBSync in a container. Refer to the example DBSync service in docker-compose.yaml and continue with the configuration section below.

To install DBSync, follow these steps:

  1. Download and extract the latest release of the fivenet binary or exe from the official FiveNet repository. Use the commands for your platform, or download the matching archive manually from the releases page:
    curl -LO https://github.com/fivenet-app/fivenet/releases/latest/download/fivenet-linux-amd64.tar.gz
    tar -xzf fivenet-linux-amd64.tar.gz
    
  2. Create a dedicated directory for the DBSync binary or exe and configuration files.
    mkdir -p /opt/fivenet/dbsync
    mv fivenet config.example.yaml dbsync.example.yaml /opt/fivenet/dbsync/
    chmod +x /opt/fivenet/dbsync/fivenet
    
  3. Optionally: Add the fivenet binary to your system PATH to make it executable from anywhere.
    echo 'export PATH="/opt/fivenet/dbsync:$PATH"' >> ~/.bashrc
    source ~/.bashrc
    
  4. Rename the dbsync.example.yaml file to dbsync.yaml.
    cd /opt/fivenet/dbsync
    mv dbsync.example.yaml dbsync.yaml
    
  5. Edit the dbsync.yaml file to configure DBSync. You can use any text editor. For example:
    nano dbsync.yaml
    
  6. Make sure the Sync API is enabled in your main FiveNet config.yaml and that at least one sync token is configured. See the Config File Reference.
  7. You can now run the DBSync process using the fivenet dbsync command.
Once the DBSync process is running without errors, it is recommended to run DBSync as a service on your server. This way, it will automatically start on server boot and can be managed (stopped, restarted) easily.You can follow the Set Up as a Service section below for details on how to do this. For Linux, an example systemd unit can be found in Running as a Systemd Unit or Service.

Set Up as a Service

To run DBSync continuously, it is recommended to set it up as a service on your server. This way, it can start automatically on boot and be managed more easily.

This assumes you have installed the fivenet binary and that it is available in your system PATH or in a dedicated directory. If you use a dedicated directory, note the full path to the fivenet binary.

Open a terminal or command prompt and navigate to the directory that contains the fivenet binary:

cd /path/to/fivenet/directory

Then follow the platform-specific instructions below to install, start, stop, or uninstall the DBSync service.

Installing the Service

To install DBSync as a service, follow these steps:

On Linux, copy the completed dbsync.yaml configuration file to /etc/fivenet before installing the service. This ensures that the service uses the correct configuration file when it starts.

sudo mkdir -p /etc/fivenet
sudo cp dbsync.yaml /etc/fivenet/dbsync.yaml
sudo fivenet dbsync install

You can now manage the DBSync service by following the next sections.

Starting / Stopping the Service

To start or stop the DBSync service, use the following commands:

sudo fivenet dbsync start
sudo fivenet dbsync stop

# Or use systemd directly
sudo systemctl start fivenet-dbsync
sudo systemctl stop fivenet-dbsync

Uninstalling the Service

To uninstall the DBSync service, run the following command:

sudo fivenet dbsync uninstall

Configuration

DBSync is configured in the dbsync.yaml file. The sections below cover the most important parts.

Destination Configuration

The destination: section defines how DBSync connects to your FiveNet instance. Example:

destination:
  # Host + port to your FiveNet instance (requires HTTPS/valid TLS certs, unless insecure is set to `true`)
  url: "fivenet.example.com"
  token: "YOUR_SYNC_API_TOKEN"
  # Disable TLS verification (not recommended)
  insecure: false
  # Sync Interval can also be specified per table in the `tables:` section
  syncInterval: 5s

Source Configuration

The source: section contains the connection details for your gameserver database. Example:

# Changes to the source require a restart of the dbsync
source:
  # Refer to https://github.com/go-sql-driver/mysql#dsn-data-source-name for details
  # Please note that the `parseTime` parameter is always set to true
  dsn: "DB_USER:DB_PASS@tcp(DB_HOST:DB_PORT)/DB_NAME?collation=utf8mb4_unicode_ci&loc=Europe%2FBerlin"

Persisting Sync State

DBSync stores its sync state in a file called dbsync.state.yaml by default. This file tracks the last synced data. Persist it so the process does not need to resync everything after a restart.

Before starting DBSync, make sure you have enabled the Sync API and configured a sync API token in your main FiveNet config.yaml file.

The tables section is used to configure the queries for the tables you want to sync to FiveNet. See the examples below for ESX and QBCore.

If you are using another framework, adjust the queries accordingly.

Database User for Source

The database user only needs read access to the gameserver database. Example queries to create a separate user and grant read access are shown below. Replace the username, password, and database name before using them:

CREATE USER 'fivenet_dbsync'@'localhost' IDENTIFIED BY 'YOUR_DBSYNC_USER_PASSWORD';
GRANT SELECT ON `your_gameserver_db`.* TO 'fivenet_dbsync'@'localhost';

Table Queries

The queries for each table must return the columns in the format expected by DBSync. For example, user-related fields must be returned as user.COLUMN, such as user.id, user.firstname, and user.lastname.

It is especially important to return a consistent id and identifier value for users or characters. The id field identifies the user in the source database, while the identifier field is used by FiveNet to associate characters with accounts. This is also how multiple characters can be bound to one account, for example char1:LICENSE and char2:LICENSE both matching an account that stores only the LICENSE.

When using a job framework that uses separate jobs for off-duty jobs, such as off_police, see the How to Handle Off-Duty Jobs section below.

For working starting points for common frameworks, see the Example Configs section below.

Usage

To run DBSync manually, use the fivenet binary as follows:

fivenet dbsync
To see all available options and flags, you can run:
fivenet dbsync --help

Example Configs

ESX Framework

The following tables configuration snippet is based on the ESX framework and uses the DBSync's "Simple Query" generation that requires no SQL-queries.Most comments have been omitted for brevity. Make sure to check the comments in the DBSync example config for additional information and details.
tables:
  jobs:
    enabled: true
    tableName: "jobs"
    columns:
      name: "name"
      label: "label"

  jobGrades:
    enabled: true
    tableName: "job_grades"
    columns:
      jobName: "job_name"
      grade: "grade"
      name: "name"
      label: "label"

  licenses:
    enabled: true
    tableName: "licenses"
    columns:
      type: "type"
      label: "label"

  users:
    enabled: true
    tableName: "users"
    updatedTimeColumn: "last_seen"
    columns:
      id: "id"
      identifier: "identifier"
      group: "group"
      firstname: "firstname"
      lastname: "lastname"
      dateOfBirth: "dateofbirth"
      sex: "sex"
      height: "height"
      job: "job"
      jobGrade: "job_grade"
      phoneNumber: "phone_number"
    ignoreEmptyNames: true

  userLicenses:
    enabled: true
    tableName: "user_licenses"
    columns:
      type: "type"
      ownerIdentifier: "owner"

  vehicles:
    enabled: true
    tableName: "owned_vehicles"
    updatedTimeColumn: "updated_at"
    columns:
      ownerIdentifier: "owner"
      plate: "plate"
      type: "type"

QBCore Framework

Most comments have been omitted for brevity. Make sure to check the comments in the DBSync example config for additional information and details.
tables:
  jobs:
    # Must return `name`, `label` columns
    enabled: false
    query: |
      SELECT
        `jobs`.`name` AS `job.name`,
        `jobs`.`label` AS `job.label`
      FROM
        `jobs`
      ORDER BY `name`;
      LIMIT $limit;

  jobGrades:
    # Must return `job_name`, `grade`, `label` columns (with `WHERE` condition for the `job_name` (`$jobName`))
    enabled: false
    query: |
      SELECT
        `job_grades`.`job_name` AS `job_grade.job_name`,
        `job_grades`.`grade` AS `job_grade.grade`,
        `job_grades`.`label` AS `job_grade.label`
      FROM
        `job_grades`
      WHERE
        `job_name` = $jobName
      ORDER BY `job_grade.job_name`, `job_grade.grade`
      LIMIT $limit;

  licenses:
    # Must return `type`, `label` columns
    enabled: false
    query: |
      SELECT
        `licenses`.`type` AS `license.type`,
        `licenses`.`label` AS `license.label`
      FROM
        `licenses`
      ORDER BY `license.type`
      LIMIT $limit;

  users:
    enabled: false
    #updatedTimeColumn: "last_seen"
    # The identifier column should be a smart combination of values when using a multichar system.
    # E.g., it is prefered to use a ESX like identifier layout for that case `charX:LICENSE`
    query: |
      SELECT
        `players`.`id` AS `user.id`,
        CONCAT(`players`.`cid`, ':', `players`.`citizenid`) AS `user.identifier`,
        'user' AS `user.group`,
        JSON_UNQUOTE(JSON_EXTRACT(`players`.`charinfo`, '$.firstname')) AS `user.firstname`,
        JSON_UNQUOTE(JSON_EXTRACT(`players`.`charinfo`, '$.lastname')) AS `user.lastname`,
        JSON_UNQUOTE(JSON_EXTRACT(`players`.`charinfo`, '$.birthdate')) AS `user.dateofbirth`,
        JSON_UNQUOTE(JSON_EXTRACT(`players`.`charinfo`, '$.height')) AS `user.height`,
        JSON_UNQUOTE(JSON_EXTRACT(`players`.`job`, '$.name')) AS `user.job`,
        JSON_UNQUOTE(JSON_EXTRACT(`players`.`job`, '$.grade.level')) AS `user.job_grade`,
        JSON_UNQUOTE(JSON_EXTRACT(`players`.`charinfo`, '$.gender')) AS `user.sex`,
        JSON_UNQUOTE(JSON_EXTRACT(`players`.`charinfo`, '$.phone')) AS `user.phone_number`
        `players`.`last_updated` AS `user.updated_at`
      FROM
        `players`
      $whereCondition
      ORDER BY `user.updated_at` ASC, `user.id` ASC
      LIMIT $limit;
    # If a lastname is not returned by the query, attempt to split the firstname into "two" parts
    splitName: true
    # Normalize date of birth value to the output format if possible
    # Please see the Go `time` pkg documentation on potential date format layouts: https://pkg.go.dev/time#Layout
    dateOfBirth:
      formats:
        - "2006-01-02" # 2000-10-18 = YYYY-MM-DD
        - "02/01/2006" # 09/06/1993 = MM/DD/YYYY
        - "02.01.2006" # 01.08.1982 = DD.MM.YYYY
      outputFormat: "02.01.2006" # DD.MM.YYYY
    valueMapping:
      sex:
        fallback: 'm'
        values:
          '1': 'f'

  userLicenses:
    # Must return `type`, `owner` columns
    enabled: false
    query: |
      SELECT
        `user_licenses`.`type` AS `user_license.type`,
        `user_licenses`.`owner` AS `user_license.owner`
      FROM
        `user_licenses`
      WHERE
        `owner` = $identifier
      LIMIT $limit;

  vehicles:
    # Must return `owner_id` (DB User ID) or `owner_identifier`, `plate`, `type`, `model` columns
    enabled: true
        query: |
      SELECT
        IF(`player_vehicles`.job_vehicle=0, `players`.`id`, NULL) AS `vehicle.owner_identifier`,
        `player_vehicles`.`plate` AS `vehicle.plate`,
        'Fahrzeug' AS `vehicle.type`,
        `player_vehicles`.`vehicle` AS `vehicle.model`,
        IF(`player_vehicles`.`job_vehicle`=1, `players`.`id`, NULL) AS `vehicle.job`,
        `player_vehicles`.`updated_at` AS `vehicle.updated_at`
      FROM
        `player_vehicles`
        LEFT JOIN `players` ON (`players`.`citizenid` = `player_vehicles`.`citizenid`)
      $whereCondition
      ORDER BY `vehicle.updated_at` ASC, `vehicle.plate` ASC
      LIMIT $limit;

Running as a Systemd Unit or Service

Before proceeding with setting up DBSync as a service, ensure you have a basic understanding of Linux system administration.

It is recommended to run DBSync as a service on your server. For example, on Linux, you can create a systemd unit file:

[Unit]
Description=FiveNet DBSync Service
After=network.target

[Service]
ExecStart=/path/to/fivenet dbsync
Restart=always
User=fivenet
Group=fivenet

[Install]
WantedBy=multi-user.target

Save this file as /etc/systemd/system/fivenet-dbsync.service, then enable and start the service:

sudo systemctl enable fivenet-dbsync
sudo systemctl start fivenet-dbsync

Common Issues and Questions

Error Message: error during sync stream, restarting in a second

This message indicates that the DBSync connection to the FiveNet instance was closed or interrupted. If it happens only occasionally, it is usually harmless because DBSync will attempt to reconnect automatically.

Long-running connections can be closed by firewalls, load balancers, or other network devices, which can lead to this message.

How to Handle Off-Duty Jobs

If your job framework uses separate off-duty jobs, such as off_police, you can handle this in the jobs and users table configuration by using filters.

This feature will be available starting with FiveNet v2025.10.0 and higher.

Example:

tables:
  jobs:
    filters:
      # Example filter to drop jobs starting with "off_", to enable uncomment this section
      # This is useful in combination with the `users:` jobs filters below if you
      # have "off-duty" jobs that need to be rewritten to their "actual" job name
      #
      # Drop in this context means that the dbsync won't send the job to FiveNet
      - pattern: '^off_'
        action: drop
# [...]
  users:
    # Filters allow to modify certain values before they are sent to FiveNet
    filters:
      jobs:
        # Example: `off_police` -> `police`
        - pattern: '^off_'
          # Search for the pattern and replace (`action: replace`) it...
          action: replace
          # with an empty string (`replacement: ''`)
          replacement: ''
Copyright © 2026 Galexrt All rights reserved. All trademarks, logos and brand names are the property of their respective owners.