The choice between Gevent and asyncio has always been a classic question. Here, we’ll use data to help you make a decision.
Introduction
Professor Lin Wei has set a high standard:
This graph shows the extreme performance of asyncio and Gevent. We can see that asyncio with uvloop is basically double the performance of Gevent.
But is this the case under web frameworks?
Let’s conduct an experiment.
First, let’s talk about the configuration of the load machine. I chose a D8as_v5 machine on Azure with the following configuration:
8 Core 32GB configuration
The underlying hardware is based on the EPYC 7763 series processor
A total of 4 nodes, allocated to Django/Flask/FastAPI/Starlette, four different frameworks
We chose locust as our load testing framework, also based on a Kubernetes cluster. Because the quota for D8as_v5 machines in my account wasn’t sufficient, we chose a mixed deployment of different machines for the load testing framework:
4 D8as_v5, totaling 32 Core computing power
4 D8as_v3, totaling 32 Core computing power
4 D4as_v2, totaling 16 Core computing power
Our main purpose for testing is to simulate throughput in a production environment, so I chose the following test method:
Prepare a 16 Core 64GB MySQL instance for data storage
Create a table and randomly write 1 million data entries
Perform SQL queries in the framework code and return the query results
# Create your views here. defdemo_views(request): result = DemoData.objects.filter( name="".join(random.choices(TEMP, k=random.randrange(1, 254))) ) # x = json.dumps(request.body) return HttpResponse( serializers.serialize("json", result if result else []), content_type="application/json", )
All services are deployed on K8S, with POD type as Guaranteed
All image is built base on the Python 3.12
Services are limited to 6 Core CPU
Django and Flask are deployed based on Gevent + Gunicorn, using Greenify to patch the binary
FastAPI and Starlette are deployed based on uvicorn, using uvloop as the event loop
OK, now let’s reveal the test results.
Test Results Under Standard Operations
Django:
FastAPI:
Flask:
Starlette:
Django is undoubtedly the last, while the performance of the other three is Flask + Gevent > Starlette > FastAPI. The CPU usage of the latter three frameworks is all > 90%.
Idle Test
To be on the safe side, we conducted an idle test on the latter three frameworks.
Flask:
FastAPI:
Starlette:
Starlette > FastAPI > Flask + Gevent
Conclusion
Currently, the overall conclusions are as follows:
In idle situations, the performance of asyncio is significantly better than Gevent. Even with the framework factor, there is still a 10-20% improvement.
In the case of ORM + MySQL Driver, Gevent’s ecosystem is better than asyncio’s ecosystem.
If we switch to ORM + PGSQL ecosystem, will the conclusion be even better? Looking forward to the results of the next round of tests.