WSGI vs ASGI server with hybrid sync/async Django app
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Modern Django can run both synchronous and asynchronous views, which leads many teams to ask whether a hybrid app should still use WSGI or move to ASGI. The short answer is that WSGI is fine for fully synchronous workloads, but ASGI is the correct server interface if you want first-class async views, WebSockets, or long-lived connections.
What WSGI and ASGI Actually Mean
WSGI is the older Python web-server interface built around synchronous request handling. It works well with classic Django deployments and mature tooling such as Gunicorn with sync workers.
ASGI is the newer asynchronous interface. It supports HTTP too, but it also supports protocols and execution patterns that WSGI does not handle well, such as:
- async request handling
- WebSockets
- long polling
- background connection management
The important detail is that Django can adapt between sync and async code internally, but the outer server interface still affects performance characteristics and feature support.
What Happens in a Hybrid Django App
A hybrid Django app may contain both sync and async views. For example, a traditional database-backed HTML page may remain synchronous, while an endpoint that calls multiple external APIs concurrently may be asynchronous.
Under ASGI, Django can run both kinds of views. Sync views are executed in a thread-sensitive adapter, and async views run natively.
Under WSGI, Django can still expose async views, but they are adapted through a synchronous boundary. That means you lose many of the reasons for writing async code in the first place.
Example of Sync and Async Views
Django can route both views. The difference is how effectively the surrounding server stack can execute them.
When WSGI Is Still Fine
WSGI remains a solid choice when the application is mostly synchronous and you do not need WebSockets or other async-native behavior. Examples include:
- classic server-rendered apps
- admin dashboards
- CRUD-heavy internal tools
- codebases where the database and middleware stack are mostly synchronous anyway
In that scenario, forcing an ASGI migration may not buy much. A well-tuned WSGI deployment is still operationally simple and mature.
When ASGI Is the Better Choice
If the application genuinely benefits from asynchronous I/O, ASGI is the right interface. That includes cases where you want to:
- serve WebSockets through Django Channels or a similar stack
- await multiple external API calls efficiently
- handle long-lived responses without tying up sync workers
- grow into a more async-heavy architecture over time
A typical ASGI entry point in Django looks like this:
That application can then be served by an ASGI server such as Uvicorn or Daphne.
Deployment Tradeoffs
For WSGI, a common deployment is Gunicorn with sync workers. For ASGI, a common deployment is Uvicorn or Gunicorn using Uvicorn workers. The right choice is not about fashion. It is about whether your runtime behavior is mostly blocking or mostly non-blocking.
A mistake teams make is writing a few async views and expecting large performance gains while the rest of the stack still uses blocking database calls, blocking HTTP clients, or synchronous middleware. Async only helps where the underlying work is also non-blocking.
Common Pitfalls
- Choosing ASGI only because Django supports async can add deployment complexity without meaningful benefit when the app is still mostly synchronous. Match the server model to the workload.
- Expecting WSGI to provide the real advantages of async Django defeats the purpose of writing async views. WSGI forces the app back through a synchronous boundary.
- Writing
async defviews while still calling blocking libraries inside them can hurt performance rather than improve it. Async code must use non-blocking dependencies to pay off. - Assuming sync and async middleware behave identically can lead to unexpected adaptation overhead. Review middleware compatibility during a migration.
- Treating WebSockets as just another HTTP route is incorrect. If you need WebSockets, ASGI is the practical requirement.
Summary
- WSGI is still a strong option for mostly synchronous Django apps.
- ASGI is the correct choice when you need native async handling or WebSockets.
- Hybrid Django apps can run under either interface, but only ASGI preserves the full benefit of async views.
- Async code helps only when the underlying libraries and I/O paths are also non-blocking.
- Pick the server model based on actual runtime behavior, not on framework trend alone.
Related reading
- Xamarin Gcm Network Manager await httpclient
- Xamarin.Android no stack trace in async method
- XCTest NSURLSession Stall on main thread
- xunit Assert.ThrowsAsync does not work properly?
- XGBModel' object has no attribute 'evals_result_
- XGBoost AttributeError 'DataFrame' object has no attribute 'feature_names
- You Don't Know JS Async and Performance - cooperative concurrency?
- ZeroMQ How to handle non-message-related, asynchronous events in a ZeroMQ node?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.