0
0
FastapiComparisonBeginner · 3 min read

Async vs def in FastAPI: Key Differences and Usage Guide

Use async in FastAPI when your endpoint performs I/O-bound operations like database calls or network requests to improve concurrency. Use def for CPU-bound or simple synchronous code where async is unnecessary.
⚖️

Quick Comparison

This table summarizes the main differences between using async and def in FastAPI endpoints.

Factorasyncdef
Function TypeAsynchronous coroutine functionSynchronous regular function
Use CaseI/O-bound tasks (DB, HTTP calls)CPU-bound or simple sync tasks
ConcurrencyAllows other tasks to run during awaitBlocks until function completes
PerformanceBetter for many simultaneous requestsSimpler, less overhead for sync code
SyntaxMust use await insideNo await allowed
CompatibilityRequires async-compatible librariesWorks with any Python code
⚖️

Key Differences

FastAPI supports both async and def endpoint functions, but they behave differently under the hood. An async function is a coroutine that can pause its execution at await points, allowing FastAPI to handle other requests concurrently. This is especially useful when your endpoint calls external services like databases or APIs, which are I/O-bound and can take time to respond.

On the other hand, a def function runs synchronously and blocks the server until it finishes. This is fine for CPU-bound tasks or simple logic that does not involve waiting for external resources. Using async unnecessarily for CPU-heavy work can add overhead without benefits.

Also, async endpoints require that any libraries you call inside support asynchronous operations. If you use synchronous libraries inside an async function without proper handling, it can block the event loop and reduce performance.

⚖️

Code Comparison

python
from fastapi import FastAPI
import asyncio

app = FastAPI()

@app.get("/async")
async def read_async():
    await asyncio.sleep(1)  # Simulate I/O-bound wait
    return {"message": "Async response after 1 second"}
Output
{"message": "Async response after 1 second"}
↔️

def Equivalent

python
from fastapi import FastAPI
import time

app = FastAPI()

@app.get("/sync")
def read_sync():
    time.sleep(1)  # Simulate blocking CPU-bound wait
    return {"message": "Sync response after 1 second"}
Output
{"message": "Sync response after 1 second"}
🎯

When to Use Which

Choose async when:

  • Your endpoint performs I/O-bound operations like database queries, HTTP requests, or file operations.
  • You want to handle many requests concurrently without blocking the server.
  • You use async-compatible libraries that support await.

Choose def when:

  • Your code is CPU-bound or simple synchronous logic without waiting.
  • You use synchronous libraries that do not support async.
  • You want simpler code without async overhead.

Using the right function type improves FastAPI app performance and responsiveness.

Key Takeaways

Use async for I/O-bound tasks to improve concurrency in FastAPI.
Use def for CPU-bound or simple synchronous code.
Async endpoints require async-compatible libraries to avoid blocking.
Choosing the correct function type optimizes app responsiveness and resource use.