Skip to content

Add fortunes to django - #1423

Merged
MDA2AV merged 2 commits into
MDA2AV:mainfrom
ruroru:main
Sep 3, 2026
Merged

Add fortunes to django#1423
MDA2AV merged 2 commits into
MDA2AV:mainfrom
ruroru:main

Conversation

@ruroru

@ruroru ruroru commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Description


PR Commands — comment on this PR to trigger (requires collaborator approval):

Command Description
/benchmark -f <framework> Run every test the framework subscribes to
/benchmark -f <framework> -t <test> Run one test only
/benchmark -f <framework> --save Run and save results (updates the leaderboard on merge)
/benchmark -f <framework> -t <test> --save Run one test and save results
/benchmark -f <framework> --compare <other> Measure the deltas against another framework instead of this one
/benchmark-multiple -f <fw1>,<fw2>,... Benchmark several frameworks in one run — takes -t and --save too; saved results land in a single commit
/benchmark-multiple --save No -f needed: benchmark and save every framework the PR touches
/benchmark-test -t <test> Benchmark all enabled frameworks subscribed to <test> and save the results

For /benchmark, always specify -f <framework>; the flags combine in any order. Results come back as a comment with a per-profile table of RPS, p99, CPU and memory — one table per framework on multi runs. A new benchmark comment while a run is in flight queues behind it (one deep) instead of cancelling it. For multi-framework PRs (dependency bumps, same-language refactors) prefer /benchmark-multiple, which runs everything in a single job and commits all saved results together, so no run overwrites another. --compare works on single-framework runs only.

What the deltas are measured against. By default, this framework's own results published on main - answering "did this change help?". When you are tuning a variant or a successor entry, --compare re-bases them on another entry instead:

/benchmark -f genhttp --compare genhttp-kestrel

The reply states which baseline it used, and profiles the other framework does not run show n/a rather than a delta.


Run benchmarks locally

You can validate and benchmark your framework locally with the lite script — no CPU pinning, fixed connection counts, all load generators run in Docker.

./scripts/validate.sh <framework>
./scripts/benchmark-lite.sh <framework> baseline
./scripts/benchmark-lite.sh --load-threads 4 <framework>

Requirements: Docker Engine on Linux. Load generators (gcannon, h2load, h2load-h3, wrk) are built as self-contained Docker images on first run.

@ruroru

ruroru commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

benchmark -f django -t fortunes --save

@Kaliumhexacyanoferrat

Copy link
Copy Markdown
Collaborator

/benchmark -f django -t fortunes --save

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

👋 Benchmark request received. A collaborator will review and approve the run.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results

Framework: django | Test: fortunes

Test Conn RPS CPU Mem Δ RPS Δ Mem
fortunes 1024 5,500 5117.8% 5.4GiB NEW NEW
Full log
#5 [1/5] FROM docker.io/library/python:3.13-slim@sha256:9d2e5553305c7c7b0097999bb17187c69b921ccd6bc9d40e4bb5ebe652c00285
#5 resolve docker.io/library/python:3.13-slim@sha256:9d2e5553305c7c7b0097999bb17187c69b921ccd6bc9d40e4bb5ebe652c00285 0.1s done
#5 DONE 0.4s

#5 [1/5] FROM docker.io/library/python:3.13-slim@sha256:9d2e5553305c7c7b0097999bb17187c69b921ccd6bc9d40e4bb5ebe652c00285
#5 sha256:9b83eae799b831086df12d4da65c2edb0e6c713caa4312455bc8ee4b1a256c39 249B / 249B 0.1s done
#5 sha256:237e12970bdcabcdd95dab0f8dc59cda22b450156ee0bd01c58e0cf3b9c43885 3.15MB / 11.91MB 0.3s
#5 sha256:5bbcb35ea63ee8dd9b96c06b0f78b33c9a32e06e5b14e1bfeb46b498a93edb5d 0B / 4.27MB 0.2s
#5 sha256:237e12970bdcabcdd95dab0f8dc59cda22b450156ee0bd01c58e0cf3b9c43885 11.91MB / 11.91MB 0.4s done
#5 sha256:5bbcb35ea63ee8dd9b96c06b0f78b33c9a32e06e5b14e1bfeb46b498a93edb5d 4.27MB / 4.27MB 0.5s done
#5 extracting sha256:5bbcb35ea63ee8dd9b96c06b0f78b33c9a32e06e5b14e1bfeb46b498a93edb5d
#5 extracting sha256:5bbcb35ea63ee8dd9b96c06b0f78b33c9a32e06e5b14e1bfeb46b498a93edb5d 0.3s done
#5 DONE 1.3s

#5 [1/5] FROM docker.io/library/python:3.13-slim@sha256:9d2e5553305c7c7b0097999bb17187c69b921ccd6bc9d40e4bb5ebe652c00285
#5 extracting sha256:237e12970bdcabcdd95dab0f8dc59cda22b450156ee0bd01c58e0cf3b9c43885
#5 extracting sha256:237e12970bdcabcdd95dab0f8dc59cda22b450156ee0bd01c58e0cf3b9c43885 0.6s done
#5 DONE 1.9s

#5 [1/5] FROM docker.io/library/python:3.13-slim@sha256:9d2e5553305c7c7b0097999bb17187c69b921ccd6bc9d40e4bb5ebe652c00285
#5 extracting sha256:9b83eae799b831086df12d4da65c2edb0e6c713caa4312455bc8ee4b1a256c39 0.1s done
#5 DONE 2.0s

#6 [2/5] WORKDIR /app
#6 DONE 0.3s

#7 [3/5] COPY requirements.txt .
#7 DONE 0.2s

#8 [4/5] RUN pip install --no-cache-dir -r requirements.txt
#8 2.886 Collecting Django==6.1 (from -r requirements.txt (line 1))
#8 2.995   Downloading django-6.1-py3-none-any.whl.metadata (3.9 kB)
#8 3.018 Collecting uvicorn==0.52.3 (from uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.028   Downloading uvicorn-0.52.3-py3-none-any.whl.metadata (6.6 kB)
#8 3.065 Collecting asyncpg==0.30.0 (from -r requirements.txt (line 3))
#8 3.077   Downloading asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.0 kB)
#8 3.100 Collecting redis==5.2.1 (from -r requirements.txt (line 4))
#8 3.111   Downloading redis-5.2.1-py3-none-any.whl.metadata (9.1 kB)
#8 3.131 Collecting asgiref>=3.9.1 (from Django==6.1->-r requirements.txt (line 1))
#8 3.141   Downloading asgiref-3.12.1-py3-none-any.whl.metadata (9.4 kB)
#8 3.156 Collecting sqlparse>=0.5.0 (from Django==6.1->-r requirements.txt (line 1))
#8 3.166   Downloading sqlparse-0.6.0-py3-none-any.whl.metadata (6.0 kB)
#8 3.184 Collecting click>=7.0 (from uvicorn==0.52.3->uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.194   Downloading click-8.5.0-py3-none-any.whl.metadata (2.6 kB)
#8 3.206 Collecting h11>=0.8 (from uvicorn==0.52.3->uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.217   Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)
#8 3.246 Collecting httptools>=0.8.0 (from uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.256   Downloading httptools-0.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (3.5 kB)
#8 3.272 Collecting python-dotenv>=0.13 (from uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.282   Downloading python_dotenv-1.2.3-py3-none-any.whl.metadata (29 kB)
#8 3.318 Collecting pyyaml>=5.1 (from uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.328   Downloading pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB)
#8 3.361 Collecting uvloop>=0.15.1 (from uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.370   Downloading uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (4.9 kB)
#8 3.439 Collecting watchfiles>=0.20 (from uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.450   Downloading watchfiles-1.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.9 kB)
#8 3.543 Collecting websockets>=13.0 (from uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.553   Downloading websockets-17.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (6.3 kB)
#8 3.573 Collecting anyio>=3.0.0 (from watchfiles>=0.20->uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.583   Downloading anyio-4.14.2-py3-none-any.whl.metadata (4.6 kB)
#8 3.597 Collecting idna>=2.8 (from anyio>=3.0.0->watchfiles>=0.20->uvicorn[standard]==0.52.3->-r requirements.txt (line 2))
#8 3.607   Downloading idna-3.19-py3-none-any.whl.metadata (9.2 kB)
#8 3.619 Downloading django-6.1-py3-none-any.whl (8.4 MB)
#8 4.059    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.4/8.4 MB 19.7 MB/s  0:00:00
#8 4.070 Downloading uvicorn-0.52.3-py3-none-any.whl (79 kB)
#8 4.080 Downloading asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.6 MB)
#8 4.115    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.6/3.6 MB 105.7 MB/s  0:00:00
#8 4.125 Downloading redis-5.2.1-py3-none-any.whl (261 kB)
#8 4.137 Downloading asgiref-3.12.1-py3-none-any.whl (25 kB)
#8 4.147 Downloading click-8.5.0-py3-none-any.whl (125 kB)
#8 4.157 Downloading h11-0.16.0-py3-none-any.whl (37 kB)
#8 4.168 Downloading httptools-0.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (486 kB)
#8 4.182 Downloading python_dotenv-1.2.3-py3-none-any.whl (22 kB)
#8 4.193 Downloading pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (801 kB)
#8 4.200    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 801.6/801.6 kB 116.5 MB/s  0:00:00
#8 4.210 Downloading sqlparse-0.6.0-py3-none-any.whl (50 kB)
#8 4.221 Downloading uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (4.4 MB)
#8 4.262    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.4/4.4 MB 105.1 MB/s  0:00:00
#8 4.273 Downloading watchfiles-1.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (454 kB)
#8 4.286 Downloading anyio-4.14.2-py3-none-any.whl (125 kB)
#8 4.297 Downloading idna-3.19-py3-none-any.whl (68 kB)
#8 4.307 Downloading websockets-17.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (224 kB)
#8 4.491 Installing collected packages: websockets, uvloop, sqlparse, redis, pyyaml, python-dotenv, idna, httptools, h11, click, asyncpg, asgiref, uvicorn, Django, anyio, watchfiles
#8 6.881 
#8 6.883 Successfully installed Django-6.1 anyio-4.14.2 asgiref-3.12.1 asyncpg-0.30.0 click-8.5.0 h11-0.16.0 httptools-0.8.0 idna-3.19 python-dotenv-1.2.3 pyyaml-6.0.3 redis-5.2.1 sqlparse-0.6.0 uvicorn-0.52.3 uvloop-0.22.1 watchfiles-1.2.0 websockets-17.1
#8 6.883 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.
#8 DONE 7.1s

#9 [5/5] COPY . .
#9 DONE 0.2s

#10 exporting to image
#10 exporting layers
#10 exporting layers 2.9s done
#10 exporting manifest sha256:a1f98b67bfd02a752f085b569ce6f697d11a09e8d64d473ffb827d9fff117e3a 0.0s done
#10 exporting config sha256:c985cc9e3e2494ba269e663f16fdafdaf84f394284d40d89fbb549037c0f72ae 0.0s done
#10 exporting attestation manifest sha256:20e3049f52bfb27f2980b4275d0ac91a065f52f48c7830ec988498cefddbcae5 0.1s done
#10 exporting manifest list sha256:29d8491f5c4743d0d0c1731941a9a23e54c3085de2e9ef794a0b854e7c27c676
#10 exporting manifest list sha256:29d8491f5c4743d0d0c1731941a9a23e54c3085de2e9ef794a0b854e7c27c676 0.0s done
#10 naming to docker.io/library/httparena-django:latest done
#10 unpacking to docker.io/library/httparena-django:latest
#10 unpacking to docker.io/library/httparena-django:latest 1.8s done
#10 DONE 4.9s
[info] zrk: docker mode (zrk:local)
[info] tuning host for benchmark runs
[info] CPU governor → performance
[info] setting kernel socket limits
[info] setting UDP buffer sizes for QUIC
[info] setting loopback MTU to 1500 (realistic Ethernet)
[info] restarting docker daemon
[info] dropping kernel caches
[info] starting postgres sidecar
[info] postgres ready (seeded)

==============================================
=== django / fortunes / 1024c (tool=gcannon) ===
==============================================
[info] waiting for server...
[info] server ready

[run 1/3]
gcannon v0.5.3
  Target:    localhost:8080/fortunes
  Threads:   64
  Conns:     1024 (16/thread)
  Pipeline:  1
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   139.50ms   102.20ms   291.40ms   394.80ms   490.80ms

  36186 requests in 5.00s, 36186 responses
  Throughput: 7.23K req/s
  Bandwidth:  131.12MB/s
  Status codes: 2xx=27276, 3xx=0, 4xx=0, 5xx=8910
  Latency samples: 36186 / 36186 responses (100.0%)

  WARNING: 8910/36186 responses (24.6%) had unexpected status (expected 2xx)
[info] CPU 5211.8% | Mem 5.2GiB

[run 2/3]
gcannon v0.5.3
  Target:    localhost:8080/fortunes
  Threads:   64
  Conns:     1024 (16/thread)
  Pipeline:  1
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   139.17ms   90.10ms   303.40ms   412.20ms   535.60ms

  36157 requests in 5.00s, 36157 responses
  Throughput: 7.23K req/s
  Bandwidth:  132.21MB/s
  Status codes: 2xx=27503, 3xx=0, 4xx=0, 5xx=8654
  Latency samples: 36157 / 36157 responses (100.0%)

  WARNING: 8654/36157 responses (23.9%) had unexpected status (expected 2xx)
[info] CPU 5117.8% | Mem 5.4GiB

[run 3/3]
gcannon v0.5.3
  Target:    localhost:8080/fortunes
  Threads:   64
  Conns:     1024 (16/thread)
  Pipeline:  1
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   127.00ms   65.70ms   302.30ms   408.30ms    2.27s

  36156 requests in 5.00s, 36156 responses
  Throughput: 7.23K req/s
  Bandwidth:  131.52MB/s
  Status codes: 2xx=27353, 3xx=0, 4xx=0, 5xx=8803
  Latency samples: 36156 / 36156 responses (100.0%)

  WARNING: 8803/36156 responses (24.3%) had unexpected status (expected 2xx)
[info] CPU 5117.9% | Mem 5.4GiB

=== Best: 5500 req/s (CPU: 5117.8%, Mem: 5.4GiB) ===
[info] saved results/fortunes/1024/django.json
httparena-bench-django
httparena-bench-django
[info] rebuilding site/data/*.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/frameworks.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/results/django.json - 1 new, 11 total
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/current.json
[info] done
httparena-postgres
[info] restoring loopback MTU to 65536

@MDA2AV
MDA2AV merged commit 521bcc5 into MDA2AV:main Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants