Sentry Answers>FastAPI>

FastAPI: difference between run_in_executor and run_in_threadpool

FastAPI: difference between run_in_executor and run_in_threadpool

David Y.

The Problem

In FastAPI, what’s the difference between run_in_executor and run_in_threadpool? As far as I can tell, both are used to execute a task in another thread. When should I use one over the other?

The Solution

Both run_in_executor and run_in_threadpool are used to run synchronous code (also called blocking code) in an asynchronous application without blocking the event loop. run_in_executor is a relatively low-level operation, originating in Python’s asyncio library, whereas run_in_threadpool comes from Starlette, the ASGI framework underlying FastAPI.

As a result, run_in_threadpool is simpler to use at the cost of flexibility, and run_in_executor is more flexible at the cost of increased complexity. Consider the following two code examples:

Click to Copy
# Using run_in_executor import asyncio from concurrent.futures import ThreadPoolExecutor def sync_function(argument1, argument2): # logic for the sync function here pass async def main(): loop = asyncio.get_running_loop() with ThreadPoolExecutor() as pool: result = await loop.run_in_executor(pool, sync_function, 'argument1', 'argument2')
Click to Copy
# Using run_in_threadpool from fastapi import FastAPI from starlette.concurrency import run_in_threadpool app = FastAPI() def sync_function(argument1, argument2): # logic for the sync function here pass async def example_route(): result = await run_in_threadpool(sync_function, 'argument1', 'argument2')

As we can see, the run_in_threadpool code is simpler – unlike the run_in_executor code, it does not require us to specify an executor, as it will always use the default executor. Most of the time, this is what we want – run_in_threadpool is integrated with FastAPI’s design and is the recommended approach for most use cases.

However, if we have a complicated application that needs to integrate a variety of disparate synchronous systems, we may want the additional control that run_in_executor provides. For example, some applications may benefit from using ProcessPoolExecutor instead of ThreadPoolExecutor.

  • Syntax.fmListen to the Syntax Podcast (opens in a new tab)
  • Community SeriesIdentify, Trace, and Fix Endpoint Regression Issues (opens in a new tab)
  • ResourcesBackend Error Monitoring 101 (opens in a new tab)
  • Syntax.fm logo
    Listen to the Syntax Podcast (opens in a new tab)

    Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.

    SEE EPISODES

Considered “not bad” by 4 million developers and more than 150,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.