Skip to Content

Scheduled jobs

The job runner in apps/scheduled-jobs is a separate process and Docker image. Today it runs account deletion every minute, and verification clean-up and device clean-up every hour.

Add a job

Register an object in src/jobs/index.ts with:

  • a unique, stable name
  • a delay in milliseconds: a positive whole number, at most 2,147,483,647
  • an async run function.

Put the job's work in src/jobs. The shared Prisma, S3 and R2 clients come from src/services.ts; pass them to the job explicitly.

How jobs run

Jobs start when the process starts. After each run finishes or fails, the runner waits delay and runs it again. Runs of the same job never overlap in one process, but different jobs can run at the same time. Failures are logged and retried after the same delay.

Schedules aren't stored, so a restart runs every job again and missed runs aren't caught up.

Rules for a new job

  • Make it safe to run twice and safe to retry after being interrupted.
  • Keep each run short, so the container can shut down within its grace period.
  • The runner doesn't give you exactly-once runs or locks between processes. Deployments can briefly run old and new containers at once, so a job with side effects needs its own coordination.
  • Keep locations, keys, credentials and personal data out of logs.
  • Test the scheduling and failure behaviour, not just the job's logic.

On this page