Mental model
Unlike WSGI (which handles requests synchronously using process/thread pools), ASGI (Asynchronous Server Gateway Interface) handles requests as asynchronous coroutines over event loops (uvloop).
Theory
An ASGI application is an async callable taking three arguments: scope (connection metadata dictionary), receive (coroutine to fetch incoming events), and send (coroutine to push outgoing response chunks).
Alternatives and trade-offs
- WSGI (Gunicorn / uWSGI): Synchronous blocking per thread; fails under heavy WebSocket or SSE streaming concurrency.
- ASGI (Uvicorn / Hypercorn): Non-blocking event loop concurrency; requires non-blocking async drivers for all I/O dependencies.
Failure modes and misconceptions
- Blocking I/O in Async Routes: Executing blocking synchronous code (e.g.
time.sleep(5)orrequests.get()) insideasync defroutes freezes the entire Uvicorn worker process event loop for all concurrent users. Usedef(which FastAPI offloads to a threadpool) or async libraries (httpx,asyncio.sleep). - Over-scaling Workers: Spawning 64 Uvicorn worker processes on an 8-core CPU wastes RAM and increases CPU context-switching overhead. General rule:
(2 * CPU_Cores) + 1.
Decision scenario
Run Gunicorn as the master process supervisor managing Uvicorn worker processes (gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker) for production containerized FastAPI deployments.
Learning outcomes
- Explain the ASGI
scope,receive, andsendprotocol contract. - Distinguish WSGI synchronous thread execution from ASGI asynchronous event loops.
- Calculate optimal Uvicorn worker process scaling for web workloads.
Trade-offs
ASGI servers enable sub-millisecond async I/O multiplexing, but require strict prevention of blocking CPU/I/O calls on the main event loop thread.