Skip to content

Schedule a job

Run a command on a UTC schedule, inspect its result, and control overlap.

Create a scheduled service for a command that runs and exits. Test it manually before adding a cron schedule. Jobs use the same repository or image sources and variables as runtime services, but have no port, public address, replicas, sleep setting or health checks.

Before you start

  • Have a ready environment and a repository with a Dockerfile or a public image.
  • Prepare a command that can finish without prompting for input.
  • Set the job’s required variables and credentials.
  • For MCP, use a product-scoped token with Deployment write to create, update, deploy and run jobs, and read for history and logs.

1. Create without a schedule

Choose Add service on the environment canvas and set the mode to scheduled. With MCP, call deployment_service_create with mode: "scheduled", your source, environment ID and name.

Supply a command of up to 4096 characters, or omit it to use the image’s entrypoint. Leave schedule unset or null while testing. Service mode is fixed at creation; you cannot later turn a job into a persistent service or the reverse.

2. Deploy and run it

Deploy the job at least once so it has an image to run. Then choose Run now on its panel, or call deployment_job_run with serviceId.

Run now bypasses both the schedule and concurrency policy. Check for an existing run before starting another if duplicate work would be a problem. Manual runs are recorded as manual in the same history as scheduled runs.

3. Set the schedule and limits

Use deployment_service_update to set schedule, jobTimeoutSec and jobConcurrency. Schedules are five-field cron expressions in UTC: minute, hour, day of month, month, day of week.

Schedule
Runs
0 3 * * *
Daily at 03:00 UTC
*/15 * * * *
Every 15 minutes
0 9 * * 1
Mondays at 09:00 UTC
0 0 1 * *
First day of each month at 00:00 UTC
30 6 * * 1-5
Weekdays at 06:30 UTC

Invalid expressions are rejected when saved. There is no timezone setting; account for daylight saving changes yourself if the work follows local time.

The timeout defaults to one hour and accepts 60–86,400 seconds. A run still going at the deadline is stopped and marked TimedOut.

Concurrency
If a scheduled tick arrives during a run
forbid (default)
Skip the new tick and record it as skipped
allow
Start another run alongside the existing one
replace
Stop the existing run and start the new one

Keep forbid unless the work supports overlap or replacement. It prevents overlapping scheduled runs, but does not constrain Run now. Failed runs are not retried automatically; implement any required retry logic in the command.

Verify it works

Open the job’s run history, or call deployment_job_runs_list. Check that the manual test succeeded with exit code 0, then inspect the output and the intended result, such as the exported file or updated records. After adding a schedule, confirm a scheduled run appears at the expected UTC time.

Status
Meaning
Running
Started and not finished
Succeeded
Exited with code 0
Failed
Exited with a nonzero code
TimedOut
Stopped at its timeout
Skipped
A scheduled tick was skipped under forbid

Logs on a run or deployment_job_run_logs returns a live tail while running and stored output afterward. Stored output contains the last 256 KiB. A polling caller should stop when the returned live value becomes false.

History retains the last 100 runs and nothing older than 30 days; skipped ticks count toward the 100. Send records elsewhere from the job if you need longer retention.

Pause and resume

Pause stops scheduled starts without clearing the schedule. Resume enables them again. MCP sets scheduleSuspended through the service update tool. Pausing does not stop an active run or block manual starts. It survives deployments and is copied when an environment is forked.

Jobs are billed for compute while running, not between runs. A product billing suspension stops scheduled starts and refuses manual runs; clearing it restores scheduling while preserving jobs you had paused.

Jobs have no interactive shell. For another command against their image, use a separate one-off run, or start the job’s configured command with Run now.

Was this page helpful?
Esc

Start typing to search the docs.

↑↓navigate↵select