Background Jobs and Task Queues: Celery vs. Arq vs. Postgres-Backed Queues
Compare production task queue options: Celery's battle-tested complexity, Arq's lightweight simplicity, and Postgres-backed alternatives. Choose the right fit for your scale.
Background Jobs and Task Queues: Celery vs. Arq vs. Postgres-Backed Queues
Every non-trivial backend needs work outside the request/response cycle—send emails, resize images, retry flaky APIs, fan out notifications. None of that belongs in your HTTP handler. The question isn't whether you need a task queue, but which one you can operate without it becoming a second job.
My honest take after running all three in production.
The Contenders
Celery — the industry standard. Python, broker-agnostic (Redis or RabbitMQ), battle-hardened, vast ecosystem. Also: genuinely complex to configure correctly, with a historically painful monitoring story.
Arq — a lightweight async task queue built on Redis and Python's asyncio. Created by the Pydantic team. Minimal surface area, integrates seamlessly with FastAPI and modern async Python.
Postgres-backed queues — using your existing Postgres database as a queue substrate via SKIP LOCKED or libraries like procrastinate. No additional infrastructure. Transactional guarantees included.
When to Use What
Celery: When Scale Demands It
Celery makes sense if:
- You're running Django (its integration is mature and well-documented)
- You need complex workflows—chains, chords, groups, canvas primitives
- You're already operating Redis or RabbitMQ
- Multiple teams benefit from established patterns
Critical: don't use Celery's default pickle serializer in production. It's a remote code execution vulnerability. Always set task_serializer = "json" and accept_content = ["json"]:
Most teams miss task_acks_late = True with worker_prefetch_multiplier = 1. Without it, a worker crash silently drops tasks.
Arq: The FastAPI Default
If you're async-native on FastAPI, Arq is the right choice. It's minimal, readable, and doesn't impose separate worker class hierarchies.
Enqueue from FastAPI:
Arq's limitations are real: no complex workflow primitives, no built-in periodic scheduling beyond basic cron, smaller community. If you need chains or fan-out patterns, you'll wire them manually—usually fine for moderate loads. Complexity you don't import is complexity you don't debug.
Postgres-Backed Queues: The Underrated Option
Most engineers dismiss this, then rediscover it with relief years later.
If you already run Postgres, adding Redis just for a queue is an infrastructure tax. Postgres with SELECT ... FOR UPDATE SKIP LOCKED gives you a reliable, exactly-once-safe job queue without new moving parts.
Minimal schema:
Worker poll:
SKIP LOCKED is the key. Without it, workers block each other. With it, each worker atomically claims a unique job with no coordination overhead.
The real advantage: transactional enqueueing. You can enqueue a job inside the same transaction that writes its dependencies. If the transaction rolls back, the job vanishes. No orphaned jobs. Redis-backed queues cannot guarantee this without significant complexity.
Use procrastinate if you want a polished wrapper rather than rolling your own.
Decision Matrix
| Concern | Celery | Arq | Postgres Queue |
|---|---|---|---|
| Existing Postgres only | ✗ | ✗ | ✓ |
| FastAPI + async-native | ✗ | ✓ | ✓ |
| Django integration | ✓ | ✗ | partial |
| Complex workflows (chains) | ✓ | ✗ | ✗ |
| Transactional enqueueing | ✗ | ✗ | ✓ |
| Operational simplicity | ✗ | ✓ | ✓ |
| Community ecosystem | ✓ | ✗ | ✗ |
Final Thoughts
For greenfield FastAPI projects: start with Arq. You'll know exactly when you've outgrown it.
For Django projects: Celery, but configure it correctly from day one. Config debt compounds.
For data integrity–critical work (financial transactions, audit trails, anything verifiable): use Postgres-backed queues. The transactional guarantee outweighs Redis throughput in those contexts.
Don't mistake Postgres queue simplicity for weakness. Some of the most reliable job systems I've operated were just tables and a polling loop.
Damian Hodgkiss
Senior Staff Engineer at Sumo Group, leading development of AppSumo marketplace. Technical solopreneur with 25+ years of experience building SaaS products.