Python ASGI Framework Benchmarks

4 months ago 19

Extremely simple comparisons between fast ASGI frameworks. Each framework used uvicorn as the server using uvicorn file:app --workers 4. Tests were performed on a Dell XPS 13 with 16GB of RAM.

from MicroPie import App class Root(App): async def index(self): return {'hello': 'world'} app = Root()
$ wrk -d15s -t4 -c64 http://127.0.0.1:8000 Running 15s test @ http://127.0.0.1:8000 4 threads and 64 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.35ms 1.09ms 21.59ms 82.45% Req/Sec 13.24k 1.63k 17.55k 73.83% 791721 requests in 15.03s, 121.56MB read Requests/sec: 52685.82 Transfer/sec: 8.09MB
from blacksheep import Application, get, json app = Application() @get("/") def home(): return json({"hello": "world"})
$ wrk -d15s -t4 -c64 http://127.0.0.1:8000 Running 15s test @ http://127.0.0.1:8000 4 threads and 64 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.15ms 392.66us 15.11ms 85.91% Req/Sec 13.88k 1.39k 26.76k 87.04% 831432 requests in 15.10s, 120.52MB read Requests/sec: 55060.05 Transfer/sec: 7.98MB
from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"}
$ wrk -d15s -t4 -c64 http://127.0.0.1:8000 Running 15s test @ http://127.0.0.1:8000 4 threads and 64 connections Thread Stats Avg Stdev Max +/- Stdev Latency 3.52ms 1.82ms 56.73ms 91.17% Req/Sec 4.71k 404.21 5.29k 95.00% 281493 requests in 15.01s, 38.12MB read Requests/sec: 18756.73 Transfer/sec: 2.54MB
from sanic import Sanic from sanic.response import json app = Sanic("my-hello-world-app") @app.route('/') async def test(request): return json({'hello': 'world'})
$ wrk -d15s -t4 -c64 http://127.0.0.1:8000 Running 15s test @ http://127.0.0.1:8000 4 threads and 64 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.84ms 0.97ms 37.83ms 92.93% Req/Sec 8.95k 790.43 18.25k 96.68% 536203 requests in 15.10s, 82.33MB read Requests/sec: 35508.58 Transfer/sec: 5.45MB
import muffin app = muffin.Application() @app.route('/') async def example(request): return muffin.ResponseJSON({'hello': 'world'})
$ wrk -d15s -t4 -c64 http://127.0.0.1:8000 Running 15s test @ http://127.0.0.1:8000 4 threads and 64 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.08ms 516.86us 29.21ms 91.45% Req/Sec 14.88k 1.71k 42.57k 94.68% 889891 requests in 15.10s, 120.51MB read Requests/sec: 58931.31 Transfer/sec: 7.98MB
from litestar import Litestar, get @get("/") async def hello_world() -> dict[str, str]: """Keeping the tradition alive with hello world.""" return {"hello": "world"} app = Litestar(route_handlers=[hello_world])
$ wrk -d15s -t4 -c64 http://127.0.0.1:8000 Running 15s test @ http://127.0.0.1:8000 4 threads and 64 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.57ms 633.11us 33.66ms 88.42% Req/Sec 10.20k 1.41k 32.86k 91.51% 610059 requests in 15.10s, 82.62MB read Requests/sec: 40401.18 Transfer/sec: 5.47MB
from starlette.applications import Starlette from starlette.responses import JSONResponse from starlette.routing import Route async def homepage(request): return JSONResponse({'hello': 'world'}) app = Starlette(debug=True, routes=[ Route('/', homepage), ])
$ wrk -d15s -t4 -c64 http://127.0.0.1:8000 Running 15s test @ http://127.0.0.1:8000 4 threads and 64 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.22ms 387.05us 17.42ms 85.42% Req/Sec 13.05k 1.05k 15.33k 84.83% 779092 requests in 15.00s, 105.51MB read Requests/sec: 51930.45 Transfer/sec: 7.03MB

The table below summarizes the performance of various ASGI frameworks based on a 15-second wrk test with 4 threads and 64 connections, measuring a simple "hello world" JSON response.

Framework Total Requests Req/Sec Transfer/Sec (MB/s) Avg Latency (ms) Stdev Latency (ms) Max Latency (ms)
Muffin 889,891 58,931.31 7.98 1.08 0.52 29.21
Blacksheep 831,432 55,060.05 7.98 1.15 0.39 15.11
MicroPie 791,721 52,685.82 8.09 1.35 1.09 21.59
Starlette 779,092 51,930.45 7.03 1.22 0.39 17.42
Litestar 610,059 40,401.18 5.47 1.57 0.63 33.66
Sanic 536,203 35,508.58 5.45 1.84 0.97 37.83
FastAPI 281,493 18,756.73 2.54 3.52 1.82 56.73
Read Entire Article