> FiveM QBCore Framework Complete Setup Guide

Set up the QBCore Framework on your FiveM server. Learn installation, configuration, essential scripts, and customization for your RP server.

Advanced
3 hours

FiveM QBCore Framework Complete Setup Guide

QBCore is the most actively developed roleplay framework for FiveM, powering thousands of RP servers. This guide walks you through a complete setup from database to fully configured server with essential resources.

What is QBCore?

QBCore is a modern, open-source FiveM framework built for roleplay servers. It provides the core systems every RP server needs: character creation, jobs, inventory, economy, vehicles, housing, and more. Developed by the community at github.com/qbcore-framework, QBCore has become the standard choice for new FiveM RP servers.

Key features of QBCore:

  • >Modular resource system with clean dependency chains
  • >Built-in multi-character support
  • >Comprehensive job and gang systems
  • >Modern inventory with item metadata
  • >Active development and community support
  • >Performance-focused design with minimal idle overhead
---

QBCore vs ESX Comparison

If you are deciding between QBCore and ESX, this comparison covers the major differences.

FeatureQBCoreESX Legacy
Active DevelopmentVery active (2024-2026)Maintenance mode
PerformanceOptimized, lower idle resource usageHeavier baseline footprint
Learning CurveModerate -- good documentationEasier -- more tutorials available
Community SizeLarge and growingVery large but declining
Multi-CharacterBuilt-in (qb-multicharacter)Requires addon
Database Connectoroxmysql (standard)oxmysql or mysql-async
Item SystemMetadata-based itemsSimpler item definitions
Job SystemGrades, gangs, duty toggle built-inBasic job grades
Code QualityModern Lua patterns, consistent styleVaries by version
Free ResourcesHundreds available on GitHubThousands available
Paid ResourcesGrowing marketplaceLargest marketplace
Migration PathCan convert ESX resourcesEstablished ecosystem
Recommendation: For new servers in 2025-2026, QBCore is the better choice. It has more active development, better performance defaults, and a growing resource ecosystem.

---

Prerequisites

Before starting, make sure you have the following ready:

  • >A working FiveM server with artifacts installed and server.cfg configured (see our FiveM Server Setup Guide)
  • >MySQL or MariaDB database server installed and accessible
  • >Basic Lua knowledge for configuration and troubleshooting
  • >Git installed on your server for cloning repositories
  • >A text editor such as VS Code, Notepad++, or nano
ComponentMinimumRecommended
CPU4 cores6+ cores
RAM8 GB16 GB
Storage50 GB SSD100 GB NVMe
Bandwidth20 Mbps100 Mbps
DatabaseMySQL 5.7MariaDB 10.6+
---

Step 1: Database Setup for QBCore

QBCore stores all persistent data -- players, vehicles, housing, inventories -- in a MySQL or MariaDB database.

MySQL/MariaDB Installation

Linux (Ubuntu/Debian):

Bash
# Install MariaDB (recommended over MySQL for FiveM)
sudo apt update
sudo apt install mariadb-server mariadb-client -y

# Secure the installation
sudo mysql_secure_installation

# Start and enable the service
sudo systemctl start mariadb
sudo systemctl enable mariadb

Windows:

  • 1.Download MariaDB or MySQL Community Server
  • 2.Run the installer and set a root password
  • 3.Ensure the service starts automatically
  • Creating the Database

    Connect to your database server and create the QBCore database:

    SQL
    -- Connect to MySQL/MariaDB
    -- Linux: sudo mysql -u root -p
    -- Windows: mysql -u root -p
    
    -- Create database
    CREATE DATABASE qbcoreframework;
    
    -- Create a dedicated user (do not use root for your server)
    CREATE USER 'qbcore'@'localhost' IDENTIFIED BY 'YourStrongPassword123';
    
    -- Grant permissions
    GRANT ALL PRIVILEGES ON qbcoreframework.* TO 'qbcore'@'localhost';
    FLUSH PRIVILEGES;
    
    -- Verify
    SHOW DATABASES;
    

    oxmysql Resource Setup

    oxmysql is the standard database connector for QBCore. It replaces the older mysql-async and ghmattimysql libraries.

  • 1.Download the latest release from github.com/overextended/oxmysql/releases
  • 2.Extract to your resources folder: resources/[standalone]/oxmysql/
  • Add the connection string to your server.cfg:

    Config
    # Database connection -- add this BEFORE any resource that uses the database
    set mysql_connection_string "mysql://qbcore:YourStrongPassword123@localhost/qbcoreframework?charset=utf8mb4"
    
    # Start oxmysql before everything else
    ensure oxmysql
    

    Connection string format:

    mysql://USERNAME:PASSWORD@HOST/DATABASE?charset=utf8mb4
    

    Test the connection by starting your server and checking the console for:

    [oxmysql] Successfully connected to the database
    

    If you see connection errors, verify your username, password, and database name.

    ---

    Step 2: Installing QBCore

    Download from GitHub

    The recommended approach is to download the complete QBCore resource package from the official repository.

    Bash
    # Navigate to your server resources directory
    cd /path/to/server-data/resources
    
    # Clone the QBCore framework resources
    # Each resource is a separate repository under the qbcore-framework organization
    
    # Create category folders
    mkdir -p [qb]
    cd [qb]
    
    # Clone core resources
    git clone https://github.com/qbcore-framework/qb-core.git
    git clone https://github.com/qbcore-framework/qb-multicharacter.git
    git clone https://github.com/qbcore-framework/qb-spawn.git
    git clone https://github.com/qbcore-framework/qb-hud.git
    git clone https://github.com/qbcore-framework/qb-inventory.git
    git clone https://github.com/qbcore-framework/qb-phone.git
    git clone https://github.com/qbcore-framework/qb-banking.git
    git clone https://github.com/qbcore-framework/qb-clothing.git
    git clone https://github.com/qbcore-framework/qb-houses.git
    git clone https://github.com/qbcore-framework/qb-vehicleshop.git
    git clone https://github.com/qbcore-framework/qb-policejob.git
    git clone https://github.com/qbcore-framework/qb-ambulancejob.git
    git clone https://github.com/qbcore-framework/qb-mechanicjob.git
    git clone https://github.com/qbcore-framework/qb-adminmenu.git
    git clone https://github.com/qbcore-framework/qb-input.git
    git clone https://github.com/qbcore-framework/qb-menu.git
    git clone https://github.com/qbcore-framework/qb-target.git
    git clone https://github.com/qbcore-framework/qb-radialmenu.git
    git clone https://github.com/qbcore-framework/qb-smallresources.git
    git clone https://github.com/qbcore-framework/qb-weathersync.git
    

    Alternative: Download the txAdmin QBCore recipe for a one-click setup through txAdmin.

    File Structure Overview

    After installation, your resources folder should look like this:

    resources/
    ├── [standalone]/
    │   └── oxmysql/
    ├── [qb]/
    │   ├── qb-core/
    │   │   ├── client/
    │   │   ├── server/
    │   │   ├── shared/
    │   │   │   ├── main.lua        # Jobs, gangs, vehicles, items
    │   │   │   ├── items.lua       # Item definitions
    │   │   │   ├── jobs.lua        # Job definitions
    │   │   │   ├── gangs.lua       # Gang definitions
    │   │   │   └── vehicles.lua    # Vehicle definitions
    │   │   └── fxmanifest.lua
    │   ├── qb-multicharacter/
    │   ├── qb-spawn/
    │   ├── qb-hud/
    │   ├── qb-inventory/
    │   ├── qb-phone/
    │   ├── qb-banking/
    │   ├── qb-clothing/
    │   ├── qb-policejob/
    │   ├── qb-ambulancejob/
    │   └── [other qb resources]/
    └── [maps]/
    

    server.cfg Resource Order

    Resource load order matters. QBCore resources have dependencies that must be respected. Load them in this order in your server.cfg:

    Config
    # ============================================
    # QBCore Server Configuration
    # ============================================
    
    # Server identity
    endpoint_add_tcp "0.0.0.0:30120"
    endpoint_add_udp "0.0.0.0:30120"
    
    sv_licensekey "your-license-key"
    sv_hostname "My QBCore RP Server"
    sv_maxclients 64
    
    sets sv_projectName "My RP Community"
    sets sv_projectDesc "A QBCore roleplay experience"
    
    # OneSync (required for QBCore)
    set onesync on
    
    # ============================================
    # 1. Database -- must load first
    # ============================================
    set mysql_connection_string "mysql://qbcore:YourStrongPassword123@localhost/qbcoreframework?charset=utf8mb4"
    ensure oxmysql
    
    # ============================================
    # 2. Core framework -- depends on database
    # ============================================
    ensure qb-core
    
    # ============================================
    # 3. Core UI and interaction systems
    # ============================================
    ensure qb-input
    ensure qb-menu
    ensure qb-target
    ensure qb-radialmenu
    
    # ============================================
    # 4. Character and spawn systems
    # ============================================
    ensure qb-multicharacter
    ensure qb-spawn
    ensure qb-clothing
    
    # ============================================
    # 5. HUD and player interface
    # ============================================
    ensure qb-hud
    ensure qb-inventory
    ensure qb-phone
    ensure qb-banking
    
    # ============================================
    # 6. Jobs and economy
    # ============================================
    ensure qb-policejob
    ensure qb-ambulancejob
    ensure qb-mechanicjob
    ensure qb-vehicleshop
    ensure qb-houses
    
    # ============================================
    # 7. Utility resources
    # ============================================
    ensure qb-smallresources
    ensure qb-weathersync
    ensure qb-adminmenu
    
    # ============================================
    # 8. Permissions
    # ============================================
    add_ace group.admin command allow
    add_ace group.admin command.quit deny
    add_principal identifier.license:YOUR_LICENSE_HERE group.admin
    

    Critical rule: oxmysql must load before qb-core, and qb-core must load before any other QBCore resource. Getting this wrong causes cascading errors.

    ---

    Step 3: Core Configuration

    QBCore's behavior is controlled through configuration files in the qb-core resource. These define your server's economy, jobs, items, and gameplay rules.

    qb-core/shared/jobs.lua

    This file defines every job available on your server. Each job has a label, default duty status, and grade levels with salaries.

    Lua
    -- qb-core/shared/jobs.lua
    QBShared.Jobs = {
        ['unemployed'] = {
            label = 'Civilian',
            defaultDuty = true,
            offDutyPay = false,
            grades = {
                ['0'] = { name = 'Unemployed', payment = 10 },
            },
        },
        ['police'] = {
            label = 'Law Enforcement',
            defaultDuty = true,
            offDutyPay = false,
            grades = {
                ['0'] = { name = 'Recruit',    payment = 50 },
                ['1'] = { name = 'Officer',    payment = 75 },
                ['2'] = { name = 'Sergeant',   payment = 100 },
                ['3'] = { name = 'Lieutenant', payment = 125 },
                ['4'] = { name = 'Chief',      payment = 150 },
            },
        },
        ['ambulance'] = {
            label = 'EMS',
            defaultDuty = true,
            offDutyPay = false,
            grades = {
                ['0'] = { name = 'Recruit',    payment = 50 },
                ['1'] = { name = 'Paramedic',  payment = 75 },
                ['2'] = { name = 'Doctor',     payment = 100 },
                ['3'] = { name = 'Surgeon',    payment = 125 },
                ['4'] = { name = 'Chief',      payment = 150 },
            },
        },
        ['mechanic'] = {
            label = 'Mechanic',
            defaultDuty = true,
            offDutyPay = false,
            grades = {
                ['0'] = { name = 'Apprentice', payment = 40 },
                ['1'] = { name = 'Mechanic',   payment = 60 },
                ['2'] = { name = 'Manager',    payment = 80 },
                ['3'] = { name = 'Owner',      payment = 100 },
            },
        },
        ['realestate'] = {
            label = 'Real Estate',
            defaultDuty = true,
            offDutyPay = false,
            grades = {
                ['0'] = { name = 'Agent',   payment = 50 },
                ['1'] = { name = 'Broker',  payment = 75 },
                ['2'] = { name = 'Manager', payment = 100 },
            },
        },
    }
    

    qb-core/shared/gangs.lua

    Gangs work similarly to jobs but are designed for criminal organizations.

    Lua
    -- qb-core/shared/gangs.lua
    QBShared.Gangs = {
        ['none'] = {
            label = 'No Gang',
            grades = {
                ['0'] = { name = 'Unaffiliated' },
            },
        },
        ['lostmc'] = {
            label = 'The Lost MC',
            grades = {
                ['0'] = { name = 'Hangaround' },
                ['1'] = { name = 'Prospect' },
                ['2'] = { name = 'Patched Member' },
                ['3'] = { name = 'Sergeant at Arms' },
                ['4'] = { name = 'Vice President' },
                ['5'] = { name = 'President' },
            },
        },
        ['ballas'] = {
            label = 'Ballas',
            grades = {
                ['0'] = { name = 'Recruit' },
                ['1'] = { name = 'Enforcer' },
                ['2'] = { name = 'Soldier' },
                ['3'] = { name = 'Shot Caller' },
                ['4'] = { name = 'OG' },
            },
        },
    }
    

    qb-core/shared/items.lua

    Items define everything players can hold in their inventory. Each item has a name, label, weight, type, and optional image.

    Lua
    -- qb-core/shared/items.lua (partial example)
    QBShared.Items = {
        -- Weapons
        ['weapon_pistol']          = { name = 'weapon_pistol',          label = 'Walther P99',        weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL',   image = 'weapon_pistol.png',          unique = true,  useable = false, shouldClose = false, combinable = nil, description = 'A compact pistol' },
        ['weapon_combatpistol']    = { name = 'weapon_combatpistol',    label = 'Combat Pistol',      weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL',   image = 'weapon_combatpistol.png',    unique = true,  useable = false, shouldClose = false, combinable = nil, description = 'Combat pistol' },
    
        -- General items
        ['phone']                  = { name = 'phone',                  label = 'Phone',              weight = 500,  type = 'item', image = 'phone.png',                  unique = true,  useable = true,  shouldClose = true,  combinable = nil, description = 'A mobile phone' },
        ['radio']                  = { name = 'radio',                  label = 'Radio',              weight = 500,  type = 'item', image = 'radio.png',                  unique = true,  useable = true,  shouldClose = true,  combinable = nil, description = 'A handheld radio' },
        ['id_card']                = { name = 'id_card',                label = 'ID Card',            weight = 0,    type = 'item', image = 'id_card.png',                unique = true,  useable = true,  shouldClose = false, combinable = nil, description = 'Identification card' },
        ['driver_license']         = { name = 'driver_license',         label = 'Drivers License',    weight = 0,    type = 'item', image = 'driver_license.png',         unique = true,  useable = true,  shouldClose = false, combinable = nil, description = 'Drivers license' },
    
        -- Food and drink
        ['sandwich']               = { name = 'sandwich',               label = 'Sandwich',           weight = 200,  type = 'item', image = 'sandwich.png',               unique = false, useable = true,  shouldClose = true,  combinable = nil, description = 'A tasty sandwich' },
        ['water_bottle']           = { name = 'water_bottle',           label = 'Water Bottle',       weight = 500,  type = 'item', image = 'water_bottle.png',           unique = false, useable = true,  shouldClose = true,  combinable = nil, description = 'Refreshing water' },
    
        -- Crafting materials
        ['metalscrap']             = { name = 'metalscrap',             label = 'Metal Scrap',        weight = 100,  type = 'item', image = 'metalscrap.png',             unique = false, useable = false, shouldClose = false, combinable = nil, description = 'Scrap metal for crafting' },
        ['plastic']                = { name = 'plastic',                label = 'Plastic',            weight = 100,  type = 'item', image = 'plastic.png',                unique = false, useable = false, shouldClose = false, combinable = nil, description = 'Plastic material' },
    }
    

    qb-core/server/config.lua

    Server-side configuration controls economy settings, starting items, and server behavior.

    Lua
    -- qb-core/server/config.lua (key settings)
    QBConfig = {}
    
    -- Money types available in the economy
    QBConfig.Money = {}
    QBConfig.Money.Types = {
        cash = { minimum = 0, default = 500 },       -- Starting cash
        bank = { minimum = 0, default = 5000 },       -- Starting bank balance
        crypto = { minimum = 0, default = 0 },         -- Cryptocurrency
    }
    
    -- Payment interval for jobs (in minutes)
    QBConfig.Money.PaycheckInterval = 15
    
    -- Items given to new characters on first spawn
    QBConfig.StarterItems = {
        { name = 'phone',          amount = 1 },
        { name = 'id_card',        amount = 1 },
        { name = 'driver_license', amount = 1 },
        { name = 'sandwich',       amount = 3 },
        { name = 'water_bottle',   amount = 3 },
    }
    
    -- Server settings
    QBConfig.Server = {}
    QBConfig.Server.Closed = false                   -- Whitelist mode
    QBConfig.Server.ClosedReason = 'Server is closed for maintenance'
    QBConfig.Server.Uptime = 0
    QBConfig.Server.PVP = true
    QBConfig.Server.Discord = 'https://discord.gg/your-invite'
    QBConfig.Server.CheckDuplicateLicense = true
    QBConfig.Server.Permissions = { 'god', 'admin', 'mod' }
    

    qb-core/client/config.lua

    Client-side configuration handles visual elements and player experience.

    Lua
    -- qb-core/client/config.lua (key settings)
    QBConfig = {}
    
    QBConfig.Client = {}
    QBConfig.Client.StatusInterval = 5000             -- How often status updates (ms)
    QBConfig.Client.DefaultSpawn = {
        x = -1035.71, y = -2731.87, z = 12.86, heading = 330.0
    }
    

    ---

    Step 4: Essential QBCore Resources

    Each QBCore resource handles a specific system. Here is what the essential resources do and how to configure them.

    qb-multicharacter (Character Selection)

    Allows players to create and manage multiple characters per account. Players see a character selection screen on join.

    Key configuration in qb-multicharacter/config.lua:

    Lua
    Config = {}
    Config.MaxCharacters = 5                           -- Characters per player
    Config.Interior = vector4(-814.49, 181.98, 72.16, 202.86) -- Selection room location
    Config.DefaultNumberOfCharacters = 2               -- Free character slots
    Config.PlayersNumberOfCharacters = {
        -- Steam or license identifier = number of slots
        -- ['steam:xxxx'] = 5,
    }
    

    qb-spawn (Spawn Selection)

    Handles where players spawn after selecting a character. Options include last location or a default spawn point.

    qb-hud (HUD System)

    Displays health, armor, hunger, thirst, and other status bars. Most servers customize the HUD appearance.

    qb-inventory (Inventory System)

    The inventory system supports item metadata, weapon attachments, and drag-and-drop functionality.

    Key features:

    • >Weight-based inventory (not slot-based)
    • >Item metadata for unique items (serial numbers on weapons, expiration on food)
    • >Crafting integration
    • >Shop system
    • >Drop/pickup system

    qb-phone (Phone System)

    An in-game smartphone with apps for messaging, calling, banking, Twitter-style social media, and more. The phone is a central interface for player interaction.

    qb-banking (Banking)

    Full banking system with personal accounts, shared accounts, and ATM locations throughout the map.

    qb-policejob and qb-ambulancejob (Emergency Services)

    Complete job scripts for police and EMS with features like:

    • >Duty toggle at specific locations
    • >Evidence collection (police)
    • >Vehicle impounding (police)
    • >Heal and revive mechanics (EMS)
    • >Armory access with rank-restricted equipment
    • >Jail system integration (police)

    qb-mechanicjob (Civilian Jobs)

    Mechanic job with vehicle repair functionality, part installation, and a garage system for storing customer vehicles.

    qb-clothing (Character Customization)

    Full character appearance customization including face features, hair, and clothing. Players access this during character creation and at clothing stores in-game.

    qb-houses (Housing System)

    Property system allowing players to purchase, furnish, and store items in houses throughout the map.

    qb-vehicleshop (Dealerships)

    Vehicle purchasing system with multiple dealership locations, test drives, and financing options.

    ---

    Step 5: Adding Custom Jobs

    One of the first things server owners want to do is add custom jobs. Here is the complete process.

    Job Configuration in shared/jobs.lua

    Add your new job definition to qb-core/shared/jobs.lua:

    Lua
    -- Add to QBShared.Jobs table
    ['trucker'] = {
        label = 'Trucker',
        defaultDuty = true,
        offDutyPay = false,
        grades = {
            ['0'] = { name = 'Trainee',       payment = 30 },
            ['1'] = { name = 'Driver',        payment = 50 },
            ['2'] = { name = 'Senior Driver', payment = 70 },
            ['3'] = { name = 'Fleet Manager', payment = 90 },
        },
    },
    

    Creating a Basic Job Script

    Create a new resource for your custom job.

    Directory structure:

    resources/[qb]/qb-truckerjob/
    ├── fxmanifest.lua
    ├── client/
    │   └── main.lua
    ├── server/
    │   └── main.lua
    └── config.lua
    

    fxmanifest.lua:

    Lua
    fx_version 'cerulean'
    game 'gta5'
    
    description 'QBCore Trucker Job'
    version '1.0.0'
    
    shared_scripts {
        '@qb-core/shared/locale.lua',
        'config.lua',
    }
    
    client_scripts {
        'client/main.lua',
    }
    
    server_scripts {
        '@oxmysql/lib/MySQL.lua',
        'server/main.lua',
    }
    
    lua54 'yes'
    

    config.lua:

    Lua
    Config = {}
    
    Config.TruckDepot = vector4(152.69, -3210.88, 5.91, 270.46)
    Config.DeliveryLocations = {
        { coords = vector4(171.29, -1553.86, 29.26, 315.0), label = 'Warehouse A', payment = 200 },
        { coords = vector4(-53.09, -2519.87, 6.01, 325.0),  label = 'Warehouse B', payment = 350 },
        { coords = vector4(810.37, -2977.74, 6.02, 90.0),   label = 'Warehouse C', payment = 500 },
    }
    
    Config.TruckModel = 'hauler'
    Config.TrailerModel = 'trailers'
    

    client/main.lua:

    Lua
    local QBCore = exports['qb-core']:GetCoreObject()
    local onDuty = false
    local currentRoute = nil
    local truck = nil
    local blip = nil
    
    -- Create depot blip on map
    CreateThread(function()
        local depotBlip = AddBlipForCoord(Config.TruckDepot.x, Config.TruckDepot.y, Config.TruckDepot.z)
        SetBlipSprite(depotBlip, 477)
        SetBlipColour(depotBlip, 5)
        SetBlipScale(depotBlip, 0.7)
        SetBlipAsShortRange(depotBlip, true)
        BeginTextCommandSetBlipName('STRING')
        AddTextComponentString('Truck Depot')
        EndTextCommandSetBlipName(depotBlip)
    end)
    
    -- Toggle duty at depot
    RegisterNetEvent('qb-truckerjob:client:toggleDuty', function()
        local PlayerData = QBCore.Functions.GetPlayerData()
    
        if PlayerData.job.name ~= 'trucker' then
            QBCore.Functions.Notify('You are not a trucker', 'error')
            return
        end
    
        onDuty = not onDuty
    
        if onDuty then
            QBCore.Functions.Notify('You are now on duty', 'success')
            startRoute()
        else
            QBCore.Functions.Notify('You are now off duty', 'primary')
            cleanupRoute()
        end
    end)
    
    function startRoute()
        -- Pick a random delivery location
        local routeIndex = math.random(1, #Config.DeliveryLocations)
        currentRoute = Config.DeliveryLocations[routeIndex]
    
        -- Spawn truck
        local hash = GetHashKey(Config.TruckModel)
        RequestModel(hash)
        while not HasModelLoaded(hash) do Wait(100) end
    
        local playerPed = PlayerPedId()
        local coords = GetEntityCoords(playerPed)
        truck = CreateVehicle(hash, coords.x + 5, coords.y, coords.z, 0.0, true, false)
        SetModelAsNoLongerNeeded(hash)
    
        QBCore.Functions.Notify('Deliver to: ' .. currentRoute.label, 'primary', 5000)
    
        -- Create delivery blip
        blip = AddBlipForCoord(currentRoute.coords.x, currentRoute.coords.y, currentRoute.coords.z)
        SetBlipSprite(blip, 1)
        SetBlipColour(blip, 3)
        SetBlipRoute(blip, true)
        BeginTextCommandSetBlipName('STRING')
        AddTextComponentString('Delivery: ' .. currentRoute.label)
        EndTextCommandSetBlipName(blip)
    
        -- Monitor delivery
        CreateThread(function()
            while onDuty and currentRoute do
                local playerCoords = GetEntityCoords(PlayerPedId())
                local dist = #(playerCoords - vector3(currentRoute.coords.x, currentRoute.coords.y, currentRoute.coords.z))
    
                if dist < 10.0 then
                    QBCore.Functions.Notify('Delivery complete!', 'success')
                    TriggerServerEvent('qb-truckerjob:server:completeDelivery', currentRoute.payment)
                    cleanupRoute()
    
                    -- Start next route after a delay
                    Wait(5000)
                    if onDuty then startRoute() end
                    return
                end
    
                Wait(1000)
            end
        end)
    end
    
    function cleanupRoute()
        currentRoute = nil
        if blip then RemoveBlip(blip) blip = nil end
        if truck and DoesEntityExist(truck) then
            DeleteVehicle(truck)
            truck = nil
        end
    end
    

    server/main.lua:

    Lua
    ensure qb-truckerjob
    

    ---

    Step 6: Vehicle Configuration

    Adding Vehicles to shared/vehicles.lua

    Vehicles are defined in qb-core/shared/vehicles.lua. Each vehicle entry maps a spawn name to its display properties and category.

    Lua
    -- qb-core/shared/vehicles.lua (add new entries)
    QBShared.Vehicles = {
        -- Format: ['spawn_name'] = { properties }
    
        -- Sports cars
        ['adder'] = {
            name = 'Adder',
            brand = 'Truffade',
            model = 'adder',
            price = 250000,
            category = 'super',
            categoryLabel = 'Super',
            hash = `adder`,
            shop = 'pdm',
            type = 'automobile',
        },
        ['zentorno'] = {
            name = 'Zentorno',
            brand = 'Pegassi',
            model = 'zentorno',
            price = 200000,
            category = 'super',
            categoryLabel = 'Super',
            hash = `zentorno`,
            shop = 'pdm',
            type = 'automobile',
        },
    
        -- Sedans
        ['sultan'] = {
            name = 'Sultan',
            brand = 'Karin',
            model = 'sultan',
            price = 35000,
            category = 'sedan',
            categoryLabel = 'Sedan',
            hash = `sultan`,
            shop = 'pdm',
            type = 'automobile',
        },
    
        -- Emergency vehicles (not purchasable -- no shop field)
        ['police'] = {
            name = 'Police Cruiser',
            brand = 'Vapid',
            model = 'police',
            price = 0,
            category = 'emergency',
            categoryLabel = 'Emergency',
            hash = `police`,
            type = 'automobile',
        },
        ['ambulance'] = {
            name = 'Ambulance',
            brand = 'Brute',
            model = 'ambulance',
            price = 0,
            category = 'emergency',
            categoryLabel = 'Emergency',
            hash = `ambulance`,
            type = 'automobile',
        },
    }
    

    Vehicle Shop Categories

    The qb-vehicleshop resource reads vehicle categories from the shared vehicles file. Categories group vehicles in the dealership UI.

    Common categories:

    CategoryLabelDescription
    superSuperHigh-end supercars
    sportsSportsSports cars
    sedanSedanFour-door sedans
    suvSUVSUVs and trucks
    muscleMuscleAmerican muscle cars
    coupeCoupeTwo-door coupes
    motorcycleMotorcycleBikes
    offroadOff-RoadOff-road vehicles
    vanVanVans and utility vehicles
    emergencyEmergencyPolice, EMS (not purchasable)
    To add a new vehicle to the shop, set the shop field to the dealership name (default is 'pdm' for Premium Deluxe Motorsport).

    ---

    Step 7: Admin Tools

    qb-adminmenu

    QBCore includes an admin menu accessible by players with admin permissions.

    Setting up admin permissions in server.cfg:

    Config
    # Permission levels
    add_ace group.god command allow
    add_ace group.admin command allow
    add_ace group.admin command.quit deny
    add_ace group.mod command allow
    
    # Inheritance
    add_principal group.admin group.mod
    add_principal group.god group.admin
    
    # Assign players to groups (use license, steam, or discord identifier)
    add_principal identifier.license:YOUR_LICENSE_ID group.god
    add_principal identifier.steam:YOUR_STEAM_HEX group.admin
    add_principal identifier.discord:YOUR_DISCORD_ID group.mod
    

    Admin menu features:

    • >Teleport to players and waypoints
    • >Spawn vehicles
    • >Give items and money
    • >Set jobs and gangs
    • >Revive and heal players
    • >Toggle god mode and noclip
    • >Ban and kick players
    • >View server resources

    txAdmin Integration

    txAdmin is a full-featured web panel that comes bundled with FiveM artifacts. It provides server management beyond what the admin menu offers.

    txAdmin features for QBCore:

    • >Live server console with command execution
    • >Player management (kick, ban, warn, DM)
    • >Scheduled restarts with player warnings
    • >Resource management (start, stop, restart)
    • >Performance monitoring graphs
    • >Discord webhook integration
    • >Automatic server restarts on crash
    Access txAdmin:

    http://your-server-ip:40120
    

    Permission Levels in QBCore

    QBCore uses its own permission system alongside FiveM's ACE system.

    Lua
    -- In qb-core, permissions are defined in server/config.lua
    QBConfig.Server.Permissions = { 'god', 'admin', 'mod' }
    

    Setting permissions via the admin menu or server console:

    Bash
    # In-game or txAdmin console
    add_principal identifier.license:xxxx group.admin
    

    ---

    Troubleshooting Common QBCore Issues

    Database Migration Errors

    Symptom: Server fails to start with SQL errors in console.

    Common causes and fixes:

    SQL
    -- Check if the database exists
    SHOW DATABASES;
    
    -- Verify tables were created
    USE qbcoreframework;
    SHOW TABLES;
    
    -- If tables are missing, import the SQL file from qb-core
    -- Located at: qb-core/sql/qb-core.sql
    SOURCE /path/to/qb-core/sql/qb-core.sql;
    

    Check the oxmysql connection:

    Config
    # Verify your connection string format in server.cfg
    set mysql_connection_string "mysql://qbcore:YourStrongPassword123@localhost/qbcoreframework?charset=utf8mb4"
    

    Common database errors:

    ErrorCauseFix
    Access deniedWrong username/passwordVerify MySQL credentials
    Unknown databaseDatabase does not existRun CREATE DATABASE qbcoreframework;
    Table doesn't existSQL not importedImport qb-core.sql and resource SQL files
    Connection refusedMySQL not runningStart the MySQL/MariaDB service

    Resource Dependency Issues

    Symptom: Resources fail to start, console shows Could not find resource errors.

    Fixes:

  • 1.Check that qb-core loads before all other QBCore resources
  • 2.Verify all required dependencies are installed and ensure-d
  • 3.Check fxmanifest.lua for each resource to see its dependencies
  • 4.Make sure folder names match exactly (case-sensitive on Linux)
  • Bash
    # Check for missing resources by reviewing fxmanifest files
    grep -r "dependency" resources/[qb]/*/fxmanifest.lua
    

    Script Conflicts

    Symptom: Features break or behave unexpectedly after adding new resources.

    Diagnosis steps:

  • 1.Check the server console for Lua errors after startup
  • 2.Look for duplicate event names across resources
  • 3.Check for multiple resources modifying the same game feature
  • 4.Test by disabling resources one at a time
  • Bash
    # Search for duplicate event registrations
    grep -rn "RegisterNetEvent" resources/[qb]/ | grep "eventName" | sort
    

    Memory Leaks from Poorly Coded Resources

    Symptom: Server RAM usage increases continuously over time.

    Common causes:

    • >Client-side threads without proper Wait() calls
    • >Entity spawning without cleanup
    • >Unclosed event handlers
    • >Tables that grow without bounds
    Identifying the problem:

    Lua
    -- Add this debug command to check resource memory usage
    RegisterCommand('checkmem', function()
        local resources = GetNumResources()
        for i = 0, resources - 1 do
            local name = GetResourceByFindIndex(i)
            if GetResourceState(name) == 'started' then
                print(name .. ': ' .. collectgarbage('count') .. ' KB')
            end
        end
    end, true)
    

    Prevention tips for custom scripts:

    Lua
    -- GOOD: Thread with proper wait
    CreateThread(function()
        while true do
            local sleep = 1000  -- Default sleep
            local playerCoords = GetEntityCoords(PlayerPedId())
    
            -- Only do expensive work when needed
            if isNearTarget then
                sleep = 0  -- Reduce sleep only when necessary
                -- Do work here
            end
    
            Wait(sleep)
        end
    end)
    
    -- BAD: Thread with no wait (causes high CPU)
    -- CreateThread(function()
    --     while true do
    --         -- This runs every frame with no sleep!
    --         doExpensiveWork()
    --     end
    -- end)
    

    ---

    Performance Tips for QBCore Servers

    Resource Optimization

  • 1.Only run resources you actually use. Every ensure line adds overhead. Remove resources you have not configured.
  • 2.Use lua54 'yes' in fxmanifest.lua. Lua 5.4 is faster than Lua 5.3 for most operations.
  • 3.Minimize client-side threads. Every CreateThread with Wait(0) runs every frame. Use longer wait times when real-time updates are not needed.
  • Database Performance

    SQL
    -- Add indexes to frequently queried columns
    ALTER TABLE players ADD INDEX idx_citizenid (citizenid);
    ALTER TABLE player_vehicles ADD INDEX idx_citizenid (citizenid);
    ALTER TABLE player_houses ADD INDEX idx_citizenid (citizenid);
    
    -- Clean up old data periodically
    DELETE FROM player_vehicles WHERE citizenid NOT IN (SELECT citizenid FROM players);
    

    OneSync Configuration

    OneSync is required for QBCore and should be tuned for your player count.

    Config
    # server.cfg OneSync settings
    set onesync on
    
    # Entity culling distances -- reduce for better performance
    set onesync_distanceCullVehicles 500
    set onesync_distanceCullPeds 300
    
    # Population management
    set onesync_population true
    

    Server Restart Schedule

    Regular restarts prevent memory buildup and clear accumulated state.

    Config
    # In txAdmin, set up a restart schedule:
    # Recommended: Every 6-8 hours
    # Example: 00:00, 06:00, 12:00, 18:00
    

    Linux systemd timer for scheduled restarts:

    INI
    # /etc/systemd/system/fivem-restart.timer
    [Unit]
    Description=FiveM Server Restart Timer
    
    [Timer]
    OnCalendar=*-*-* 00,06,12,18:00:00
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    

    INI
    # /etc/systemd/system/fivem-restart.service
    [Unit]
    Description=FiveM Server Restart
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/systemctl restart fivem
    

    Bash
    sudo systemctl enable fivem-restart.timer
    sudo systemctl start fivem-restart.timer
    

    General Performance Checklist

    • >[ ] OneSync is enabled and configured
    • >[ ] oxmysql is the database connector (not mysql-async)
    • >[ ] Only necessary resources are running
    • >[ ] Custom scripts use proper Wait() values in threads
    • >[ ] Database has indexes on frequently queried columns
    • >[ ] Server restarts on a regular schedule
    • >[ ] txAdmin monitoring is active
    • >[ ] Player count matches hardware capacity
    • >[ ] Vehicle and ped culling distances are set appropriately
    • >[ ] No resources are throwing repeated errors in console
    ---

    Conclusion

    Setting up a QBCore server takes time, but the result is a full-featured RP environment with modern systems and active community support. Start with the core resources, get them working correctly, then add custom jobs and features one at a time.

    Next steps after setup:

    • >Configure individual job scripts for your server's theme
    • >Add custom vehicles and clothing
    • >Set up a Discord bot for server status
    • >Create custom scripts for unique RP scenarios
    • >Join the QBCore Discord for community support
    For more information, visit the QBCore GitHub, the QBCore Documentation, and the FiveM Documentation.

    .. payment .. ' for the delivery', 'success') end) " onclick="navigator.clipboard.writeText(this.dataset.code).then(()=>{this.querySelector('.copy-icon').style.display='none';this.querySelector('.check-icon').style.display='block';setTimeout(()=>{this.querySelector('.copy-icon').style.display='block';this.querySelector('.check-icon').style.display='none'},2000)})">
    local QBCore = exports['qb-core']:GetCoreObject()
    
    RegisterNetEvent('qb-truckerjob:server:completeDelivery', function(payment)
        local src = source
        local Player = QBCore.Functions.GetPlayer(src)
    
        if not Player then return end
        if Player.PlayerData.job.name ~= 'trucker' then return end
    
        -- Validate payment amount (server-side check)
        local validPayment = false
        for _, location in pairs(Config.DeliveryLocations) do
            if location.payment == payment then
                validPayment = true
                break
            end
        end
    
        if not validPayment then return end
    
        -- Pay the player
        Player.Functions.AddMoney('bank', payment, 'trucker-delivery')
        TriggerClientEvent('QBCore:Notify', src, 'You earned %%CODEBLOCK_19%%#x27; .. payment .. ' for the delivery', 'success')
    end)
    

    Add the resource to your server.cfg:

    %%CODEBLOCK_20%%

    ---

    Step 6: Vehicle Configuration

    Adding Vehicles to shared/vehicles.lua

    Vehicles are defined in qb-core/shared/vehicles.lua. Each vehicle entry maps a spawn name to its display properties and category.

    %%CODEBLOCK_21%%

    Vehicle Shop Categories

    The qb-vehicleshop resource reads vehicle categories from the shared vehicles file. Categories group vehicles in the dealership UI.

    Common categories:

    CategoryLabelDescription
    superSuperHigh-end supercars
    sportsSportsSports cars
    sedanSedanFour-door sedans
    suvSUVSUVs and trucks
    muscleMuscleAmerican muscle cars
    coupeCoupeTwo-door coupes
    motorcycleMotorcycleBikes
    offroadOff-RoadOff-road vehicles
    vanVanVans and utility vehicles
    emergencyEmergencyPolice, EMS (not purchasable)
    To add a new vehicle to the shop, set the shop field to the dealership name (default is 'pdm' for Premium Deluxe Motorsport).

    ---

    Step 7: Admin Tools

    qb-adminmenu

    QBCore includes an admin menu accessible by players with admin permissions.

    Setting up admin permissions in server.cfg:

    %%CODEBLOCK_22%%

    Admin menu features:

    • >Teleport to players and waypoints
    • >Spawn vehicles
    • >Give items and money
    • >Set jobs and gangs
    • >Revive and heal players
    • >Toggle god mode and noclip
    • >Ban and kick players
    • >View server resources

    txAdmin Integration

    txAdmin is a full-featured web panel that comes bundled with FiveM artifacts. It provides server management beyond what the admin menu offers.

    txAdmin features for QBCore:

    • >Live server console with command execution
    • >Player management (kick, ban, warn, DM)
    • >Scheduled restarts with player warnings
    • >Resource management (start, stop, restart)
    • >Performance monitoring graphs
    • >Discord webhook integration
    • >Automatic server restarts on crash
    Access txAdmin:

    %%CODEBLOCK_23%%

    Permission Levels in QBCore

    QBCore uses its own permission system alongside FiveM's ACE system.

    %%CODEBLOCK_24%%

    Setting permissions via the admin menu or server console:

    %%CODEBLOCK_25%%

    ---

    Troubleshooting Common QBCore Issues

    Database Migration Errors

    Symptom: Server fails to start with SQL errors in console.

    Common causes and fixes:

    %%CODEBLOCK_26%%

    Check the oxmysql connection:

    %%CODEBLOCK_27%%

    Common database errors:

    ErrorCauseFix
    Access deniedWrong username/passwordVerify MySQL credentials
    Unknown databaseDatabase does not existRun CREATE DATABASE qbcoreframework;
    Table doesn't existSQL not importedImport qb-core.sql and resource SQL files
    Connection refusedMySQL not runningStart the MySQL/MariaDB service

    Resource Dependency Issues

    Symptom: Resources fail to start, console shows Could not find resource errors.

    Fixes:

  • 1.Check that qb-core loads before all other QBCore resources
  • 2.Verify all required dependencies are installed and ensure-d
  • 3.Check fxmanifest.lua for each resource to see its dependencies
  • 4.Make sure folder names match exactly (case-sensitive on Linux)
  • %%CODEBLOCK_28%%

    Script Conflicts

    Symptom: Features break or behave unexpectedly after adding new resources.

    Diagnosis steps:

  • 1.Check the server console for Lua errors after startup
  • 2.Look for duplicate event names across resources
  • 3.Check for multiple resources modifying the same game feature
  • 4.Test by disabling resources one at a time
  • %%CODEBLOCK_29%%

    Memory Leaks from Poorly Coded Resources

    Symptom: Server RAM usage increases continuously over time.

    Common causes:

    • >Client-side threads without proper Wait() calls
    • >Entity spawning without cleanup
    • >Unclosed event handlers
    • >Tables that grow without bounds
    Identifying the problem:

    %%CODEBLOCK_30%%

    Prevention tips for custom scripts:

    %%CODEBLOCK_31%%

    ---

    Performance Tips for QBCore Servers

    Resource Optimization

  • 1.Only run resources you actually use. Every ensure line adds overhead. Remove resources you have not configured.
  • 2.Use lua54 'yes' in fxmanifest.lua. Lua 5.4 is faster than Lua 5.3 for most operations.
  • 3.Minimize client-side threads. Every CreateThread with Wait(0) runs every frame. Use longer wait times when real-time updates are not needed.
  • Database Performance

    %%CODEBLOCK_32%%

    OneSync Configuration

    OneSync is required for QBCore and should be tuned for your player count.

    %%CODEBLOCK_33%%

    Server Restart Schedule

    Regular restarts prevent memory buildup and clear accumulated state.

    %%CODEBLOCK_34%%

    Linux systemd timer for scheduled restarts:

    %%CODEBLOCK_35%%

    %%CODEBLOCK_36%%

    %%CODEBLOCK_37%%

    General Performance Checklist

    • >[ ] OneSync is enabled and configured
    • >[ ] oxmysql is the database connector (not mysql-async)
    • >[ ] Only necessary resources are running
    • >[ ] Custom scripts use proper Wait() values in threads
    • >[ ] Database has indexes on frequently queried columns
    • >[ ] Server restarts on a regular schedule
    • >[ ] txAdmin monitoring is active
    • >[ ] Player count matches hardware capacity
    • >[ ] Vehicle and ped culling distances are set appropriately
    • >[ ] No resources are throwing repeated errors in console
    ---

    Conclusion

    Setting up a QBCore server takes time, but the result is a full-featured RP environment with modern systems and active community support. Start with the core resources, get them working correctly, then add custom jobs and features one at a time.

    Next steps after setup:

    • >Configure individual job scripts for your server's theme
    • >Add custom vehicles and clothing
    • >Set up a Discord bot for server status
    • >Create custom scripts for unique RP scenarios
    • >Join the QBCore Discord for community support
    For more information, visit the QBCore GitHub, the QBCore Documentation, and the FiveM Documentation.