Overview
Chronos is a managed scheduling API. You define when jobs should run, chronos makes sure they actually happen, with retries, backoff, and execution tracking built in.
The guarantee
Section titled “The guarantee”| Layer | Guarantee | What it means |
|---|---|---|
| Scheduling | Exactly-once job creation | Each schedule fires once per interval, no matter how many app instances you run |
| Delivery | At-least-once execution | Jobs retry with exponential backoff until they succeed or exhaust max attempts |
How it works
Section titled “How it works”Schedule ──spawns──▶ Job ──creates──▶ Execution- Schedule: A recurring pattern (cron or interval) that spawns jobs on a cadence.
- Job: A unit of work to execute. Created by a schedule (recurring) or directly via the API (one-off).
- Execution: A single attempt to run a job. If it fails and retries remain, a new execution is created.
Example worker
Section titled “Example worker”Install the SDK:
pnpm add @chronos.sh/sdknpm install @chronos.sh/sdkyarn add @chronos.sh/sdkCreate a worker that processes jobs:
import { Chronos } from '@chronos.sh/sdk';
const chronos = new Chronos({ apiKey: process.env.CHRONOS_API_KEY });
chronos.worker.handle('sync-tenant', async (ctx) => { const tenants = await db.tenants.findMany(); for (const tenant of tenants) { await syncData(tenant.id, ctx.payload); } return { synced: tenants.length };});
await chronos.worker.start();Create a schedule via the API, and your worker picks up jobs automatically:
curl -X POST https://api.chronos.sh/v1/schedules \ -H "Authorization: Bearer chrns_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "name": "Hourly tenant sync", "handler": "sync-tenant", "interval": { "value": 1, "unit": "hour" }, "payload": { "full": false } }'Two ways to receive jobs
Section titled “Two ways to receive jobs”Pull (worker): Your process long-polls Chronos for jobs. Best for background processing where you control the compute. This is what the example above shows.
Push (HTTP): Chronos calls your HTTP endpoint when a job is due. Best when you already have a server listening, or want jobs delivered to serverless functions.
Both paths get the same retry guarantees. Choose based on your infrastructure, not reliability needs.
Next step
Section titled “Next step” Quick Start Create and run your first job in under 5 minutes