Design, configure, and test Celery async and scheduled jobs in Django.
Copy the install command and let the AI configure it · recommended for beginners
Please install the "django-celery" skill from askskill: 1. Download https://raw.githubusercontent.com/affaan-m/ECC/main/skills/django-celery/SKILL.md 2. Save it as ~/.claude/skills/django-celery/SKILL.md 3. Reload skills and tell me it's ready
Design a Celery-based async email sending setup for a Django project, including Django and Celery configuration, task definitions, invocation patterns, retry strategy, and recommendations for local development and production.
A practical Django + Celery async email solution with sample configuration, task structure, and retry guidance.
Explain how to configure periodic tasks with Celery Beat in Django, such as syncing order data every night. Include configuration steps, task examples, timezone considerations, and advice to avoid duplicate execution.
A complete implementation guide for Celery Beat periodic jobs, including scheduling config, sample code, and operational caveats.
Create a testing and monitoring plan for a Django + Celery project, covering unit tests, integration tests, task status tracking, failure alerts, and recommendations for Flower or other monitoring tools.
A testing and monitoring checklist for Django + Celery to improve task reliability and observability.
Production-grade patterns for background task processing in Django using Celery with Redis or RabbitMQ.
pip install 'celery[redis]' django-celery-results django-celery-beat
celery.py — App Entrypoint# config/celery.py
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.development')
app = Celery('myproject')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks() # Discovers tasks.py in each INSTALLED_APP
@app.task(bind=True, ignore_result=True)
def debug_task(self):
print(f'Request: {self.request!r}')
# config/__init__.py
from .celery import app as celery_app
__all__ = ('celery_app',)
# config/settings/base.py
# Broker (Redis recommended for production)
CELERY_BROKER_URL = env('CELERY_BROKER_URL', default='redis://localhost:6379/0')
CELERY_RESULT_BACKEND = env('CELERY_RESULT_BACKEND', default='django-db')
# Serialization
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
# Task behavior
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60 # Hard limit: 30 min
CELERY_TASK_SOFT_TIME_LIMIT = 25 * 60 # Soft limit: sends SoftTimeLimitExceeded
CELERY_WORKER_PREFETCH_MULTIPLIER = 1 # Prevent worker hoarding long tasks
CELERY_TASK_ACKS_LATE = True # Re-queue on worker crash
# Result persistence
CELERY_RESULT_EXPIRES = 60 * 60 * 24 # Keep results 24 hours
# Beat scheduler (for periodic tasks)
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
# Installed apps
INSTALLED_APPS += [
'django_celery_results',
'django_celery_beat',
]
# Start worker (development)
celery -A config worker --loglevel=info
# Start beat scheduler (periodic tasks)
celery -A config beat --loglevel=info --scheduler django_celery_beat.schedulers:DatabaseScheduler
# Combined worker + beat (dev only, never production)
celery -A config worker --beat --loglevel=info
# Production: multiple workers with concurrency
celery -A config worker --loglevel=warning --concurrency=4 -Q default,high_priority
# apps/notifications/tasks.py
from celery import shared_task
import logging
logger = logging.getLogger(__name__)
@shared_task(name='notifications.send_welcome_email')
def send_welcome_email(user_id: int) -> None:
"""Send welcome email to newly registered user."""
from apps.users.models import User
from apps.notifications.services import EmailService
try:
user = User.objects.get(pk=user_id)
except User.DoesNotExist:
logger.warning('send_welcome_email: user %s not found', user_id)
return # Idempotent — do not raise, task already impossible to complete
EmailService.send_welcome(user)
logger.info('Welcome email sent to user %s', user_id)
@shared_task(
bind=True,
name='integrations.sync_to_crm',
max_retries=5,
default_retry_delay=60, # seconds before first retry
autoretry_for=(ConnectionError, TimeoutError),
retry_backoff=True, # exponential backoff
retry_backoff_max=600, # cap at 10 minutes
retry_jitter=True, # randomise to avoid thundering herd
)
def sync_contact_to_crm(self, contact_id: int) -> dict:
"""Sync contact to external CRM with retry on transient failures."""
from apps.crm.services import CRMClient
try:
…
Handle returns, refunds, fraud checks, and warranty claim decisions efficiently.
Use Bun for runtime, bundling, testing, packages, and Node migration decisions.
Use the correct Ethereum Keccak-256 hashing in Node.js and TypeScript.
Apply Nuxt 4 patterns for SSR safety, performance, and data fetching.
Generate images, videos, and audio with one unified AI media workflow.
Design Quarkus 3 backend patterns for messaging, APIs, data, and async workflows.
Learn Django architecture, DRF API design, and production-ready development practices.
Schedule, run, and manage one-time or recurring automated tasks.
Run pre-release verification for Django projects across tests, security, and deployment checks.