Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture

Arbiter does not use a broker or central coordinator. Each worker pool claims jobs directly from PostgreSQL. Add worker processes to increase capacity. There is no leader process.

Queuedvisible now or laterIn flighthidden, heartbeatingAckedarchived if enabledRetry, after backoffDead-letter queueclaimsuccessretryableattempts spent, or permanentretry from the DLQtimeout lapsed, or nack

The lifecycle under transactionalWorkerConfig:

  1. Claim: The dispatcher claims visible jobs in per-group order, increments each attempt count, and hides each job for the visibility timeout. Admission is part of the same statement: a job whose rate-limit bucket is empty or whose concurrency pool is full is not claimed, and a claimed job has already spent its tokens and taken its slot. A heartbeat extends the timeout while the handler runs.
  2. Run: The worker runs the handler inside a transaction. The handler's database work, its stored result, and the ack commit together.
  3. Success: The job is acked and the transaction commits.
  4. Failure: The transaction rolls back. A separate transaction retries the job with backoff or moves it to the dead-letter queue (DLQ).
  5. Reclaim: If the visibility period ended and another worker claimed the job, the heartbeat or the ack throws and the worker abandons the job.

The claim operation applies the admission limits. The limits apply to worker pools in all processes and to clients that use the REST API. Claimants do not coordinate with each other.

Delivery is at least once. Arbiter can run a job again after a worker crash or an expired visibility timeout. Make non-transactional side effects idempotent.

With manualWorkerConfig and defaultBatchedWorkerConfig, step 2 does not start a transaction. The handler uses callbacks to complete, fail, cancel, or nack each job. The claim, heartbeat, and reclaim operations are unchanged.

Group Ordering

A group key permits one job or batch at a time in that group. Different groups can run concurrently.

  • Same group key: Eligible jobs run in insertion order within each priority. A retrying job remains first until it succeeds or moves to the DLQ. A ready job can run before a delayed job. A group waits during a job's retry backoff or rate-limit delay.
  • No group key: Any available worker can run the job concurrently.