Skip to main content

CronJob

A CronJob runs a handler on a schedule. Use it for periodic work — daily reports, hourly aggregations, weekly retention sweeps.

Quick example

import { Project, CronJob, Database } from '@sprintsail/sdk';

export const app = new Project('orders');
export const db = new Database(app, 'orders', { engine: 'postgres', version: '16' });

export const dailyReport = new CronJob(app, 'daily-report', {
handler: './src/handlers/daily-report.ts',
schedule: 'cron(0 9 * * ? *)', // every day at 09:00 UTC
memory: 512,
timeout: 300,
bindings: { db },
});

Handler:

import { db } from '../../infra.js';

export default async function handler() {
const rows = await db.query(
"SELECT count(*) FROM orders WHERE placed_at >= now() - interval '1 day'",
);
console.log({ ordersToday: rows[0].count });
}

Config

interface CronJobConfig {
handler: string;
runtime?: 'nodejs22' | 'nodejs20' | 'python3.12';
schedule: string; // see "Schedule formats" below
memory?: number; // MB, default 256
timeout?: number; // seconds, default 30
env?: Record<string, string>;
bindings?: Record<string, Database | Bucket | Secret | Queue>;
}

Schedule formats

The SDK accepts a permissive schedule string and translates it per target:

FormatExampleTranslates to (AWS)Translates to (Runtime)
5-field Linux cron0 9 * * *cron(0 9 * * ? *)passed through
6-field EventBridge croncron(0 9 * * ? *)passed throughdropped year/?
rate(N minute/hour/day)rate(15 minutes)passed throughconverted to */15 * * * *
Shortcuts@hourly, @daily, @weekly, @monthly, @yearlyconvertedpassed through (K8s supports)

Target mapping

TargetMaps toNotes
awsLambda + EventBridge Scheduler ruleSame Lambda constraints as Function.
sprintsail-runtimeNative Kubernetes CronJob (batch/v1)concurrencyPolicy: Forbid. History limits: 3 successful / 3 failed jobs retained.

Concurrency

By default, only one invocation runs at a time on the runtime (concurrencyPolicy: Forbid). On AWS, EventBridge fires the schedule and Lambda concurrency limits apply globally — the SDK doesn't add per-CronJob concurrency control there.

If your schedule is faster than your handler runs, consider increasing timeout or switching to a Worker consuming from a queue instead.

Time zones

Schedules are interpreted as UTC on both targets. Convert local times yourself.