From b208addf11df12bf2f69776c06e9b8d44aca4ccb Mon Sep 17 00:00:00 2001 From: TOKUJI <14055040+TOKUJI@users.noreply.github.com> Date: Mon, 27 Jul 2026 00:19:25 +0900 Subject: [PATCH 1/2] fastapi: emit a single Server header and stop gzip-inflating tiny bodies - Replace the BaseHTTPMiddleware-based ServerHeaderMiddleware with uvicorn's --no-server-header --header Server:FastAPI: responses previously carried both 'server: uvicorn' and 'server: FastAPI', now exactly one 'server: FastAPI' at zero per-request cost - Raise GZipMiddleware minimum_size from 1 to 1000 (the value in FastAPI's own docs example; compresslevel=5 unchanged) so tiny bodies are no longer inflated by compression Fixes #1052 Co-Authored-By: Claude Fable 5 --- frameworks/fastapi/Dockerfile | 2 +- frameworks/fastapi/app.py | 11 +---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/frameworks/fastapi/Dockerfile b/frameworks/fastapi/Dockerfile index f2936a878..b491ce246 100644 --- a/frameworks/fastapi/Dockerfile +++ b/frameworks/fastapi/Dockerfile @@ -4,4 +4,4 @@ COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8080 8081 -CMD [ "python3", "launcher.py", "uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080", "--loop", "uvloop", "--log-level", "critical" ] +CMD [ "python3", "launcher.py", "uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080", "--loop", "uvloop", "--log-level", "critical", "--no-server-header", "--header", "Server:FastAPI" ] diff --git a/frameworks/fastapi/app.py b/frameworks/fastapi/app.py index 20167abfa..3f2acf7bc 100644 --- a/frameworks/fastapi/app.py +++ b/frameworks/fastapi/app.py @@ -9,7 +9,6 @@ from fastapi import FastAPI, Request, Response, Path, Query, HTTPException from fastapi.responses import PlainTextResponse, JSONResponse from fastapi.middleware.gzip import GZipMiddleware -from fastapi.applications import BaseHTTPMiddleware from fastapi.staticfiles import StaticFiles @@ -74,15 +73,7 @@ async def lifespan(application: FastAPI): app = FastAPI(lifespan=lifespan) -app.add_middleware(GZipMiddleware, minimum_size=1, compresslevel=5) - -class ServerHeaderMiddleware(BaseHTTPMiddleware): - async def dispatch(self, request, call_next): - response = await call_next(request) - response.headers["Server"] = "FastAPI" - return response - -app.add_middleware(ServerHeaderMiddleware) +app.add_middleware(GZipMiddleware, minimum_size=1000, compresslevel=5) # -- Routes ------------------------------------------------------------------ From ed551d47bbb617c08c51f9bc0d80a36db9c87622 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Jul 2026 16:26:36 +0000 Subject: [PATCH 2/2] Benchmark results: fastapi --- site/data/results/fastapi.json | 320 +++++++++++++++++---------------- 1 file changed, 162 insertions(+), 158 deletions(-) diff --git a/site/data/results/fastapi.json b/site/data/results/fastapi.json index 3d14734d1..1b683cfe3 100644 --- a/site/data/results/fastapi.json +++ b/site/data/results/fastapi.json @@ -4,71 +4,71 @@ "api-16-1024": { "framework": "fastapi", "language": "Python", - "rps": 18677, - "avg_latency": "54.63ms", - "p99_latency": "190.40ms", - "cpu": "1585.1%", - "memory": "1.5GiB", + "rps": 30215, + "avg_latency": "32.92ms", + "p99_latency": "153.60ms", + "cpu": "1616.1%", + "memory": "1.7GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "95.74MB/s", - "input_bw": "1.05MB/s", - "reconnects": 55832, - "status_2xx": 280158, + "bandwidth": "154.17MB/s", + "input_bw": "1.70MB/s", + "reconnects": 90601, + "status_2xx": 453239, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_baseline": 104850, - "tpl_json": 104941, + "tpl_baseline": 169729, + "tpl_json": 170496, "tpl_db": 0, "tpl_upload": 0, "tpl_static": 0, - "tpl_async_db": 70367 + "tpl_async_db": 113014 }, "api-4-256": { "framework": "fastapi", "language": "Python", - "rps": 7634, - "avg_latency": "33.51ms", - "p99_latency": "116.40ms", - "cpu": "399.8%", - "memory": "495MiB", + "rps": 8449, + "avg_latency": "30.24ms", + "p99_latency": "143.10ms", + "cpu": "401.4%", + "memory": "494MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "39.13MB/s", - "input_bw": "439.85KB/s", - "reconnects": 22896, - "status_2xx": 114523, + "bandwidth": "43.16MB/s", + "input_bw": "486.81KB/s", + "reconnects": 25351, + "status_2xx": 126749, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_baseline": 42884, - "tpl_json": 42988, + "tpl_baseline": 47335, + "tpl_json": 47652, "tpl_db": 0, "tpl_upload": 0, "tpl_static": 0, - "tpl_async_db": 28651 + "tpl_async_db": 31762 }, "async-db-1024": { "framework": "fastapi", "language": "Python", - "rps": 54572, - "avg_latency": "18.66ms", - "p99_latency": "152.90ms", - "cpu": "6230.0%", - "memory": "5.0GiB", + "rps": 76351, + "avg_latency": "12.08ms", + "p99_latency": "267.60ms", + "cpu": "6248.4%", + "memory": "4.8GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "205.07MB/s", - "input_bw": "3.64MB/s", - "reconnects": 21345, - "status_2xx": 545720, + "bandwidth": "287.35MB/s", + "input_bw": "5.10MB/s", + "reconnects": 30281, + "status_2xx": 763515, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -76,18 +76,19 @@ "baseline-4096": { "framework": "fastapi", "language": "Python", - "rps": 123499, - "avg_latency": "32.77ms", - "p99_latency": "114.00ms", - "cpu": "6491.1%", - "memory": "5.3GiB", + "rps": 314605, + "avg_latency": "12.99ms", + "p99_latency": "18.30ms", + "cpu": "6506.2%", + "memory": "4.6GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "20.51MB/s", + "bandwidth": "40.49MB/s", + "input_bw": "24.30MB/s", "reconnects": 0, - "status_2xx": 617499, + "status_2xx": 1573028, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -95,18 +96,19 @@ "baseline-512": { "framework": "fastapi", "language": "Python", - "rps": 139815, - "avg_latency": "3.65ms", - "p99_latency": "5.53ms", - "cpu": "6509.6%", - "memory": "4.7GiB", + "rps": 320447, + "avg_latency": "1.60ms", + "p99_latency": "3.24ms", + "cpu": "6505.3%", + "memory": "4.5GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "23.19MB/s", + "bandwidth": "41.25MB/s", + "input_bw": "24.75MB/s", "reconnects": 0, - "status_2xx": 699079, + "status_2xx": 1602237, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -114,19 +116,19 @@ "json-4096": { "framework": "fastapi", "language": "Python", - "rps": 85612, - "avg_latency": "47.31ms", - "p99_latency": "121.10ms", - "cpu": "6279.2%", - "memory": "5.3GiB", + "rps": 157204, + "avg_latency": "23.62ms", + "p99_latency": "344.30ms", + "cpu": "6468.8%", + "memory": "4.8GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "304.89MB/s", - "input_bw": "4.08MB/s", - "reconnects": 15435, - "status_2xx": 428064, + "bandwidth": "556.14MB/s", + "input_bw": "7.50MB/s", + "reconnects": 30739, + "status_2xx": 786024, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -134,19 +136,19 @@ "json-comp-16384": { "framework": "fastapi", "language": "Python", - "rps": 55749, - "avg_latency": "275.58ms", - "p99_latency": "407.60ms", - "cpu": "6459.2%", - "memory": "6.7GiB", + "rps": 92206, + "avg_latency": "117.01ms", + "p99_latency": "803.70ms", + "cpu": "6450.5%", + "memory": "4.9GiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "76.98MB/s", - "input_bw": "4.15MB/s", - "reconnects": 0, - "status_2xx": 278747, + "bandwidth": "125.76MB/s", + "input_bw": "6.86MB/s", + "reconnects": 17668, + "status_2xx": 461034, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -154,19 +156,19 @@ "json-comp-4096": { "framework": "fastapi", "language": "Python", - "rps": 62402, - "avg_latency": "64.77ms", - "p99_latency": "224.60ms", - "cpu": "6231.1%", - "memory": "5.4GiB", + "rps": 93953, + "avg_latency": "39.75ms", + "p99_latency": "575.70ms", + "cpu": "6445.4%", + "memory": "4.7GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "86.14MB/s", - "input_bw": "4.64MB/s", - "reconnects": 10330, - "status_2xx": 312012, + "bandwidth": "128.13MB/s", + "input_bw": "6.99MB/s", + "reconnects": 18111, + "status_2xx": 469768, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -174,19 +176,19 @@ "json-comp-512": { "framework": "fastapi", "language": "Python", - "rps": 64548, - "avg_latency": "7.94ms", - "p99_latency": "16.90ms", - "cpu": "6264.9%", - "memory": "4.8GiB", + "rps": 93695, + "avg_latency": "5.46ms", + "p99_latency": "12.20ms", + "cpu": "6450.8%", + "memory": "4.7GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "89.08MB/s", - "input_bw": "4.80MB/s", - "reconnects": 12693, - "status_2xx": 322740, + "bandwidth": "127.79MB/s", + "input_bw": "6.97MB/s", + "reconnects": 18690, + "status_2xx": 468476, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -194,18 +196,18 @@ "json-tls-4096": { "framework": "fastapi", "language": "Python", - "rps": 76025, - "avg_latency": "52.03ms", - "p99_latency": "52.03ms", - "cpu": "6233.6%", - "memory": "5.7GiB", + "rps": 135982, + "avg_latency": "29.02ms", + "p99_latency": "141.69ms", + "cpu": "6176.2%", + "memory": "4.8GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "270.25MB", + "bandwidth": "480.30MB", "reconnects": 0, - "status_2xx": 387333, + "status_2xx": 692249, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -213,18 +215,19 @@ "limited-conn-4096": { "framework": "fastapi", "language": "Python", - "rps": 116324, - "avg_latency": "34.60ms", - "p99_latency": "108.10ms", - "cpu": "6482.0%", - "memory": "5.5GiB", + "rps": 286820, + "avg_latency": "10.07ms", + "p99_latency": "75.80ms", + "cpu": "6496.5%", + "memory": "5.8GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "19.32MB/s", - "reconnects": 56706, - "status_2xx": 581623, + "bandwidth": "36.91MB/s", + "input_bw": "22.16MB/s", + "reconnects": 143214, + "status_2xx": 1434102, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -232,18 +235,19 @@ "limited-conn-512": { "framework": "fastapi", "language": "Python", - "rps": 129440, - "avg_latency": "3.95ms", - "p99_latency": "7.64ms", - "cpu": "6498.1%", - "memory": "5.1GiB", + "rps": 284181, + "avg_latency": "1.79ms", + "p99_latency": "3.92ms", + "cpu": "6508.9%", + "memory": "5.7GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "21.47MB/s", - "reconnects": 64724, - "status_2xx": 647202, + "bandwidth": "36.58MB/s", + "input_bw": "21.95MB/s", + "reconnects": 142084, + "status_2xx": 1420905, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -251,18 +255,18 @@ "pipelined-4096": { "framework": "fastapi", "language": "Python", - "rps": 122597, - "avg_latency": "499.86ms", - "p99_latency": "689.40ms", - "cpu": "6491.5%", - "memory": "5.5GiB", + "rps": 359847, + "avg_latency": "178.29ms", + "p99_latency": "205.40ms", + "cpu": "6524.2%", + "memory": "4.7GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "20.46MB/s", + "bandwidth": "46.31MB/s", "reconnects": 0, - "status_2xx": 612986, + "status_2xx": 1799237, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -270,18 +274,18 @@ "pipelined-512": { "framework": "fastapi", "language": "Python", - "rps": 145799, - "avg_latency": "55.99ms", - "p99_latency": "80.70ms", - "cpu": "6326.4%", - "memory": "4.8GiB", + "rps": 364432, + "avg_latency": "22.48ms", + "p99_latency": "25.70ms", + "cpu": "6524.6%", + "memory": "4.5GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "24.32MB/s", + "bandwidth": "46.91MB/s", "reconnects": 0, - "status_2xx": 728997, + "status_2xx": 1822160, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -289,18 +293,18 @@ "static-1024": { "framework": "fastapi", "language": "Python", - "rps": 19534, - "avg_latency": "51.91ms", - "p99_latency": "51.91ms", - "cpu": "6778.6%", - "memory": "5.7GiB", + "rps": 22055, + "avg_latency": "45.97ms", + "p99_latency": "160.67ms", + "cpu": "6702.8%", + "memory": "5.3GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "352.18MB", + "bandwidth": "397.42MB", "reconnects": 0, - "status_2xx": 99634, + "status_2xx": 112102, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -308,18 +312,18 @@ "static-4096": { "framework": "fastapi", "language": "Python", - "rps": 17887, - "avg_latency": "219.05ms", - "p99_latency": "219.05ms", - "cpu": "6849.5%", - "memory": "7.1GiB", + "rps": 20911, + "avg_latency": "187.91ms", + "p99_latency": "472.21ms", + "cpu": "6765.1%", + "memory": "6.8GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "320.89MB", + "bandwidth": "375.36MB", "reconnects": 0, - "status_2xx": 91350, + "status_2xx": 106844, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -327,18 +331,18 @@ "static-6800": { "framework": "fastapi", "language": "Python", - "rps": 17366, - "avg_latency": "363.90ms", - "p99_latency": "363.90ms", - "cpu": "6867.5%", - "memory": "8.2GiB", + "rps": 20315, + "avg_latency": "311.88ms", + "p99_latency": "771.69ms", + "cpu": "6712.9%", + "memory": "7.9GiB", "connections": 6800, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "310.10MB", + "bandwidth": "363.17MB", "reconnects": 0, - "status_2xx": 89459, + "status_2xx": 104961, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -346,19 +350,19 @@ "upload-256": { "framework": "fastapi", "language": "Python", - "rps": 1439, - "avg_latency": "167.21ms", - "p99_latency": "1.38s", - "cpu": "5305.0%", - "memory": "5.0GiB", + "rps": 1536, + "avg_latency": "161.36ms", + "p99_latency": "811.10ms", + "cpu": "6271.6%", + "memory": "4.8GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "253.41KB/s", - "input_bw": "11.41GB/s", - "reconnects": 1337, - "status_2xx": 7197, + "bandwidth": "210.38KB/s", + "input_bw": "12.18GB/s", + "reconnects": 1490, + "status_2xx": 7682, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -366,19 +370,19 @@ "upload-32": { "framework": "fastapi", "language": "Python", - "rps": 1541, - "avg_latency": "20.73ms", - "p99_latency": "124.50ms", - "cpu": "1520.9%", + "rps": 2125, + "avg_latency": "14.99ms", + "p99_latency": "65.90ms", + "cpu": "2532.7%", "memory": "4.6GiB", "connections": 32, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "271.18KB/s", - "input_bw": "12.22GB/s", - "reconnects": 1539, - "status_2xx": 7706, + "bandwidth": "290.99KB/s", + "input_bw": "16.86GB/s", + "reconnects": 2129, + "status_2xx": 10628, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0