Từ Django 3.1, middleware có thể chạy async.
Khai báo bằng cách set async_capable = True + sync_capable = False rồi dùng async def __call__.
class AsyncTimingMiddleware:
sync_capable = False
async_capable = True
def __init__(self, get_response):
self.get_response = get_response
async def __call__(self, request):
start = time.perf_counter()
response = await self.get_response(request)
response['X-Render-MS'] = f'{(time.perf_counter() - start) * 1000:.1f}'
return responseDjango tự chọn mode (sync/async) dựa trên chuỗi middleware + view. Nếu trong chuỗi có một mắt xích chỉ sync, Django wrap async ↔ sync bằng asgiref.sync.async_to_sync / sync_to_async — mỗi lần wrap là một event-loop hop, tức là overhead thực.
Hai lỗi hay gặp: gọi ORM (Post.objects.filter(...)) sync-style trong async middleware sẽ bị SynchronousOnlyOperation, phải dùng await Post.objects.afilter(...) hoặc bọc sync_to_async(...). Và để một sync middleware nằm giữa stack async là toàn pipeline bị degrade vì wrap qua wrap lại.
Đo trước khi đua theo async. Nếu view chính vẫn là sync (Postgres chưa có driver async thực sự ổn), async middleware không cứu được hiệu năng — tối ưu DB hoặc cache thường có ROI cao hơn nhiều.