FastAPI suporta tanto async def quanto def regular para operações de caminho. A escolha importa para o desempenho: use async def quando você puder I/O não-bloqueante, e regular quando seu código chamar operações bloqueantes (síncronas).
FastAPI suporta tanto async def quanto def regular para operações de caminho. A escolha importa para o desempenho: use async def quando você puder I/O não-bloqueante, e regular quando seu código chamar operações bloqueantes (síncronas).
awaitdef@app.get("/async")
async def async_endpoint():
data = await fetch_from_api() # await non-blocking I/O — efficient
return data
@app.get("/sync")
def sync_endpoint():
data = blocking_db_call() # ordinary blocking code
return data
async def → runs on the main event loop. Efficient ONLY if you await non-blocking calls.
⚠️ A BLOCKING call inside async def blocks the WHOLE event loop → kills concurrency!
def → FastAPI runs it in a THREAD POOL, so blocking code doesn't block the event loop.
Safe for synchronous/blocking libraries.
# ✅ async def — when you can await async libraries (httpx, async DB drivers)
async def get_user():
async with httpx.AsyncClient() as c:
return await c.get(url)
# ✅ plain def — when using SYNCHRONOUS/blocking libraries (requests, sync ORM)
def get_user():
return requests.get(url).json() # blocking → FastAPI runs it in a thread
# ❌ THE DANGEROUS MISTAKE — blocking call inside async def
async def bad():
return requests.get(url).json() # blocks the event loop! Use `def` or an async client
A regra crítica: nunca coloque chamadas bloqueantes em async def — isso bloqueia o event loop e destrói a concorrência. Use uma biblioteca async com await, ou use um def simples (que FastAPI executa com segurança em um thread pool).
Escolher corretamente entre async def e def afeta diretamente o desempenho e a concorrência de sua API, e errar é um erro comum e grave.
O insight-chave é que async def só é benéfico quando você await operações não-bloqueantes — colocar uma chamada bloqueante (como a biblioteca requests síncrona ou um driver de banco de dados bloqueante) dentro de um async def bloqueia todo o event loop, congela todas as solicitações concorrentes e destrói o propósito do async.
Inversamente, FastAPI executa inteligentemente endpoints def simples em um thread pool, então código síncrono/bloqueante é seguro lá.
Entender essa regra — use async def com bibliotecas realmente async, use def simples para código bloqueante, e nunca misture chamadas bloqueantes em async def — é essencial para escrever endpoints FastAPI com desempenho e evitar o erro sutil mas devastador de serializar acidentalmente todas as solicitações atrás de um event loop bloqueado.