Asynchronous (async) and synchronous (sync) are topics I always been avoided. But recently I came across the path to look into it again. Two weeks ago an article What Color is Your Function? remind me the pain of mixing async and sync in the code. In FastAPI, the way endpoints handle requests depends on whether they are defined as synchronous (def
) or asynchronous (async def
). Let's break down the explanation:
Synchronous Endpoints (def
)
Synchronous Function: A function defined with
def
is synchronous, meaning it will execute from start to finish before moving on to the next task.External Threadpool: FastAPI runs these synchronous endpoints in a separate thread from an external threadpool.
Asynchronous Handling: Even though the function itself is synchronous, FastAPI manages it asynchronously by waiting for the thread to complete. This allows the server to handle other requests concurrently.
Concurrency: Each incoming request to a synchronous endpoint will use a new thread or reuse an existing one from the threadpool. This way, the server avoids being blocked by long-running synchronous tasks.
Asynchronous Endpoints (async def
)
Asynchronous Function: A function defined with
async def
is asynchronous, allowing it to yield control back to the event loop at certain points usingawait
.Event Loop: These endpoints run directly in the event loop, which operates in the main (single) thread.
Non-Blocking Operations: If the function contains
await
calls to non-blocking I/O operations (like reading from a database, waiting for network data, etc.), the server can handle multiple requests concurrently.Concurrency: The event loop can manage many such asynchronous tasks at once, making the server more efficient in handling I/O-bound operations.
Blocking Behavior
Lack of
await
inasync def
: If anasync def
function does not contain anyawait
calls, it does not yield control back to the event loop.Sequential Processing: In this case, the function will block the event loop until it finishes. As a result, requests to this endpoint (or others) will be processed sequentially, which can degrade performance.
Summary
def
Endpoints: Run in separate threads using an external threadpool, allowing FastAPI to handle them asynchronously by managing the threads.async def
Endpoints: Run in the event loop, and can handle multiple requests concurrently if they containawait
calls for non-blocking I/O operations.Avoiding Blocking: For
async def
endpoints to be efficient, they should includeawait
calls to ensure they do not block the event loop, thus maintaining asynchronous processing.
This approach ensures that FastAPI can handle both synchronous and asynchronous functions effectively, providing concurrency and efficient request handling. But make sure that you don't choose wrong function call. See FastAPI runs api-calls in serial instead of parallel fashion for deeper insight.