FastAPI: when to use async def versus def

Backend Live Coding November 13, 2026 python

FastAPI runs def in a threadpool, so blocking code (sync SQLAlchemy, requests) is safe there.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# ======================================================================
# Q: When do you write async def and when def in FastAPI?
#
# FastAPI runs def in a threadpool, so blocking code (sync SQLAlchemy, requests)
# is safe there. async def runs on the event loop: if you put a blocking call
# inside, the whole server freezes. So async def only when the whole chain is
# async (AsyncSession, httpx.AsyncClient, redis.asyncio).
# ======================================================================

# WRONG: blocks the event loop for all users
@app.get('/bad')
async def bad():
    return requests.get(URL, timeout=10).json()

# RIGHT 1: sync endpoint -> threadpool
@app.get('/ok-sync')
def ok_sync():
    return requests.get(URL, timeout=10).json()

# RIGHT 2: fully async
@app.get('/ok-async')
async def ok_async(client: httpx.AsyncClient = Depends(get_http_client)):
    r = await client.get(URL, timeout=10)
    return r.json()