Bird
Raised Fist0
Djangoframework~8 mins

Calling tasks asynchronously in Django - Performance & Optimization

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Performance: Calling tasks asynchronously
HIGH IMPACT
This affects how quickly the main web request responds by offloading long-running tasks to background workers.
Performing a long-running task during a web request
Django
from myapp.tasks import long_running_task

def view(request):
    long_running_task.delay()
    return HttpResponse("Task started, response sent immediately")
The task runs in the background, letting the web request respond immediately and improving user experience.
πŸ“ˆ Performance GainNon-blocking response, reduces INP by avoiding main thread blocking.
Performing a long-running task during a web request
Django
def view(request):
    result = long_running_task()
    return HttpResponse(f"Result: {result}")
The web request waits for the task to finish, blocking the response and causing slow page load and poor interaction.
πŸ“‰ Performance CostBlocks rendering for the duration of the task, increasing INP and LCP significantly.
Performance Comparison
PatternDOM OperationsReflowsPaint CostVerdict
Synchronous task in viewMinimalN/ABlocks paint until response[X] Bad
Asynchronous task with CeleryMinimalN/AImmediate paint and interaction[OK] Good
Rendering Pipeline
When tasks run synchronously, the browser waits for the server response, delaying rendering and interaction. Asynchronous tasks let the server respond quickly, so the browser can paint and become interactive sooner.
β†’Server Processing
β†’Network Response
β†’First Paint
β†’Interaction
⚠️ BottleneckServer Processing blocks the response when tasks run synchronously.
Core Web Vital Affected
INP
This affects how quickly the main web request responds by offloading long-running tasks to background workers.
Optimization Tips
1Never run long tasks directly in Django views; use asynchronous task queues.
2Use Celery or similar tools to run background tasks and keep web requests fast.
3Faster server responses improve user interaction and reduce input delay (INP).
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance benefit of calling tasks asynchronously in Django?
AThe task runs faster on the server
BThe database queries are optimized automatically
CThe web request responds faster without waiting for the task to finish
DThe browser caches the task results
DevTools: Performance
How to check: Record a performance profile while loading the page and interacting. Look for long server response times blocking the main thread.
What to look for: Long 'Waiting (TTFB)' times and delayed 'First Contentful Paint' indicate synchronous blocking. Short TTFB and quick paint indicate good async usage.

Practice

(1/5)
1. What is the main purpose of calling tasks asynchronously in a Django app using Celery?
easy
A. To avoid using any external libraries
B. To make the app run slower by adding extra steps
C. To run time-consuming tasks in the background without blocking the main app
D. To run tasks only when the server restarts

Solution

  1. Step 1: Understand asynchronous task calling

    Calling tasks asynchronously means running them in the background so the main app can continue working without waiting.
  2. Step 2: Identify the benefit in Django apps

    This helps keep the app fast and responsive by not blocking user requests with long tasks.
  3. Final Answer:

    To run time-consuming tasks in the background without blocking the main app -> Option C
  4. Quick Check:

    Async tasks = background work = To run time-consuming tasks in the background without blocking the main app [OK]
Hint: Async tasks run in background, keeping app responsive [OK]
Common Mistakes:
  • Thinking async tasks slow down the app
  • Believing async tasks run only on server restart
  • Confusing async with avoiding external libraries
2. Which of the following is the correct way to call a Celery task named send_email asynchronously?
easy
A. send_email.delay()
B. send_email()
C. send_email.async()
D. send_email.run()

Solution

  1. Step 1: Recall Celery task calling syntax

    Celery tasks are called asynchronously using the .delay() method.
  2. Step 2: Match the correct method to the task name

    Calling send_email.delay() queues the task to run in the background.
  3. Final Answer:

    send_email.delay() -> Option A
  4. Quick Check:

    Use .delay() to call async tasks [OK]
Hint: Use .delay() to call Celery tasks asynchronously [OK]
Common Mistakes:
  • Calling the task like a normal function without .delay()
  • Using .async() which is not a Celery method
  • Using .run() which executes task synchronously
3. Given the following Celery task and call:
@shared_task
def add(x, y):
    return x + y

result = add.delay(4, 5)

What will result.get() return after the task completes?
medium
A. 9
B. None
C. An error because .get() is not valid
D. A task ID string

Solution

  1. Step 1: Understand what add.delay(4, 5) does

    This queues the add task with arguments 4 and 5 to run asynchronously.
  2. Step 2: Understand result.get() usage

    Calling result.get() waits for the task to finish and returns the result, which is 4 + 5 = 9.
  3. Final Answer:

    9 -> Option A
  4. Quick Check:

    Task result = 4 + 5 = 9 [OK]
Hint: Use .get() to fetch async task result after completion [OK]
Common Mistakes:
  • Thinking .get() returns task ID instead of result
  • Believing .get() is invalid for Celery AsyncResult
  • Expecting None because task runs asynchronously
4. What is wrong with this Celery task call?
@shared_task
def multiply(x, y):
    return x * y

result = multiply(3, 7)
medium
A. The arguments 3 and 7 are invalid types
B. The task is missing the @app.task decorator
C. The function multiply should not return a value
D. The task is called synchronously, not asynchronously

Solution

  1. Step 1: Check how the task is called

    The task is called directly as multiply(3, 7), which runs it immediately and blocks.
  2. Step 2: Identify correct async call method

    To call asynchronously, it should be multiply.delay(3, 7).
  3. Final Answer:

    The task is called synchronously, not asynchronously -> Option D
  4. Quick Check:

    Direct call runs sync, use .delay() for async [OK]
Hint: Use .delay() to call tasks async, not direct function call [OK]
Common Mistakes:
  • Calling task function directly instead of using .delay()
  • Confusing @shared_task with @app.task (both valid but different)
  • Thinking return values are disallowed in tasks
5. You want to send a welcome email asynchronously after a user registers. Which approach correctly combines Django signals and Celery tasks to achieve this?
hard
A. Call send_welcome_email(user.id) directly inside the signal handler
B. Connect a signal handler that calls send_welcome_email.delay(user.id) after user creation
C. Use a signal to call send_welcome_email.run(user.id) synchronously
D. Call send_welcome_email.delay() before the user is saved

Solution

  1. Step 1: Understand the goal

    We want to send the email asynchronously after the user is created to avoid slowing registration.
  2. Step 2: Use Django signals with Celery correctly

    Connect a signal (like post_save) to call send_welcome_email.delay(user.id) after user creation, queuing the task.
  3. Final Answer:

    Connect a signal handler that calls send_welcome_email.delay(user.id) after user creation -> Option B
  4. Quick Check:

    Signal + .delay() after save = async email send [OK]
Hint: Use signals to trigger .delay() after user save [OK]
Common Mistakes:
  • Calling task directly inside signal, blocking request
  • Calling .run() which is synchronous
  • Calling .delay() before user exists in DB