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.
Each tick of the schedule runs once and exits. Then it waits for the next tick.
What you configure
| Field | Purpose |
|---|---|
| Name | Identifier for the job — unique within the project. |
| Schedule | Standard 5-field cron expression evaluated in UTC. See Schedule reference below. |
| Command | The command to run inside the container (e.g. node scripts/cleanup.js, /usr/local/bin/backup). |
| Build source | image (pull from a Docker registry) or git (build from a connected repo). |
| Image | When build source is image: the registry path, e.g. ghcr.io/acme/backup:1.4.0. |
| Dockerfile | When build source is git: the path inside the repo, defaults to Dockerfile. |
| Plan | Compute 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:
| Expression | When it fires |
|---|---|
*/5 * * * * | Every 5 minutes |
0 * * * * | Every hour, on the hour |
0 0 * * * | Once a day at midnight UTC |
0 9 * * 1-5 | 09: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 exampleCRON_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
- Open the project and environment where the job should run.
- Click New service → Cron job.
- 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.
- Image — paste a Docker image (e.g.
- Fill in the name, schedule, command, and compute shape (Flex / Standard / Performance).
- Optionally add environment variables or secrets.
- 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
| Pattern | Schedule | What it looks like |
|---|---|---|
| Database cleanup every night | 0 3 * * * | Container connects to your Postgres in the same environment, runs a delete-old-rows script, exits. |
| Weekly backup | 0 4 * * 0 | Dumps your datastore to object storage at 4 AM UTC every Sunday. |
| Hourly report for stakeholders | 0 9-17 * * 1-5 | Generates 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.