abersheeran / a2wsgi

Convert WSGI app to ASGI app or ASGI app to WSGI app.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WSGIMiddleware overhead

gaganpreet opened this issue · comments

I'm exploring the feasibility of moving an existing Flask app to FastAPI while running the old Flask app using the WSGIMiddleware.

I've been running some performance tests and there's a very significant overhead that WSGIMiddleware brings to the mix. I wrote a small demo here.

This is how I run the server:

uvicorn main:app --port 8000 --no-access-log  --workers 1

There are two endpoints: /users_fastapi (direct, no middleware) and /users_flask (wsgi middleware). Both endpoints query some dummy data from the in-memory db and return it as a response.

$ wrk http://127.0.0.1:8000/users_fastapi

Running 10s test @ http://127.0.0.1:8000/users_fastapi
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   568.68ms   68.02ms 637.11ms   95.32%
    Req/Sec    12.06      7.11    20.00     36.21%
  171 requests in 10.01s, 16.15MB read
Requests/sec:     17.08
Transfer/sec:      1.61MB
$ wrk http://127.0.0.1:8000/users_flask

Running 10s test @ http://127.0.0.1:8000/users_flask
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.24s   157.89ms   1.56s    77.03%
    Req/Sec     7.58      5.52    20.00     64.06%
  74 requests in 10.01s, 6.99MB read
Requests/sec:      7.39
Transfer/sec:    714.88KB

The direct route has a throughput of 17.08 reqs/s, and the one behind wsgi middleware only goes up to 7.39, which is a significant difference.

I'm looking at the middleware and trying to figure out if there's room to reduce overhead, however, any inputs or ideas are much appreciated.

commented

Maybe you can get a better comparison by testing the performance of the original flask.

You are welcome to submit any PRs that improve performance. Here's a performance benchmark I just ran.

$ pytest ./benchmark.py -s
=================================================================================== test session starts ===================================================================================
platform win32 -- Python 3.9.6, pytest-7.0.1, pluggy-1.0.0
rootdir: C:\Users\aber\Documents\GitHub\a2wsgi
plugins: anyio-3.5.0, asyncio-0.11.0, cov-3.0.0
collected 6 items

benchmark.py
             Name              Average Time
          pure-ASGI            0.00030796286.
    a2wsgi-WSGIMiddleware      0.0008904933199999999.
    uvicorn-WSGIMiddleware     0.00062742427.
      asgiref-WsgiToAsgi       0.00141565296.
          pure-WSGI            0.00023801917.
    a2wsgi-ASGIMiddleware      0.0008830748.

Maybe you can get a better comparison by testing the performance of the original flask.

I tried this.

gunicorn main:flask_app --bind=:8000 -w 1
$ wrk http://localhost:8000/users_flask

Running 10s test @ http://localhost:8000/users_flask
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   414.07ms   43.31ms 480.73ms   94.07%
    Req/Sec    13.61      7.62    30.00     70.07%
  236 requests in 10.01s, 22.29MB read
Requests/sec:     23.58
Transfer/sec:      2.23MB

At 23.58 reqs/s, pure Flask is even faster than the ASGI implementation. This is not a fair comparison of ASGI vs WSGI, as the ASGI code is running synchronous code.

You are welcome to submit any PRs that improve performance.

I haven't found anything yet to improve performance, I'll spend some time this weekend and see what's possible.