#556: Updates on Django's Async Story

Summary of #556: Updates on Django's Async Story

by Michael Kennedy

1h 4mJuly 26, 2026

Overview of Talk Python to Me #556: Updates on Django's Async Story

This episode is a deep dive into how Django’s async support has matured from “use with caution” to a much more practical, production-ready story. Michael Kennedy talks with Carlton Gibson about the rewritten async documentation, what parts of async still have real constraints, and which concerns were mostly historical fear. They also cover major upcoming Django 6.1 features, the new task framework, and Carlton’s own work on Django Mantle—a modern, typed serialization/data-access layer for Django.

Key Themes and Main Takeaways

Django’s async story is now much more complete

Carlton explains that the old docs overstated the danger and incompleteness of Django async. The current reality is:

  • Django’s async APIs are broadly in place across the ORM, cache framework, auth, sessions, and signals.
  • The remaining issues are mostly Python async / concurrency issues, not Django-specific shortcomings.
  • Performance overhead from sync_to_async is far smaller on modern Python than the old documentation suggested.

Async is useful, but not a magic fix

The conversation repeatedly emphasizes that async is great for some workloads, but not a universal solution:

  • It shines for:
    • long-lived requests
    • streaming responses
    • server-sent events
    • WebSockets
    • calling multiple slow external APIs concurrently
  • It is less useful when the bottleneck is:
    • database indexing
    • CPU-bound computation
    • poor query patterns
    • general application design issues

Django 6.1 Highlights

Database-level cascades for on_delete

One of the biggest upcoming improvements is the ability to push cascade behavior down to the database.

Why this matters:

  • Django has historically handled cascades in Python by walking object trees in memory.
  • That approach can become expensive or even dangerous at scale.
  • Database-level cascades are much better suited for large deletion chains and multi-table relationships.

Fetch modes / fetch_peers

Another major feature is fetch modes, especially fetch_peers, which helps solve the N+1 query problem more automatically.

What it does:

  • If you access the first related object in a collection, Django can fetch the rest eagerly as well.
  • It reduces the need to manually add prefetch_related() everywhere.
  • It’s designed to be a practical performance improvement without requiring every developer to remember every access path.

Custom multipart parser class

Django 6.1 also allows customizing the multipart parser on the request object.

Why Carlton cares:

  • It’s not a feature most people will touch.
  • But for applications handling large multipart uploads, it could provide meaningful performance gains.
  • More importantly, it opens the door to deeper request-level customization.

Django Tasks: Built-In Background Jobs

A backend-agnostic task framework

Carlton discusses Django’s new task framework, which is intended to standardize background work without forcing everyone into Celery.

The idea:

  • Django provides a common API for enqueuing tasks and checking results.
  • Different backends can implement that API.
  • This allows packages to support tasks without committing to one queue system.

Why this matters

This solves a long-standing ecosystem problem:

  • Package authors can expose background jobs without locking users into Celery, RQ, Huey, or another specific backend.
  • Users can choose the backend that fits their stack.
  • Simpler projects can use lightweight options like ORM-based or Redis-backed queues.

Carlton’s view on Celery

He’s very positive about Celery as software, but notes that it is often:

  • operationally heavy
  • overkill for many projects
  • more complex than teams expect once they factor in workers, beat, monitoring, and failure handling

Django Mantle: A Modern Serialization Story

What Mantle is

Mantle is Carlton’s attempt to rethink serialization and data access in Django using modern typing-friendly tools like:

  • attrs
  • cattrs
  • Pydantic-like patterns, but ORM-aware

The core idea

Mantle separates:

  • the database model / dynamic ORM layer
  • the typed, static “shape” layer used by application logic

This gives you:

  • better typing support
  • more explicit architecture
  • cleaner separation of responsibilities
  • controlled eager loading and validation
  • protection from N+1 issues by design

Why he built it

Carlton argues that as Django apps grow, models often accumulate too many responsibilities:

  • persistence
  • business logic
  • display logic
  • validation
  • aggregation

Mantle is his answer to that natural architectural drift.

Async, Threads, and Free-Threaded Python

The GIL and CPU-bound work

A big portion of the discussion is about why async still has limitations in Python:

  • Async helps with I/O concurrency.
  • But CPU-bound work still blocks the event loop or hits GIL contention when pushed to threads.
  • That’s why parallelism is still constrained in standard Python.

Why free-threading matters

Carlton is optimistic about free-threaded Python:

  • Django already uses threads in a lot of places.
  • The ecosystem has largely been written with thread-safety in mind.
  • If libraries and apps test well under free-threaded Python, Django could gain real performance benefits without major architectural changes.

Practical Guidance for Django Developers

When to use async views

Good candidates:

  • long-lived connections
  • streaming
  • SSE
  • WebSockets
  • concurrent I/O to multiple APIs

Less important if:

  • your app is mostly request/response
  • your bottleneck is the database
  • you’re just hoping async will make a slow app fast

When to use ASGI

Carlton suggests ASGI is most valuable when you need long-lived connections or async endpoints, but many teams may still want:

  • core app on WSGI
  • async endpoints on a sidecar ASGI deployment

That hybrid approach lets teams adopt async gradually.

Don’t ignore the basics

Before reaching for async or more workers, check:

  • database indexes
  • query plans
  • N+1 queries
  • CPU hotspots
  • memory overhead from too many workers

His message is clear: async is powerful, but it is not a substitute for good fundamentals.

Community and Process Notes

Django’s development process has improved

Carlton mentions:

  • a new features board on GitHub
  • better visibility into proposed features
  • faster resolution of long-running debates when discussed in person

Django on the Med

He also talks about Django on the Med, a core-dev sprint event designed to create focused, in-person work time for contributors.

The benefits:

  • easier collaboration
  • faster decisions
  • better onboarding for new contributors
  • tangible progress on hard features like database cascades

Bottom Line

The episode’s central message is that Django’s async story is no longer “half-finished”. The framework is ready for real async usage, and the remaining issues are mostly general Python concurrency concerns rather than Django-specific gaps.

At the same time, Carlton makes a strong case for practical engineering:

  • use async where it genuinely helps
  • use tasks for background work
  • optimize the database first
  • adopt new features gradually
  • watch free-threaded Python closely

For Django developers, this episode is both a reality check and a roadmap.