Skip to main content

Cron Jobs

A cron job is a service kind that runs a container on a schedule. You give it a cron expression and a command; ComputeSphere fires the container at every tick, the command runs once, the container exits, and the schedule waits for the next tick.

One run, start to finish
Schedule ticksUTC
Container starts
Command runs
Exit
Logs captured

Each tick of the schedule runs once and exits. Then it waits for the next tick.

What you configure​

FieldPurpose
NameIdentifier for the job — unique within the project.
ScheduleStandard 5-field cron expression evaluated in UTC. See Schedule reference below.
CommandThe command to run inside the container (e.g. node scripts/cleanup.js, /usr/local/bin/backup).
Build sourceimage (pull from a Docker registry) or git (build from a connected repo).
ImageWhen build source is image: the registry path, e.g. ghcr.io/acme/backup:1.4.0.
DockerfileWhen build source is git: the path inside the repo, defaults to Dockerfile.
PlanCompute shape per run — Flex, Standard, or Performance. Pick the smallest that fits the job.

Cron jobs live in an environment alongside your other services. They can read the env's variables, including secrets, the same way a web service does.

Schedule reference​

ComputeSphere uses the standard 5-field cron format, evaluated in UTC:

┌───────────  minute        (0 – 59)
│ ┌───────── hour (0 – 23)
│ │ ┌─────── day of month (1 – 31)
│ │ │ ┌───── month (1 – 12)
│ │ │ │ ┌─── day of week (0 – 6, Sunday = 0)
│ │ │ │ │
* * * * *

Common patterns:

ExpressionWhen it fires
*/5 * * * *Every 5 minutes
0 * * * *Every hour, on the hour
0 0 * * *Once a day at midnight UTC
0 9 * * 1-509:00 UTC every weekday
0 0 1 * *Midnight UTC on the 1st of every month

Test expressions before pasting them in: crontab.guru is the standard ground truth for what a cron line means.

Lifecycle controls​

Every cron job carries the same lifecycle verbs as a long-running service, with the schedule grafted on top:

  • Trigger now. Run the job immediately, off-schedule, without waiting for the next tick. Useful for testing or for ad-hoc re-runs.
  • Suspend. Pause the schedule. The job stays configured; no ticks fire until you resume. Use this for known-broken downstreams ("don't run backups while we're migrating").
  • Resume. Re-arm the schedule from where it left off.
  • Update. Change the image, command, schedule, env vars, or plan — redeploys the job atomically.
  • Rollback. Restore a previous version of the job's deployment (image + config). Same primitive as web services.
  • Delete. Remove the job entirely.

Run history and logs​

Every run leaves a trace. From the Console (or API), for any cron job you can:

  • List runs — every past trigger with its start time and outcome.
  • Read logs for a single run — the container's full stdout/stderr, scoped to that one execution.
  • Stream live logs for an in-progress run.

The schedule's two computed outputs surface alongside the job:

  • last_run — when the most recent run started.
  • next_run — when the next tick will fire.

Honest limits​

A few constraints worth knowing up front, so you don't reach for a setting that isn't there:

  • Timezone. Schedules are evaluated in UTC unless they start with CRON_TZ=<zone>, for example CRON_TZ=Europe/London 0 9 * * *. An unknown zone is refused.
  • One run at a time. If a run is still going when the next tick comes, no second run starts beside it. When the run ends, the job runs once for the tick it missed, then follows its schedule again. A job that runs longer than its interval runs back to back, not in parallel.
  • Retries. A failed run may be retried a few times before it ends failed. Make the command safe to run twice.
  • No per-run timeout. A run executes until the command exits. If a run hangs, suspend the schedule, stop the running deployment, and investigate.

Enable a cron job​

  1. Open the project and environment where the job should run.
  2. Click New service → Cron job.
  3. Pick a build source:
    • Image — paste a Docker image (e.g. ghcr.io/acme/backup:1.4.0).
    • Git — connect a GitHub repo and pick a branch; ComputeSphere builds on every push.
  4. Fill in the name, schedule, command, and compute shape (Flex / Standard / Performance).
  5. Optionally add environment variables or secrets.
  6. Click Create.

The job appears in the Services tab with next_run computed from the schedule. To run it once without waiting, click Trigger run.

Common patterns​

PatternScheduleWhat it looks like
Database cleanup every night0 3 * * *Container connects to your Postgres in the same environment, runs a delete-old-rows script, exits.
Weekly backup0 4 * * 0Dumps your datastore to object storage at 4 AM UTC every Sunday.
Hourly report for stakeholders0 9-17 * * 1-5Generates a CSV every business hour and emails or posts it.
Re-index search after data drifts*/30 * * * *Pulls fresh records, pushes updates to your search index every 30 min.

For one-shot ad-hoc work — not on a schedule — use Trigger now on a cron job whose schedule is set to a far-future date, or run a background worker manually. Schedules are mandatory at create time.

What's next​

  • Service kinds — the broader mental model for web services, workers, and cron jobs.
  • Datastores: SphereDB (PostgreSQL), SphereCache (Valkey), SphereQueue (RabbitMQ). Cron jobs often run against them.
  • Environment variables — how secrets and config land in your job's container.