🔀

FastAPI async/await — The Difference Between def and async def

Does async def make it faster? It depends on the case

In FastAPI, these two behave completely differently.

def (regular function)

FastAPI auto-runs it in threadpool via run_in_executor(). Blocking I/O won't freeze the event loop.

async def

Runs directly on the event loop. Blocking code without await freezes the entire server. The most common mistake.

When to Use Which

  • Sync DB (SQLAlchemy sync) → def

  • Async DB (asyncpg, motor) → async def

  • requests lib → def, httpx → async def

  • CPU computation → def (GIL makes async meaningless anyway)

Key Points

1

def → FastAPI runs in threadpool (blocking I/O OK)

2

async def → runs on event loop (must use await)

3

Blocking code (requests.get etc.) in async def freezes entire server

4

When unsure, use def — FastAPI handles threadpool automatically

Use Cases

Servers with many external API calls — async + httpx for concurrent requests Legacy sync code migration — start with def, gradually switch to async