How to use priority in celery task.apply_async
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Celery lets you attach a priority to tasks sent with apply_async, but the setting only matters if the broker and queue are configured to honor it. The practical answer is to declare priority-capable queues, send tasks with the priority argument, and remember that priority influences scheduling order rather than creating a hard real-time guarantee.
Send a Task with priority
The call site is straightforward. Pass priority to apply_async when you enqueue the task.
The actual meaning of higher and lower numbers depends on the broker. With RabbitMQ, higher numeric values are typically treated as higher priority within a queue configured for priorities.
Configure the Queue to Support Priorities
Passing priority alone is not enough. The queue must declare a maximum priority.
Without the queue argument, many brokers will accept the task but ignore the priority metadata.
Route Urgent Tasks Intentionally
Priority works best when combined with explicit routing. If all tasks share one busy queue, high-priority items can still be delayed by tasks already prefetched by workers.
In practice, separate queues for materially different workloads are often clearer than relying on one queue with many priority levels.
Understand Worker Prefetch Behavior
A common surprise is that a supposedly urgent task waits behind lower-priority tasks that have already been prefetched by workers. Celery workers reserve tasks before executing them, which can reduce the visible effect of priority.
A lower prefetch value can make priority behavior more responsive, especially when task duration varies widely. The tradeoff is lower throughput in some workloads.
Use Priority as a Scheduling Hint, Not a Contract
Priority improves the odds that urgent tasks run sooner, but it does not bypass every queueing or worker-level constraint. Long-running tasks, insufficient worker capacity, or poor routing can still overwhelm the system.
If an operation is truly critical, consider a dedicated queue and dedicated workers instead of relying only on numeric priority.
Verify Behavior with Small Tests
Test with visible task durations so you can confirm what the broker and workers are actually doing.
Observe worker logs before assuming the configuration works. Many priority problems are really queue declaration or prefetch problems.
Common Pitfalls
- Passing
prioritywhile using a broker or queue configuration that does not support priorities. - Assuming lower and higher numbers mean the same thing across all broker setups without checking documentation.
- Expecting priority to override tasks that workers have already prefetched.
- Putting every workload into one queue instead of separating genuinely critical tasks.
- Treating task priority as a hard guarantee instead of a scheduling hint.
Summary
- Use
apply_async(..., priority=...)to attach a priority to a Celery task. - Configure queues with
x-max-priorityso the broker can honor it. - Combine priority with routing and queue design, not as a standalone fix.
- Tune worker prefetch if urgent tasks still wait too long.
- Test the behavior with real workers instead of assuming the broker uses priority the way you expect.

