In the last few years, there are several new async web frameworks. One of them is Starlette, I decided to evaluate it. The first step is to compare it basic performance with Tornado.
Starlette, using uvicorn, claims to be one of the fastest python web framework. I copied the codes directly from its website:
I run it with "uvicorn example:app", then measure rps using 'ab':from starlette.responses import PlainTextResponse async def app(scope, receive, send): assert scope['type'] == 'http' response = PlainTextResponse('Hello, world!') await response(scope, receive, send)
ab -n 1000 -c 10 127.0.0.1:8000/The result is on average 4200 requests per second.
I then run basic Tornado app, again with code copied directly from tornado website:
Using the same measurement, the ab result is a average 1900 requests/second.
So it looks like Starlette/uvicorn is more than 2 times faster than Tornado. However, the code on Tornado website is actually not the best for production use. Just replace "app.listen(8888)" the second to last line with following:
(and put "from tornado.httpserver import HTTPServer" at the beginning of the file), its performance increases to 4700 requests/second, actually faster than Starlette.
The code change to Tornado make the app start 4 processes instead of 1. Of course we can also do the similar for the Starlette app:
uvicorn --workers 4 example:appThe result now is 7500 requests/second, surpassing multi-process Tornado again.
These are superficial results that don't mean much. But it did make me appreciate the works that got into Tornado that keep it performant in these years.
- Tornado (default): 1900 rps
- Startlette/uvicorn (default): 4200 rps
- Tornado (4 workers): 4700 rps
- Starlette/uvicorn (4 workers): 7500 rps