Documentation
Docs and examples
Reference material rendered inside the app, not raw markdown dumps. Search filters guides and snippets as you type.
Architecture diagrams
SVG diagrams follow light and dark theme tokens. Toggle the theme to preview both.
Guides
- 01Async code vs background jobsasync def, BackgroundTasks, and durable queues.
- 02Brokers and frameworks: Celery, Redis, RabbitMQ, KafkaCelery, Redis, RabbitMQ, Kafka, Taskiq, Dramatiq.
- 03Job lifecycle and schemaStates, SQL shape, 202 contract.
- 04Outbox, inbox, and idempotencyDual-write safety and dedupe.
- 05Example: Celery + RabbitMQ + FastAPIPseudocode worker and enqueue path.
- 06Example: Taskiq + RabbitMQ + FastAPIAsync-native FastAPI workers.
- 07Example: Dramatiq + RabbitMQ + FastAPISimple actors on AMQP.
- 08Example: FastStream + Kafka (events)Events, keys, and lag.
- 09Error taxonomy, retries, and DLQRetry vs fail vs dead-letter.
- 10Testing workers and async jobsUnit, API fakes, smoke tests.
- 11Designing an event-driven system (with FastAPI)Commands vs events, catalog, topology.
- 12Using DDD with FastAPI (and workers)Bounded contexts, aggregates, use cases.
- 13Laravel-style queues → FastAPI (RabbitMQ / Kafka)Laravel queue features mapped to FastAPI + RMQ/Kafka.
- 14Celery Beat scheduling (with FastAPI)Celery Beat: schedules, single-leader HA, idempotent ticks.
- 15Observability, metrics, and Flower (FastAPI + Celery)Health, JSON logs, job metrics, SLOs, Flower security, alerts.
- 16Job locks and rate limits (FastAPI + workers)Distributed locks, API rate limits, job/vendor rate limits.
- 17Implement with Celery: API RL → enqueue → RabbitMQ → job RL + lock → side effectCelery: API RL → enqueue → RMQ → job RL + lock.
- 18Monitoring Celery with FlowerFlower setup, task events, private auth, ops vs product status.
- 19Integrate Flower with PrometheusScrape Flower /metrics, PromQL, alerts, RMQ exporter.
- refReferencesOfficial docs, recipes, and architecture diagram index.
Pseudocode snippets
5/5Quick patterns. Full context lives in the guides above.
Enqueue + 202
async def enqueue_export(body, db, bus):
job = await db.insert_job(type="export", status="pending", ...)
await bus.publish("jobs.heavy", {"job_id": str(job.id), "type": "export"})
return {"job_id": job.id} # HTTP 202Idempotent worker
async def handle(message, db):
job = await db.get_job(message["job_id"])
if job.status == "succeeded":
return
await db.mark_running(job.id)
await do_work(job)
await db.mark_succeeded(job.id)Transactional outbox
async with db.transaction():
job = await db.insert_job(...)
await db.insert_outbox(
destination="jobs.default",
payload={"job_id": str(job.id), "type": job.type},
)Lock + job rate limit
@celery_app.task(bind=True, max_retries=25)
def sync_account(self, job_id: str, account_id: str):
if not take_token(redis, f"rl:vendor:{account_id}", rate=5, burst=10):
raise self.retry(countdown=2)
token = new_uuid()
if not acquire_lock(redis, f"lock:account:{account_id}", token, ttl=300):
raise self.retry(countdown=10)
try:
do_sync(account_id)
finally:
release_lock(redis, f"lock:account:{account_id}", token)Job metrics sketch
metrics.incr("jobs_enqueued_total", tags={"type": job.type})
metrics.observe("job_runtime_seconds", elapsed, tags={"type": job.type})
# backlog: rabbitmq_queue_depth gauge per queue
# alerts: consumers==0 critical; dlq_depth>0 highMachine-readable export
Prefer these pages in the browser. Agents can still ingest the full dump:
Open llms-full.txt