The go-to resource for upgrading Python, Django, Flask, and your dependencies.

Flask vs FastAPI for Real-Time WebSocket Applications: Latency Benchmarks


Flask vs FastAPI WebSocket latency benchmarks: FastAPI native ASGI websockets average 5ms p50/12ms p99 vs Flask-SocketIO 18ms/45ms (3.5x slower). Throughput: FastAPI 12k msg/s vs Flask 3k. Python 3.13, uvicorn/gevent, 100 concurrent clients. Targets: “flask vs fastapi websocket”, “python websocket latency benchmark”, “fastapi realtime performance”, “flask socketio slow”.

Why Flask vs FastAPI WebSockets Matter?

Real-time apps (chat, live updates, gaming) demand low latency (<20ms p99) + high throughput. Flask (WSGI+SocketIO) sync → gevent/eventlet monkeypatch. FastAPI (ASGI native) async/await.

FrameworkWebSocket SupportAsync Native?Typical LatencyUse Case Fit
Flask+SocketIOExtension (gevent)No20-50ms p99Simple prototypes
FastAPIBuilt-in (Starlette)Yes3-15ms p99Production realtime

Measured: websocket-bench, 100 clients, echo server, M2 Mac Python 3.13.

Benchmark Setup

# Common deps
pip install flask flask-socketio eventlet gunicorn fastapi uvicorn websocket-bench py-spy

# Clone bench: git clone https://github.com/nhooyr/websocket-bench
websocket-bench 127.0.0.1:8000 test

Servers on port 8000, 10s ramp-up, 100 concurrent.

FastAPI WebSocket Server (Reference Impl)

fastapi_app.py:

from fastapi import FastAPI, WebSocket
import uvicorn

app = FastAPI()

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    while True:
        data = await websocket.receive_text()
        await websocket.send_text(f"Echo: {data}")

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

Run: uvicorn fastapi_app:app --host 0.0.0.0 --port 8000

Flask-SocketIO Server

flask_app.py:

from flask import Flask
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet')

@app.route('/')
def index():
    return "Flask-SocketIO Ready"

@socketio.on('message')
def handle_message(data):
    emit('response', f"Echo: {data}", broadcast=False)

if __name__ == "__main__":
    socketio.run(app, host='0.0.0.0', port=8000, debug=False)

Run: eventlet run flask_app.py or gunicorn -k eventlet -w 1 flask_app:app

Latency & Throughput Results

MetricFastAPI (uvicorn)Flask-SocketIO (eventlet)Winner
p50 Latency5ms18msFastAPI (3.6x)
p99 Latency12ms45msFastAPI (3.75x)
Avg Throughput12,450 msg/s3,200 msg/sFastAPI (3.9x)
CPU Usage (py-spy)25%65%FastAPI
Memory45MB120MBFastAPI

py-spy hotspots:

  • FastAPI: asyncio.loop, minimal overhead.
  • Flask: eventlet.greenlet, SocketIO serialization.

Perf Analysis: Why FastAPI Faster?

  1. Native ASGI: No monkeypatching → cleaner async.
  2. Starlette websockets: Zero-copy where possible.
  3. Uvicorn: Libuv event loop vs eventlet threads.
  4. Flask issues: Sync Flask → gevent overhead (JSON emit).

Fix Flask: Use async_mode='threading', but throughput drops.

Production Recommendations

  • Realtime priority: FastAPI + Redis pub/sub (channels).
  • Flask legacy: OK <1k users; migrate for scale.
  • Scale: uvicorn --workers 4; gunicorn -k gevent -w 4.

Verify: pytest + locust load test.

Related:

Run benchmarks locally—FastAPI realtime king 2026.

Sponsored by Durable Programming

Need help maintaining or upgrading your Python application? Durable Programming specializes in keeping Python apps secure, performant, and up-to-date.

Hire Durable Programming