question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Does it make sense to use ThreadPoolExecutor in fastAPI

See original GitHub issue

Hi All,

I have a super simple app that has only one endpoint. This endpoint loads data from a database and this is parallelised using a ThreadPoolExecutor. For example:

@app.get('/load_from_db')
def load_from_db():
    ....
    with concurrent.futures.ThreadPoolExecutor() as executor:
        for dataset in datasets:
            executor.submit(dataset.load_from_database)
    ....

Now I changed from Flask to FastAPI. I have declared my function as def load_from_db such that it is executed in a different thread-pool and does not block the main thread.

OUT-DATED As a result my service now is 10x slower than using Flasks? I tried to set max_workers=5 but did no really help. What is the reason?

EDIT: I created again some thorough test cases and it turns out fastAPI is not slower for me. Let’s change the question to:

Is it safe & does it make sense to use ThreadPoolExecutor in fastAPI?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

9reactions
nzigcommented, Jun 2, 2021

@hellocoldworld is correct. I will add that in some cases you do actually need a thread pool, if you want to mix async with blocking operations. In that case you can use Starlette’s run_in_threadpool:

from starlette.concurrency import run_in_threadpool

@app.get('/')
async def():
   await do_something_async()
   await run_in_threadpool(do_something_blocking)

This is actually what FastAPI uses internally if you define your handler as def (and not async def).

7reactions
nzigcommented, Jun 2, 2021

Yes, it’s slightly slower. If you use ThreadPoolExecuter in a def function in FastAPI, what happens is:

  1. Thread 1 runs FastAPI. Since FastAPI is an async application and your def function might block, it calls it with run_in_threadpool, which runs it in a thread 2.
  2. Thread 2 runs your function. Since you created a ThreadPoolExecuter, this creates thread 3.
  3. Thread 3 runs whatever you did with the ThreadPoolExecuter.

This means for the handler to complete you need 4 thread switches (1->2->3->2->1).

If you use an async def there are 0 thread switches, and if you use async def with run_in_threadpool there are 2. Since each thread switch adds overhead, using ThreadPoolExecuter inside a def function will probably be slower.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is having a concurrent.futures.ThreadPoolExecutor call ...
I need to use the concurrent.futures.ThreadPoolExecutor part of the code in a FastAPI endpoint. My concern is the impact of the number of...
Read more >
tiangolo/fastapi - Gitter
By default, it uses a ThreadPoolExecutor. By default, it has "number of processors on the machine, multiplied by 5". So, it's actually a...
Read more >
Concurrency and async / await - FastAPI
You can only use await inside of functions created with async def . ... That's why it makes a lot of sense to...
Read more >
Concurrent.futures in FastAPI : r/learnpython - Reddit
I have a FastAPI application where one of the API needs to perform the tasks in parallel. With the help of threadexecutorpool we...
Read more >
How to use ThreadPoolExecutor in Python
First, create an instance of ThreadPoolExecutor . Next, we have to declare the number of worker threads. The default value of max_workers is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found