A multijob system quietly makes or breaks the roleplay on your server. It lets players hold more than one job and switch between them from a menu, instead of being locked into a single role. Done well, it makes your server feel flexible. Done badly, it is a laggy, exploit-riddled headache that hands out police access to anyone who opens the developer console.
If you're shopping for one, here's what actually matters, how to test a candidate, and how to tell a good multijob from a dangerous one.
What "multijob" actually means
Out of the box, both QBCore and ESX give a player one job. Setting a new one overwrites the old:
Player.Functions.SetJob('mechanic', 0) -- whatever they were before is goneA multijob system adds a layer on top: it remembers every job a player has been hired into, and lets them switch the *active* one without losing the others. Grade, salary and duty state travel with each job.
That is the whole idea, and it is why the script has to be careful โ it is deciding which job a player is allowed to hold, which is the same as deciding who can access the police armoury.
The exploit that breaks most multijob scripts
This is the single most important thing on this page.
A naive implementation sends the chosen job from the client to the server:
-- Client
RegisterNUICallback('selectJob', function(data)
TriggerServerEvent('multijob:setJob', data.job, data.grade)
end)
-- Server โ DANGEROUS
RegisterNetEvent('multijob:setJob', function(job, grade)
local Player = QBCore.Functions.GetPlayer(source)
Player.Functions.SetJob(job, grade) -- trusts whatever arrived
end)Anyone can trigger that event with any arguments. One line in an executor and they are a grade-4 police officer. It does not matter how good the UI looks.
The correct shape checks ownership server-side, against data the client never controls:
RegisterNetEvent('multijob:setJob', function(job)
local Player = QBCore.Functions.GetPlayer(source)
if not Player then return end
-- the jobs this player actually owns, read server-side
local owned = MultiJob.GetOwnedJobs(Player.PlayerData.citizenid)
local entry = owned[job]
if not entry then return end -- they do not have it: refuse
Player.Functions.SetJob(job, entry.grade) -- grade comes from the server too
end)Note that the grade is not taken from the client either. A script that validates the job but accepts the grade lets a probationary officer promote themselves to chief.
What a good multijob system should do
- One-click switching between owned jobs, with grade and salary shown.
- Duty toggling without leaving the menu โ and station-locked duty for police and EMS if your roleplay needs it.
- Server-side validation of both job and grade. See above. This is not a nice-to-have.
- Framework compatibility with what you run โ QBCore, QBox, ESX, or ideally all of them with auto-detection.
- Persistence across relogs and restarts. Owned jobs living only in memory is a bug waiting for your next restart.
- Near-zero idle cost. A menu should cost nothing when closed.
- A UI you can re-theme, because it will sit next to the rest of your server's design.
How to test one before you trust it
Do this on a test server before it goes near your live one.
1. Try the exploit yourself. Trigger the job-setting event with a job you do not own:
TriggerServerEvent('multijob:setJob', 'police', 4)If your character becomes police, the script is unsafe. Delete it. This takes thirty seconds and tells you more than any sales page.
2. Check idle cost.
resmon 1Closed menu, nobody using it. Should be effectively zero. Our resmon guide covers reading the numbers properly.
3. Relog. Switch job, disconnect, reconnect. Are your owned jobs still there? Is the active one correct?
4. Restart the resource while a player is online. Does it recover, or does it need a full server restart?
5. Read the config. If it is escrow-protected, the config should still be open and readable. A resource where you cannot see or change the job list is a resource you cannot fit to your server.
Red flags
- No server-side checks. The test above catches this in seconds.
- Leaked or nulled copies. Free "cracked" versions of paid scripts are everywhere and frequently carry backdoors. Our guide on spotting a backdoored script shows what to look for โ and the FiveM TOS covers why running them risks your server and store, not just your security.
- Dead support. A multijob touches core systems. When the next framework update lands and something breaks, a vanished seller leaves you rewriting it.
- Single-framework lock-in. If you ever migrate, you buy again.
- Heavy resmon. Usually a
Wait(0)loop that has no reason to exist.
QBCore vs ESX โ does it matter?
Both frameworks handle jobs differently under the hood โ different player objects, different setters, different duty conventions. A script has to be written for the one you run, or for both.
Some multijob scripts are QBCore-only or ESX-only, which means you are stuck if you switch. A dual-framework multijob that auto-detects your setup is more future-proof, and matters more than it sounds given how many servers eventually migrate between frameworks. If you are still choosing, QBCore vs ESX covers the wider decision.
Free vs paid
Free multijob releases exist and some are decent. Realistically:
- Free tends to mean single-framework, minimal validation, and no support when it breaks. Fine for a test server or if you can read and fix Lua yourself.
- Paid should buy you server-side security, dual-framework support, updates when frameworks change, and someone to ask. If it does not, it is not worth paying for either.
The deciding question is not price. It is whether you can fix it yourself at 2am when it breaks during peak hours.
Our pick: Viper Multi-Job
We build the [Viper Multi-Job FiveM multijob script](/scripts/7566188) to hit every point above:
- One-click job switching with grade and salary display
- Built-in duty toggle, including station-locked duty for police and EMS
- Server-side validation of both job and grade โ players can only switch to jobs they genuinely own, at the grade the server holds
- QBCore, QBox and ESX Legacy from one resource, with automatic detection
- Fully re-themeable UI โ change one hex colour to restyle the menu
- Four languages included (EN, ES, FR, DE)
- Near-zero idle resmon, escrow protected with the config left open
It installs clean, it is actively maintained, and it comes with Discord support and full documentation. If you want to wire it up yourself first, our multijob setup guide walks through the process.
The bottom line
A multijob system sits at the centre of your server's job economy, which means it also sits on top of your security. Run the exploit test on whatever you are considering. Prioritise server-side validation, dual-framework support and an active creator over saving a few dollars on a leaked copy that may be reading your database.