Written with the assistance of AI (ChatGPT)
π§ The Basics
If you're building web apps with Flask, Django, or FastAPI, you've probably heard terms like:
- WSGI
- ASGI
Sync
Async
Blocking
Non-blocking
But what do these actually mean for you as a developer?
Letβs break it down β simply.
π WSGI vs ASGI
When building web apps in Python, WSGI (Web Server Gateway Interface) and ASGI (Asynchronous Server Gateway Interface) determine how requests are handled and how your server communicates with your code.
WSGI is the traditional standard used by synchronous Python web frameworks like Flask and Django. It processes one request per thread, meaning it blocks the thread until that request is completed. This is fine for low-traffic apps but can cause slowdowns when handling many concurrent users.
ASGI, on the other hand, was introduced to support asynchronous operations and handle concurrency. It allows multiple requests to be processed at the same time using async/await. This makes it ideal for modern frameworks like FastAPI and Django Channels, which need to handle high traffic or tasks like real-time updates, long-running operations, or handling I/O-bound operations (e.g., database queries, API calls).
In simple terms:
WSGI: One thread, one request at a time.
ASGI: Multiple threads (or coroutines), multiple requests at once.
π§± Synchronous (WSGI)
In a synchronous world (like using Flask), each request blocks the thread it's running on until it's done:
@app.route("/X")
def sync_x():
time.sleep(5) # Simulates a long task
return "Done"
Problem:
User A calls
/X
β sleeps for 5 secDuring this, no other requests can be handled (on a single worker)
User B or C? They wait.
Unless you scale with multiple threads or processes, your app becomes slow under load.
β‘ Asynchronous (ASGI)
With frameworks like FastAPI, you can write non-blocking code using async def
and await
:
@app.get("/X")
async def async_x():
await asyncio.sleep(5) # Simulated non-blocking delay
return {"message": "Done"}
Benefit:
User A hits
/X
and awaitsWhile waiting, the server handles User B and User C
All requests proceed without blocking each other
π§ͺ Real-World Scenario: 3 Users, Same Endpoint
SYNC Version (blocking):
from fastapi import FastAPI
import time
app = FastAPI()
@app.get("/sync")
def sync_endpoint():
time.sleep(5)
return {"message": "Sync response"}
ASYNC Version (non-blocking):
from fastapi import FastAPI
import asyncio
app = FastAPI()
@app.get("/async")
async def async_endpoint():
await asyncio.sleep(5)
return {"message": "Async response"}
Test:
Sync: Each request waits its turn
Async: All requests run at the same time
Thatβs the power of non-blocking code.
π€ Waitβ¦ Doesnβt await
Still βWaitβ?
Yes! But only your coroutine pauses β the event loop keeps going.
a = await some_async_call()
b = a + 1
Your function pauses at await
, but the server is free to do other things.
When some_async_call()
completes, your code resumes with b = a + 1
.
π What is a Coroutine?
A coroutine is a special type of function that can pause and resume its execution β perfect for handling I/O tasks like API calls, database queries, or sleep timers without blocking the main thread.
In Python, any function defined with async def
is a coroutine:
async def get_data():
await asyncio.sleep(1)
return "Done"
Coroutines give you concurrency without threads β theyβre lightweight, efficient, and ideal for high-performance web apps.
π§ Final Thoughts
Use WSGI (sync) for simple apps or when working with older libraries.
Use ASGI (async) for modern apps that need speed, scale, or handle I/O (DBs, APIs).
Even a simple change like switching from
time.sleep()
toawait asyncio.sleep()
can unlock huge performance gains.
π¬ TL;DR
Feature | Sync (WSGI) | Async (ASGI) |
---|---|---|
Blocking | Yes (per request) | No (per request) |
Concurrency | Threads/Processes | Coroutines (cheap!) |
Popular With | Flask, Django (classic) | FastAPI, Django (ASGI) |
Performance | Good (low traffic) | Excellent (high traffic) |
π References and Further Reading
Real Python: Async IO in Python
ASGI Spec: asgi.readthedocs.io
FastAPI Docs: fastapi.tiangolo.com
Django Async Support: docs.djangoproject.com
WSGI Spec: wsgi.readthedocs.io
Top comments (0)