Getting Started with Celery: Asynchronous Task Queue for Python

Celery is a distributed task queue or job queue built on asynchronous message passing. It allows Python applications to process background tasks either immediately or at a scheduled time. You can configure Celery to run tasks synchronously or asynchronously, depending on your use case.

Asynchronous message passing ensures that messages are stored between the sender and receiver. This enables the sender to continue other operations after sending a message and allows multiple messages to be queued before being processed.

Main Components of Celery

  • Tasks
  • Task Broker
  • Result Backend
  • Worker

Tasks are standard Python functions that Celery executes in its workers. They are identified with a special decorator to distinguish them from regular functions.

The Task Broker is the system responsible for delivering messages between your application and Celery. It handles the transmission of tasks for execution. Supported brokers include Redis®, RabbitMQ, and Amazon SQS.

The Result Backend stores the results of executed tasks. Celery retrieves this information after completion. It supports various backends such as Redis®, RabbitMQ (AMQP), and SQLAlchemy.

A Worker is a Celery process that continuously runs in the background, waiting for tasks to arrive in the broker. Typically, multiple workers operate simultaneously to ensure concurrent task execution.

Task Life Cycle in Celery

Celery’s task execution process consists of three main stages:

  • Task Registration
  • Task Execution
  • Result Storage

Your application sends a task to the broker, which is then picked up by a worker for execution. Once processed, the result is stored in the result backend.

Applications of Celery

Celery can be used in various ways depending on your project’s needs. Below are the most common applications:

  • Periodic Execution – Tasks that run at fixed intervals, such as sending a monthly newsletter.
  • Third-Party Execution – Tasks that interact with external systems, like sending emails via SMTP.
  • Long-Running Execution – Tasks requiring significant time, such as compressing or processing large files.

Creating Your First Celery Program

This section demonstrates how to integrate Celery tasks into a simple Python program.

Prerequisites

To follow this guide, ensure you have:

  • Python 3.7 or later
  • Redis® server installed

Installing Celery

Celery can be installed via Python’s package manager (pip).

Install the latest version of Celery:

Install dependencies for Redis® support:

Writing Your First Celery Task

Here’s a simple example of converting a regular Python function into a Celery task.

Import and initialize the Celery object:

from celery import Celery

app = Celery(
    'tasks',
    broker="redis://localhost:6379/0",
    backend="redis://localhost:6379/0"
)

If your Redis® configuration differs, modify the connection string accordingly:
redis://username:password@hostname:port/db

Create a simple Celery task:

@app.task
def multiply(a, b):
    import time
    time.sleep(5)
    return a * b

Final version of tasks.py:

from celery import Celery

app = Celery(
    'tasks',
    broker="redis://localhost:6379/0",
    backend="redis://localhost:6379/0"
)

@app.task
def multiply(a, b):
   import time
   time.sleep(5)
   return a * b

Managing Celery Workers

Workers execute tasks that are queued by Celery.

Start a Celery worker:

celery -A tasks worker -n worker1 -P prefork -l INFO

Arguments explained:

  • -A: Specifies the application.
  • -n: Names the worker.
  • -P: Defines the pool type.
  • -l: Sets log level.

To run the worker in the background, add the -D flag.

Stop all Celery workers:

ps auxww | awk '/celery(.*)worker/ {print $2}' | xargs kill -9

Executing Tasks in Celery

After starting the worker, open a Python shell in the same directory as tasks.py.

Import and execute the task:

from tasks import multiply
task1 = multiply.delay(512, 100)

Check task status:

Retrieve result:

Types of Celery Workers

Choosing the right worker type affects efficiency and performance.

  • Solo – Executes tasks sequentially.
  • Prefork – Uses multiple processes for parallel task execution.
  • Eventlet – Uses green threads for concurrent I/O-bound tasks.
  • Gevent – Similar to Eventlet, ideal for network-bound workloads.

Start worker with Solo pool:

celery -A tasks worker --pool=solo --loglevel=info

Start worker with Prefork pool:

celery -A tasks worker --pool=prefork --concurrency=4 --loglevel=info

Start worker with Eventlet or Gevent pool:

celery -A tasks worker --pool=eventlet --concurrency=500 --loglevel=info
celery -A tasks worker --pool=gevent --concurrency=500 --loglevel=info

Note: Install dependencies for Eventlet or Gevent separately:
pip install celery[eventlet] or pip install celery[gevent]

Conclusion

With this guide, you learned how to integrate Celery into Python applications. Celery powers background task execution for many SaaS applications, offering scalable and efficient asynchronous processing for diverse workloads.

Source: vultr.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in: