Running Background Tasks
In this section, we will learn how to run background tasks in Django using Celery, a powerful task queue that allows you to execute time-consuming operations asynchronously. This is particularly useful for tasks like sending emails, processing files, or performing complex calculations without blocking the main application.
Redis is used for multiple purposes in a Django application, including as a message broker for Celery and for caching. It is an in-memory data structure store that can be used as a database, cache, and message broker.
Installing Redis
Section titled “Installing Redis”We will use Docker to run Redis locally. Add the following service to your docker-compose.yml file:
-
Add the Redis service to your
docker-compose.yml:services:redis:image: rediscontainer_name: redisrestart: alwaysports:- 6379:6379volumes:- ./data/redis:/datacommand: ["redis-server", "--appendonly", "yes"] # Enable data persistence (optional)redisinsight:image: redislabs/redisinsightcontainer_name: redisinsightports:- 8001:8001volumes:- ./data/redisinsight:/db -
Start the Redis server using Docker Compose:
Terminal window docker-compose up -d redis redisinsight -
To use Redis in your Django application, install the
redisPython client package:Terminal window uv add redis
This will start both the Redis server and RedisInsight, a web-based tool for managing Redis. You can access RedisInsight at http://localhost:8001 to monitor your Redis instance.
Celery
Section titled “Celery”Celery is a powerful task queue that allows you to run background tasks asynchronously. It helps you to offload time-consuming tasks from the main application thread, improving the responsiveness of your application.
Installing Celery
Section titled “Installing Celery”To install Celery, follow these steps based on your operating system:
Best option: Switch to Linux Ubuntu or use GitHub Codespaces to avoid manual configuration headaches. If you prefer to run Celery on Windows, you can use WSL (Windows Subsystem for Linux). Here’s how to set it up:
- Install Celery in your Django project:
Terminal window uv add celery - Setup WSL (Windows Subsystem for Linux) and follow the Linux instructions to run Celery in the WSL environment.
-
Install WSL and a Linux distribution (e.g., Ubuntu) from the Microsoft Store:
Terminal window wsl --install -
Install Python and required packages in the WSL environment:
Terminal window sudo apt updatesudo apt install python3 python3-pip -
Export your project dependencies to a
requirements.txtfile for the WSL environment:Terminal window uv export --format requirements-txt > requirements.txt# oruv export --no-hashes > requirements.txt# oruv export --no-dev > requirements.txt# oruv pip compile pyproject.toml -o requirements.txtUpdate your
.gitignorefile to include therequirements.txtand virtual environment directory to avoid committing them to version control:# .gitignorerequirements.txtwsl_venv/ -
Navigate to your project directory in the WSL terminal and create a virtual environment:
Terminal window python3 -m venv wsl_venvsource wsl_venv/bin/activatepip install -r requirements.txt -
Start the Celery worker in the WSL terminal:
Terminal window celery -A your_project_name worker --loglevel=info -
In another WSL terminal window, start the Celery beat scheduler:
Terminal window celery -A your_project_name beat --loglevel=info
-
- Install Celery in your Django project:
Terminal window uv add celery - Start the Celery worker to process tasks:
Terminal window celery -A your_project_name worker --loglevel=info - In another terminal, start the Celery beat scheduler for periodic tasks:
Terminal window celery -A your_project_name beat --loglevel=info
Configuring Celery
Section titled “Configuring Celery”To configure Celery in your Django project, follow these steps:
-
Create a
celery.pyfile in your Django project directory (same level assettings.py):# your_project_name/celery.pyimport osfrom celery import Celeryos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project_name.settings')celery = Celery('your_project_name')celery.config_from_object('django.conf:settings', namespace='CELERY')celery.autodiscover_tasks() -
Update your Django
__init__.pyfile to include the Celery app:# your_project_name/__init__.pyfrom .celery import celery as celery_app__all__ = ('celery_app',) -
Configure Celery settings in your
settings.pyfile:# settings.pyfrom celery.schedules import crontabCELERY_BROKER_URL = 'redis://localhost:6379/1'CELERY_RESULT_BACKEND = 'redis://localhost:6379/2'CELERY_BEAT_SCHEDULE = {'send-notifications-every-minute': {# format: 'your_project_name.app_name.tasks.task_name''task': 'your_project_name.tasks.notify_user',# crontab docs: https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html#crontab-schedules'schedule': crontab(minute='*'), # Run every minute'args': ["My Notification Message"],'kwargs': {}},}Here, we configure Redis as both the message broker and result backend for Celery. In the URLs:
redis://localhost:6379/1uses Redis database 1 as the broker (stores pending tasks)redis://localhost:6379/2uses Redis database 2 for storing task results
Using separate databases prevents data conflicts between different Celery components.
-
Create a
tasks.pyfile in one of your Django apps to define your background tasks:# your_project_name/tasks.pyfrom celery import shared_task@shared_taskdef notify_user(message):# Simulate a time-consuming taskimport timetime.sleep(5)print(f"Notification sent successfully: {message}")# your_project_name/tasks.pyfrom your_project_name.celery import celery@celery.taskdef notify_user(message):# Simulate a time-consuming taskimport timetime.sleep(5)print(f"Notification sent successfully: {message}") -
Start the Celery worker and beat scheduler in separate terminal windows:
Terminal window # Terminal 1: Start the worker process (processes queued tasks)celery -A your_project_name worker --loglevel=info# Terminal 2: Start the beat scheduler (triggers periodic tasks)celery -A your_project_name beat --loglevel=info
Monitoring Celery Tasks
Section titled “Monitoring Celery Tasks”To monitor Celery tasks, you can use the flower package, which provides a web-based dashboard for monitoring Celery workers and tasks in real-time.
- Install Flower:
Terminal window uv add flower - Start the Flower server in a new terminal:
Terminal window celery -A your_project_name flower --port=5555 - Access the Flower dashboard at
http://localhost:5555to monitor your Celery workers, tasks, and execution history.
Summary
Section titled “Summary”By following this guide, you have:
- Set up Redis as a message broker and result backend
- Configured Celery in your Django project
- Created background tasks using the
@shared_taskdecorator - Learned how to run worker and beat processes
- Enabled monitoring with Flower for visibility into task execution
Background tasks are essential for building scalable Django applications that can handle long-running operations without blocking user requests.