FastAPI is generally faster in executing independent async functions in parallel than Flask, but uses slightly more CPU resources.
Abstract
The article compares FastAPI and Flask, two web frameworks for building APIs with Python, in terms of their performance in executing independent async functions in parallel. The author creates an API that uses a function to multiply two numpy arrays in the background, first with Flask and then with FastAPI. The code for both APIs is provided. The author then runs both APIs in separate terminals and measures the time for response. The results show that FastAPI is faster than Flask in executing the async function in parallel, but uses more CPU resources. The article concludes that FastAPI is a better choice for running independent async functions in parallel, but the trade-off is that it uses slightly more CPU resources.
Bullet points
FastAPI and Flask are two web frameworks for building APIs with Python
The article compares their performance in executing independent async functions in parallel
The author creates an API that uses a function to multiply two numpy arrays in the background, first with Flask and then with FastAPI
The code for both APIs is provided
The author runs both APIs in separate terminals and measures the time for response
The results show that FastAPI is faster than Flask in executing the async function in parallel, but uses more CPU resources
FastAPI is a better choice for running independent async functions in parallel, but the trade-off is that it uses slightly more CPU resources.
Let’s end the FastAPI vs Flask debate
For calling independent async functions in parallel
Both FastAPI and Flask are web frameworks (well Flask is a “microframework”) to build APIs with Python. Based on your needs you might have used any of these from time to time. But for different applications, it can become quite a headache to decide which one to go for. In this blog, I will break down which one is better for creating APIs for running multiple asynchronous functions in parallel.
We will code the same application in FastAPI and Flask and observe which one is better, faster and what are the trade-offs. Download this repository to get the code that we will be using below.
As we want to test, how good the frameworks are at executing independent async functions in parallel let’s create a function that can take up more than half a second to complete based on your system configurations.
We will create two numpy arrays of shape (10000, 10000) and multiply them and return the multiplied result. This process can take more than half a second (at least for me).
Let’s first create an API that uses this function in the background using Flask
Create flask_api/util.py and use the following code
Image by Author
We have already been through the __multiply__ function. Let’s go through the array_multiply function. As we will be executing the __multiply__ function multiple times we have wrapped that function around the array_multiply function and passing a num as an argument to it. The num argument will just print from what number of async call is it. Moreover, the multiplication result is flattened and converted to a list, and returned.
To get the output from all the async calls we make we use the multiple_array_multiply function which takes n as an argument and executes the array_multiply function n times and returns all the outputs from all the async functions called
While using Flask, to call an async function we create an asyncio event loop and run the async function inside that loop. To achieve this we have created the multiply_util function which is taking an argument n.
Create flask_api/app.py file and use the code below
Now let’s use the multiply_util and create an API endpoint /api/multiply using the code snippet above. We provide n=5 in the multiply_util function meaning we want to run 5 instances of the array_multiply function in async.
Now that we are done with the Flask side of things, let’s move on to create the same API using the FastAPI
Create fast_api/util.py and use the following snippet
Image by Author
No event loop, much less code know, I now right 😆. We used the same piece of code in flask_api/util.py file as well and it’s already explained. So let’s move to the fast_api/app.py file.
Create fast_api/app.py file and use the following code
Yeah, here we don’t need to call an event loop because there is already an event loop that gets created when we start the server. We can use the same event loop and just need to use await asyncio.gather to run multiple instances of the same function in async and get the result.
Save all your unsaved files and let’s run this in two different terminals and look at the time for response.
Note: We aren’t returning the list of flattened floats because there will be a lot of integers and the servers might hang up passing that much data. To check if you are getting the correct output you can save the result in a .json file.
Open an jupyter notebook or an ipython shell and run the following lines of code one after another.
Flask API
import requests
%time r = requests.get("http://localhost:5500/api/multiply")
FastAPI
%time r = requests.get("http://localhost:8000/api-fast/multiply")
Observer the Wall Time to check the total time taken to get the response. For me the API call to the API created using Flask took 1min 11s and the one created using FastAPI took only 31.9s.
Image by Author
Here, we can also observe that FastAPI uses more CPU Times which can be because of multiple reasons. The randomly generated arrays might have larger values or in general, FastAPI can be CPU hungry. This is not that huge of a trade-off practically.
Conclusion
In summary, we saw that practically FastAPI is faster in executing independent async functions in parallel but uses slightly more CPU resources. Also, when it comes to writing async code we can avoid a lot of template code using FastAPI. Based on your needs you can choose whatever framework/microframework.