Cron jobs
In this guide you schedule a recurring command for an app, for example a nightly cleanup, and check that it runs.
Prerequisites
Section titled “Prerequisites”- An app that has been deployed at least once. Runs are skipped until then.
- The
developerrole to create, change, run jobs and read their output. Any team member can list jobs.
PANEL=https://panel.example.comH='Authorization: Bearer gsl_xxxxxxxxxxxxxxxx'J='Content-Type: application/json'1. Check the schedule
Section titled “1. Check the schedule”Schedules are 5-field cron expressions (*/15 * * * *, 0 3 * * mon-fri) or
@hourly, @daily, @weekly, @monthly, @yearly. They’re evaluated in
UTC.
curl -s "$PANEL/apps/42/cron/preview?schedule=0%203%20*%20*%20*" -H "$H"# → the next 5 run times, or 400 invalid_schedule with the reason2. Create the job
Section titled “2. Create the job”curl -sX POST $PANEL/apps/42/cron/ -H "$H" -H "$J" -d '{ "name": "nightly-cleanup", "schedule": "0 3 * * *", "command": "./current/app cleanup --older-than 30d", "timeoutSeconds": 600}'| Field | Notes |
|---|---|
name |
Up to 100 characters. |
schedule |
As above. |
command |
Up to 4000 characters. Runs like a console command: as the app’s Linux user, in its directory, with its env vars and toolchain on the path. |
timeoutSeconds |
1 to 3600, default 300. The run is killed and marked timed_out after that. |
enabled |
Default true. |
An app can have at most 20 jobs.
3. Run it now
Section titled “3. Run it now”curl -sX POST $PANEL/apps/42/cron/{jobId}/run -H "$H"The response is the run. Its execId streams live output on the
/ws/apps/42/exec/{execId} WebSocket, like the console. You get 409 if a
run of this job is still going.
4. Change, pause or delete it
Section titled “4. Change, pause or delete it”curl -sX PATCH $PANEL/apps/42/cron/{jobId} -H "$H" -H "$J" -d '{"enabled": false}'curl -sX DELETE $PANEL/apps/42/cron/{jobId} -H "$H" # also deletes its runsHow runs are scheduled
Section titled “How runs are scheduled”The worker checks for due jobs every 30 seconds. Each slot is claimed atomically, so a job never runs twice even with several workers. A slot missed while the worker was down runs once when it comes back. A run is skipped while the previous one is still running, or while the app has never been deployed. A run lost to a worker restart is marked failed after its timeout plus 5 minutes.
Verify it works
Section titled “Verify it works”curl -s $PANEL/apps/42/cron/ -H "$H" | jq '.results[] | {name, nextRunAt, lastRunAt, lastStatus}'
curl -s $PANEL/apps/42/cron/{jobId}/runs -H "$H" \ | jq '.results[0] | {status, exitCode, output}'Runs (the last 50) have a status of running, succeeded, failed,
timed_out or skipped, an exitCode, and the last 200 lines of output.
Output can contain secrets, which is why reading runs needs the developer
role.