cron
cron reference for ESX Legacy. Schedule daily server tasks at a fixed time with the cron:runAt event, weekday handling, timezone and common pitfalls.
cron is a tiny server-side scheduler shipped with ESX Legacy. Other resources
register a callback for a time of day (hour and minute) and cron calls it once
every day at that time. Official addons use it, for example esx_society for
salaries and esx_vehicleshop for rental payments.
Overview
| Resource | cron |
| Side | Server only |
| Dependencies | None |
| Config | None |
| Required | Only when a resource uses cron:runAt (esx_society and esx_vehicleshop do) |
cron:runAt
The only API is a server-side local event.
TriggerEvent("cron:runAt", h, m, cb)| Name | Type | Description |
|---|---|---|
h | number | Hour, 0-23, in server local time. |
m | number | Minute, 0-59. |
cb | function | Called as cb(d, h, m). A callable table (with __call) also works. |
Callback arguments:
| Name | Type | Description |
|---|---|---|
d | number | Weekday from os.date("*t").wday: 1 = Sunday, 2 = Monday, ..., 7 = Saturday. |
h | number | The hour you registered. |
m | number | The minute you registered. |
Wrong argument types fail with an assert that names the invoking resource.
Examples
-- Every day at 05:10
TriggerEvent("cron:runAt", 5, 10, function(d, h, m)
print(("Daily cleanup at %02d:%02d"):format(h, m))
MySQL.update("DELETE FROM my_logs WHERE created_at < NOW() - INTERVAL 30 DAY")
end)-- Every Monday at 18:30
local MONDAY <const> = 2
TriggerEvent("cron:runAt", 18, 30, function(d)
if d ~= MONDAY then return end
print("Weekly payout")
end)-- Every 6 hours: register several times
for _, hour in ipairs({ 0, 6, 12, 18 }) do
TriggerEvent("cron:runAt", hour, 0, function()
print("Six-hour task")
end)
endHow scheduling works
- cron checks once per minute, aligned to the start of the minute.
- On each new minute it computes every job's most recent scheduled time (today, or yesterday if today's time is still ahead) and runs the job if that time is newer than the previous check. A short server hitch therefore does not skip a job.
- Jobs do not catch up after a restart. A task scheduled for 05:10 does not run if the server was offline at 05:10.
- Errors in a callback are caught and printed as
cron job at HH:MM errored, skipping it; other jobs keep running.
Common issues
- Weekday check never matches. The official README uses
d == 1for Monday. In Luawday1 is Sunday; Monday is2. - Task runs at the wrong hour. The server's timezone differs from yours.
Check
os.date()in the server console. - Errors after restarting a resource. Jobs cannot be removed. When you restart a resource that registered a job, the old callback reference stays registered and errors every day, next to the new job the restarted resource registers. The error is harmless, but a full server restart cleans it up.
- Jobs stop after restarting cron. Jobs live in cron's memory. Restarting
cronalone drops every job; the resources that registered them must be restarted too. - Registering from the client.
cron:runAtis a server-only local event; it does nothing on the client and cannot be triggered over the network.
Related
Frequently asked questions
Independent documentation
Last updated on
esx_chat_theme
esx_chat_theme for ESX Legacy explained. What the ESX chat theme changes, how it hooks into the cfx chat resource, and how to customize or remove it.
ESX Legacy Addons
Overview of all 39 official ESX Legacy addons with categories, dependencies, installation order and the 2026 security hardening SQL migration.