#36797 closed New feature (wontfix)

Implement fully async-capable support for django.middleware.common.CommonMiddleware

Reported by: Mykhailo Havelia Owned by:
Component: HTTP handling Version: 6.0
Severity: Normal Keywords: async
Cc: Mykhailo Havelia Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

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.

Change History (2)

comment:1 by Clifford Gama, 52 minutes ago

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 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 documented guidelines for requesting features.

comment:2 by Clifford Gama, 49 minutes ago

Resolution: wontfix
Status: newclosed
Note: See TracTickets for help on using tickets.
Back to Top