Skip to content

Broker Setup for Celery — Complete Guide

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about Broker Setup for Celery. We cover key concepts, practical examples, and best practices to help you master this topic.

Configure Redis and RabbitMQ as Celery brokers, understand their trade-offs, set up connection pooling, and handle broker failover in production.

What You Learn

You will learn how to configure Redis and RabbitMQ as Celery brokers, choose between them based on your needs, set up connection pooling, and handle broker connection failures.

Why It Matters

The broker is the backbone of Celery. It holds all pending tasks. If the broker goes down, no tasks can be submitted or executed. Choosing the right broker and configuring it correctly is critical for reliability.

Real-World Use

DodaTech uses RabbitMQ as the Celery broker in production for its routing flexibility and delivery guarantees. Development environments use Redis for simplicity and speed. The broker configuration is environment-aware.

Broker Comparison

flowchart TB
    subgraph "Broker Choice"
        direction LR
        R[Redis] --- RMQ[RabbitMQ]
    end
    R --> |Pros| RP[Fast, simple,
good visibility] R --> |Cons| RC[No routing,
limited persistence] RMQ --> |Pros| RMP[Advanced routing,
delivery guarantees] RMQ --> |Cons| RMC[More complex,
heavier setup] style R fill:#f90,color:#fff style RMQ fill:#6a0,color:#fff

Redis Broker Configuration

# celery_app.py
from celery import Celery

# Simple Redis configuration
app = Celery('redis_app',
             broker='redis://localhost:6379/0',
             backend='redis://localhost:6379/1')

# Redis with password
app2 = Celery('secure_app',
              broker='redis://:password@localhost:6379/0')

# Redis over TLS
app3 = Celery('tls_app',
              broker='rediss://:password@redis.example.com:6379/0')

# Redis with connection pool settings
app.conf.update(
    broker_pool_limit=10,
    broker_connection_timeout=30,
    broker_connection_retry=True,
    broker_connection_retry_on_startup=True,
    broker_connection_max_retries=10,
)

@app.task
def sample_task(data):
    return f"Processed: {data}"

RabbitMQ Broker Configuration

# RabbitMQ broker setup
from celery import Celery

# Simple RabbitMQ
app = Celery('rabbit_app',
             broker='amqp://guest:guest@localhost:5672//',
             backend='rpc://')

# RabbitMQ with virtual host
app2 = Celery('multi_tenant',
              broker='amqp://user:pass@localhost:5672/production_vhost')

# RabbitMQ cluster
app3 = Celery('cluster_app',
              broker='amqp://user:pass@node1:5672,node2:5672,node3:5672/production_vhost')

# RabbitMQ over TLS
app4 = Celery('tls_app',
              broker='amqps://user:pass@rabbitmq.example.com:5671/production_vhost')

Connection Pooling

from celery import Celery

app = Celery('pool_app', broker='redis://localhost:6379/0')

# Configure connection pool
app.conf.update(
    broker_pool_limit=20,
    broker_connection_timeout=30,
    broker_connection_retry=True,
    broker_connection_max_retries=0,  # infinite retries
)

@app.task(bind=True, max_retries=3)
def task_with_retry(self, data):
    try:
        return f"Result: {data}"
    except Exception as exc:
        raise self.retry(exc=exc, countdown=60)

Broker URL Formats

Broker URL Format Notes
Redis redis://localhost:6379/0 Database number suffix
Redis with password redis://:pass@host:6379/0 Colon before password
Redis via TLS rediss://host:6379/0 Double-s for TLS
RabbitMQ amqp://user:pass@host:5672/vhost Vhost after slash
RabbitMQ cluster amqp://user:pass@host1,host2/vhost Comma-separated hosts
RabbitMQ via TLS amqps://host:5671/vhost Double-s for TLS
SQS sqs:// Requires boto3

Sentinel Configuration for Redis

For high-availability Redis, use Sentinel:

from celery import Celery

app = Celery('sentinel_app')

# Redis Sentinel configuration
app.conf.update(
    broker_url='redis-sentinel://sentinel1:26379,sentinel2:26379,sentinel3:26379/0',
    broker_transport_options={
        'master_name': 'mymaster',
        'sentinels': [
            ('sentinel1', 26379),
            ('sentinel2', 26379),
            ('sentinel3', 26379),
        ],
    }
)

Broker Visibility Timeout

Redis broker has a visibility timeout for unacknowledged tasks:

app.conf.update(
    broker_transport_options={
        'visibility_timeout': 3600,  # 1 hour
    }
)

Tasks that are not acknowledged within the visibility timeout are redelivered. Set this to match your longest expected task runtime.

Common Mistakes

1. Using Same Redis Database for Broker and Result Backend

Use different database numbers (e.g., broker=db0, result=db1). Mixing them causes key collisions and unpredictable behavior.

2. Not Setting broker_connection_retry_on_startup

Without this setting, Celery may fail to start if the broker is temporarily unavailable. Always enable it for production.

3. Ignoring Broker Connection Timeouts

Default timeouts may be too short for slow networks. Set broker_connection_timeout to 30-60 seconds for production environments.

4. Using Redis Without Persistence

Redis stores everything in memory by default. Configure Redis persistence (AOF or RDB) to avoid losing tasks on restart.

5. Not Monitoring Broker Memory

Redis stores all unprocessed tasks in memory. Monitor memory usage and set a maxmemory policy to prevent OOM crashes.

Practice Questions

1. What is the main advantage of RabbitMQ over Redis as a Celery broker?

RabbitMQ provides advanced routing (exchanges, bindings), delivery guarantees, and supports complex task routing patterns. Redis is simpler and faster but lacks routing features.

2. How do you configure a Redis broker with a password?

Use the URL format redis://:password@host:6379/0. The colon before the password is required.

3. What is broker_connection_retry_on_startup used for?

It tells Celery to retry connecting to the broker on startup instead of failing immediately. Essential for environments where the broker may start after the worker.

4. What is the visibility timeout in Redis broker?

The time a task remains invisible to other workers after being fetched. If the worker does not ack within this time, the task is redelivered.

Challenge

Design a broker configuration for a multi-region Celery deployment. Workers in US, EU, and Asia each have a local Redis broker. Tasks are routed based on region. Configure connection pooling, timeouts, and retries for each region.

FAQ

Can Celery use multiple brokers simultaneously?

No, one Celery app uses one broker. For multi-broker setups, create separate app instances or use routing to direct tasks to different queues on the same broker.

What happens if the broker is down when a task is submitted?

The task submission fails with a connection error. Use retry logic in the caller or a fallback mechanism to queue tasks locally.

How do I migrate from Redis to RabbitMQ broker?

Create a new Celery app with the RabbitMQ broker URL. Run both brokers during migration. Gradually move task producers and workers to the new app.

Does the broker store task results?

No. The broker only stores task messages. Results are stored in the result backend. They use different configurations.

What is the maximum queue size for Redis broker?

Redis can handle millions of tasks in a list. Memory is the practical limit. Set maxmemory with an appropriate eviction policy.

Mini Project: Dual Broker Setup

import os
from celery import Celery

env = os.environ.get('APP_ENV', 'development')

if env == 'production':
    broker_url = 'amqp://user:pass@rabbitmq:5672/production_vhost'
    backend_url = 'redis://redis:6379/1'
elif env == 'staging':
    broker_url = 'amqp://user:pass@rabbitmq-staging:5672/staging_vhost'
    backend_url = 'redis://redis-staging:6379/1'
else:
    broker_url = 'redis://localhost:6379/0'
    backend_url = 'redis://localhost:6379/1'

app = Celery('multi_env', broker=broker_url, backend=backend_url)

app.conf.update(
    task_serializer='json',
    accept_content=['json'],
    result_serializer='json',
    timezone='UTC',
    enable_utc=True,
    broker_connection_retry_on_startup=True,
    broker_connection_max_retries=10,
    task_track_started=True,
)

@app.task
def process_data(data_id):
    return f"Processed {data_id} in {env} environment"
# Run with different environments
APP_ENV=development celery -A multi_env_app worker --loglevel=info
APP_ENV=production celery -A multi_env_app worker --loglevel=info

Expected output:

[2026-06-28 10:00:00: INFO/MainProcess] Connected to redis://localhost:6379/0
[2026-06-28 10:00:00: INFO/MainProcess] celery@hostname ready.

What's Next

Now that your broker is configured, learn about defining tasks with different options, then explore running the Celery worker with various settings.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro