Guides

Jobs and cron

A job runs to completion instead of serving traffic — nightly reports, cleanup tasks, data imports, one-off scripts.

Two kinds of job

KindBehaviour
One-shotRuns once when created. Use for migrations, backfills and single-use scripts.
ScheduledRuns repeatedly on a cron schedule. Use for anything recurring.

A job becomes scheduled simply by having a schedule; without one it runs a single time.

Creating a job

Open the environment’s canvas, add a Job (+ Add → Job / Cron), and give it an image, a command, and optionally a schedule. A job usually runs the same image as your app, so it has your code and dependencies already. The CLI, the HTTP API and the MCP tools can create jobs too:

bash
$ codaracloud jobs create nightly-report \    --client my-workspace --project website --environment production \    --image ghcr.io/acme/report:2026.08.19 \    --command npm --arg run --arg report \    --schedule "0 3 * * *"
FieldMeaning
ImageThe container image to run. Point it at your app’s image to reuse your code.
CommandWhat to execute, e.g. npm run send-digests.
ScheduleA cron expression. Leave empty for a one-shot job.
EnvironmentWhich environment it belongs to — it inherits that environment’s isolation and can reach its databases.

Cron schedules

ExpressionRuns
0 3 * * *Daily at 03:00
*/15 * * * *Every 15 minutes
0 9 * * 1Mondays at 09:00
0 0 1 * *First day of each month, midnight

Databases and jobs

A job in an environment can connect to that environment’s databases the same way an app does, and Codara waits for those dependencies to be ready before starting the job. A nightly report can query the same Postgres your API uses, without you wiring up credentials.

Watching a job

bash
$ codaracloud jobs list --client my-workspace --project website --environment production $ codaracloud jobs get nightly-report --client my-workspace --environment production $ codaracloud jobs image nightly-report ghcr.io/acme/report:2026.08.19 --client my-workspace --environment production $ codaracloud jobs logs nightly-report --client my-workspace --tail 500

The flag is --environment, not --env

The jobs commands spell the environment flag out in full, unlike most other command groups. --client is required.

Job logs are a bounded tail — up to 1000 lines — rather than a live stream, and credentials appearing in output are redacted. Logs are only retained while the underlying run still exists, so capture anything you need to keep.

Re-running and changing a job

A one-shot job is immutable once created. To run it again, use the console’s run action or codaracloud jobs rerun, which starts a fresh run from the same definition. To change what it does, delete it (codaracloud jobs delete <job> --yes) and create it again. A running one-shot job can be stopped with codaracloud jobs stop <job> --wait; scheduled jobs cannot be stopped this way.

A scheduled job keeps running on its schedule until you delete it, suspend it through the API/MCP tool, or pause its environment. You can pin a new OCI image for future runs with jobs image; its schedule, command, arguments, connections and resources stay intact. Existing or completed runs are not rewritten.

Good practice

  • Make jobs idempotent. A job can be retried or run twice; running it twice should not do damage.
  • Keep them short. Long-running work is better as a worker app than as a cron job.
  • Exit non-zero on failure. That is how Codara knows the run failed.
  • Log what happened. Retention is short, but a failed run is much easier to diagnose when the output says what it was doing.
  • Prefer a pre-deploy command for migrations. Running migrations as part of the release means a failed migration stops the release — see Building and deploying.

Jobs use your plan's capacity

A job’s CPU and memory must fit your plan’s largest-service size; otherwise creating or running it is refused with 402 plan_limit_exceeded. See Plans and capacity.

Last updated