How to use State Bags
A State Bag is a sticky note attached to a player or entity that every resource can read. You write a value once, and FiveM copies it everywhere automatically. No events, no asking around. Need to know a player's job, hunger, or radio channel? Just read their note. In 2026 this is the standard way to share data that lots of resources need but nothing breaks if it's a beat late.
Build it
Create the resource
resources/qu_statebag_demo/
fxmanifest.lua
server.lua
client.lua
fx_version 'cerulean'
game 'gta5'
server_script 'server.lua'
client_script 'client.lua'
Set a State Bag value (server)
Write a value to a player's note. We do this on the server because the server is the boss of player state:
-- Set a State Bag value for a player
local playerId = 1 -- replace with actual player ID
local playerState = Player(playerId).state
playerState:set('job', 'police', true) -- true = replicate to all clients
print(('Set player %s job to police'):format(playerId))
That third argument (true) decides who gets to see the value. Replication just means "copy it out to every client." Pass true and all players can read it. Pass false and it stays server-only, like a private note.
Read a State Bag value (client)
Now read the note back. Any client can read another player's State Bag - first turn the server ID into a client ID, then grab the value:
-- Read another player's State Bag
local targetId = GetPlayerFromServerId(1) -- server ID → client ID
local job = Player(targetId).state.job
print(('Player 1 job: %s'):format(job or 'not set'))
-- Read your own State Bag
local myJob = LocalPlayer.state.job
print(('My job: %s'):format(myJob or 'not set'))
Reading your own note is even easier: LocalPlayer.state is always you, so there's no ID lookup to do.
React to State Bag changes
Best part: you don't have to keep checking the note. A change handler is code that FiveM runs for you the moment a value changes. Set one up for job:
-- Handler fires every time 'job' changes on any player
AddStateBagChangeHandler('job', nil, function(bagName, key, value)
local playerId = GetPlayerFromStateBagName(bagName)
if playerId == 0 then return end -- bagName is not a player
print(('Player %s job changed to: %s'):format(playerId, value))
end)
It fires on every change, all on its own. No loop checking the value over and over, no event to trigger.
Keep reading the full lesson
Sign in to start, then unlock every step of this lesson and the full FiveM School with a membership.
- Common failures
The remainder of How to use State Bags is available to FiveM School members.