Django update: the Python framework embraces async

Django 3.0 introduces ASGI support and first async views: a synchronous framework opens to concurrency without abandoning its API, with a gradual migration path.

Open SourceWeb Open SourceDjangoPythonASGIAsyncBackend

A synchronous framework in an asynchronous world

For fifteen years Django has built its identity around a synchronous execution model: a request arrives, is processed from start to finish on a single thread and produces a response. The approach is predictable, easy to debug and compatible with the entire ecosystem of middleware, ORM and libraries built on the certainty that each operation completes before the next begins.

But the web application landscape has changed. WebSockets, server-sent events, calls to external services with unpredictable latencies and microservice architectures make the synchronous model a constraint. Frameworks such as FastAPI and Starlette, built natively on Python’s asyncio, demonstrate that asynchronous concurrency improves throughput on I/O-bound workloads without requiring more threads or processes.

Django 3.0 and ASGI support

With version 3.0, released in December 2019, Django introduces support for ASGI (Asynchronous Server Gateway Interface), the asynchronous successor to WSGI. ASGI allows serving Django through asynchronous servers like Daphne or Uvicorn, opening the door to concurrent handling of long-lived connections.

The architectural choice is deliberately conservative: Django 3.0 can be served via ASGI, but views, middleware and the ORM remain synchronous. The framework executes synchronous code in a thread pool within the async loop, maintaining compatibility with all existing code. This is not a rewrite: it is a gradual opening.

The first async views

Django 3.1, released the following August 2020, takes the next step by introducing async views: view functions declared with async def that can use await for non-blocking operations. An endpoint that needs to wait for a response from an external API or service can now do so without blocking the thread, freeing resources to handle other requests.

Middleware receives an analogous migration path: Django supports both synchronous and asynchronous middleware, and the framework automatically manages the transition between the two worlds when needed. Signals and the authentication system remain synchronous in 3.1, with migration planned for subsequent versions.

The ORM stays synchronous — for now

The ORM is the most complex component to migrate: database queries are inherently blocking, and the entire system of QuerySets, managers and relations is built on synchronous operations. Django 3.x keeps the ORM synchronous, using sync_to_async as a bridge when called from asynchronous code. The roadmap envisions a native asynchronous ORM interface in future versions, but the priority is not breaking compatibility with the thousands of existing applications.

Gradual migration as strategy

Django’s strategy reflects a clear philosophy: open up to concurrency without forcing a rewrite. Existing applications continue to work without modifications. New endpoints can be asynchronous where the benefit is tangible. For organisations with established Django codebases, this incremental approach reduces risk and allows adopting async where it truly matters.

Link: djangoproject.com

Need support? Under attack? Service Status
Need support? Under attack? Service Status