Skip to main content
Some work doesn’t fit in a request: sending 10,000 emails, processing a video, periodic data sync. For these, use Convex actions with a job table and the scheduling primitives.

The pattern

1

A job record lives in the schema

jobs table with status (queued, running, completed, failed), payload, attempts.
2

A mutation enqueues

Inserts a row in jobs with status queued, then schedules an action.
3

A scheduled action processes

Picks up queued jobs, runs them, updates status. Retries on failure with exponential backoff.
4

Clients observe via reactive query

useQuery(api.jobs.byUser) shows live status to the user.

Example: bulk email send

convex/jobs.ts

Limits

  • Action runtime cap: 10 minutes per invocation
  • For longer work, split into chunks and reschedule each chunk

Patterns to consider

Inngest integration

For complex multi-step workflows with steps, retries, and backoff built in.

Trigger.dev integration

Job queue with a polished dashboard.

Scheduled functions

For recurring (cron-like) jobs.

Webhooks pattern

For event-driven jobs.

Convex actions

The function type background jobs use.

Scheduled functions

Cron + delayed scheduling.

Email campaigns recipe

Worked example.
Last modified on April 18, 2026