[Django] #36797: Implement fully async-capable support for django.middleware.common.CommonMiddleware

4 views
Skip to first unread message

Django

unread,
Dec 12, 2025, 9:55:44 AM12/12/25
to django-...@googlegroups.com
#36797: Implement fully async-capable support for
django.middleware.common.CommonMiddleware
-------------------------------------+-------------------------------------
Reporter: Mykhailo Havelia | Type: New
| feature
Status: new | Component: HTTP
| handling
Version: 6.0 | Severity: Normal
Keywords: async | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
From the Django documentation:

> You will only get the benefits of a fully asynchronous request stack if
you have no synchronous middleware loaded into your site.

Currently, all of Django's internal middleware uses `MiddlewareMixin` and
relies on `sync_to_async` under the hood. This makes it difficult for end
users to have a fully async request flow, because they would need to copy
and adapt all internal logic for each middleware, and maintain it across
Django releases.

Some internal middleware only performs `CPU`-bound operations and does not
require `async`/`AIO` logic, so it could safely be used in both `sync` and
`async` contexts without `sync_to_async`.

Options to solve this

- Implement `__acall__` without `sync_to_async`

Not recommended. Can lead to subtle bugs if users subclass and customize
the middleware:


{{{
class CustomCommonMiddleware(CommonMiddleware):
def process_response(self, request, response):
# custom logic
return super().process_response(request, response)
}}}


In an async context, this custom logic would be ignored or behave
unexpectedly.

- Rewrite middlewares using `sync_and_async_middleware` decorator

Safe and straightforward. Breaking change: would break all existing custom
middleware that inherits from the internal middleware.

- Implement separate async middleware (`AsyncCommonMiddleware`)

Compromise solution. Safe for users: they can explicitly replace
`CommonMiddleware` with `AsyncCommonMiddleware` in async setups.
When `MiddlewareMixin` is eventually removed, we can rename
`AsyncCommonMiddleware` -> `CommonMiddleware` without breaking changes.

I'm going to start by implementing an async version of CommonMiddleware as
a test case for this approach. Once we validate it, the plan is to extend
the same pattern to:

- django.contrib.auth.middleware.AuthenticationMiddleware
- django.middleware.locale.LocaleMiddleware
- django.middleware.security.SecurityMiddleware

If you have any thoughts or concerns about this approach, especially
regarding edge cases or backward compatibility, please share them.
--
Ticket URL: <https://code.djangoproject.com/ticket/36797>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 12, 2025, 10:50:17 AM12/12/25
to django-...@googlegroups.com
#36797: Implement fully async-capable support for
django.middleware.common.CommonMiddleware
----------------------------------+--------------------------------------
Reporter: Mykhailo Havelia | Owner: (none)
Type: New feature | Status: new
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: async | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Comment (by Clifford Gama):

Hello, Mykhailo,

Thanks for the ticket. Given this is a new feature request, it will have
to be proposed and discussed with the community on the
[https://github.com/django/new-features/issues new features tracker].

I'll close the ticket for now, but if the community agrees with the
proposal, please reopen and reference the issue in the features tracker.
For more information, please refer to ​the
[https://docs.djangoproject.com/en/stable/internals/contributing/bugs-and-
features/#requesting-features documented guidelines for requesting
features].
--
Ticket URL: <https://code.djangoproject.com/ticket/36797#comment:1>

Django

unread,
Dec 12, 2025, 10:52:26 AM12/12/25
to django-...@googlegroups.com
#36797: Implement fully async-capable support for
django.middleware.common.CommonMiddleware
----------------------------------+--------------------------------------
Reporter: Mykhailo Havelia | Owner: (none)
Type: New feature | Status: closed
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution: wontfix
Keywords: async | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Changes (by Clifford Gama):

* resolution: => wontfix
* status: new => closed

--
Ticket URL: <https://code.djangoproject.com/ticket/36797#comment:2>
Reply all
Reply to author
Forward
0 new messages