broker moves messages, backend stores resultsRedis/RabbitMQ broker; backend optional
@app.task then .delay()nothing runs until a worker is up
.delay() vs calling directlydelay enqueues; add(2,3) runs inline, bypassing Celery
apply_async for controlcountdown/eta, queue, priority, link callbacks
bind=True for retriesself.retry(exc=e); or autoretry_for + retry_backoff
-Q to isolate workloadsroute heavy tasks to dedicated workers
beat schedules, workers executerun exactly one beat
canvas: chain / group / chordsequential / parallel / parallel-then-callback (map-reduce)
pass ids, stay idempotent, JSON onlyat-least-once delivery; never pickle untrusted