# Prioritizing Tasks with Celery Queues

By default, Celery sends all tasks to a single queue named `celery`. To prioritize specific tasks (like sending a password reset email immediately vs. generating a daily report), you should use **Routing** and multiple **Queues**.

## 1. Defining Queues

You don't strictly need to define queues upfront; Celery creates them automatically if you route a task to them. However, it is good practice to define them in your configuration.

```python
from celery import Celery
from kombu import Queue, Exchange

app = Celery('tasks', broker='redis://localhost:6379/0')

# Optional: Explicitly define queues
app.conf.task_queues = (
    Queue('default', Exchange('default'), routing_key='default'),
    Queue('high_priority', Exchange('high_priority'), routing_key='high_priority'),
    Queue('low_priority', Exchange('low_priority'), routing_key='low_priority'),
)

# Set the default queue
app.conf.task_default_queue = 'default'
```

## 2. Routing Tasks

You can assign tasks to queues in two ways:

### A. Automatic Routing (Configuration)

This is the cleanest method. You map tasks to queues in your Celery config.

```python
app.conf.task_routes = {
    'tasks.send_email': {'queue': 'high_priority'},
    'tasks.generate_report': {'queue': 'low_priority'},
    # All other tasks go to 'default'
}
```

### B. Manual Routing (At Call Time)

You can specify the queue when calling the task.

```python
from tasks import generate_report

# Send to high priority queue just this once
generate_report.apply_async(args=['2023-10-31'], queue='high_priority')
```

## 3. Consuming from Queues

Now that tasks are in different queues, you need to tell your workers how to handle them.

### Strategy A: Dedicated Workers (Recommended)

Run separate worker instances for different queues. This guarantees that high-priority tasks always have dedicated resources.

**Terminal 1 (High Priority Worker):**
```bash
celery -A tasks worker -Q high_priority --hostname=high_worker@%h
```

**Terminal 2 (Default/Low Priority Worker):**
```bash
celery -A tasks worker -Q default,low_priority --hostname=default_worker@%h
```

[[programming/python/celery]]