Commit Graph

6 Commits

Author SHA1 Message Date
Vladimir Dubrovin
7140ffb43d bench: 90th percentile latency, per-connection link emulation
wrk's and mix's 90th percentile is recorded (p90_ms) and shown in the
report.py --latency tables when present.

--flow-rate limits each connection between the client and the proxy
(fq maxrate), under --netem when both are given, now with a large netem
queue. Both directions are shaped in the client's namespace, the
incoming one through an ifb, so the emulation runs on the client's CPUs;
segmentation offload and GRO are off on that link so that netem drops
single packets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 11:02:30 +03:00
Vladimir Dubrovin
b1a551c5b1 bench: latency tables
report.py --latency makes a table of the runs' 50th and 99th percentile
latency for one CSV, ranked by the 99th. RESULTS gets one for each
machine in the HTTP, CONNECT, SOCKS, relay and mix sections, with how to
read them: wrk runs a closed loop, so medians follow throughput and the
99th percentile against the median shows how evenly a proxy serves its
connections; the mix -3k runs are the open-loop ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 23:28:57 +03:00
Vladimir Dubrovin
ef0c98e4c1 bench: RESULTS with a table for each machine, HTTPS with streams and envoy
Every table is now for one machine, ARM or Intel, with no averages of
the two, the copying proxies and those using splice() in one table:
bold the best of each group and * the best of the row for the HTTP proxy
and the relay, only the best of the row for CONNECT and SOCKS. The
tables for 13 October replace those of 11-12 October, whose columns for
splice by direction and 16 KB buffers are gone with them.

The HTTPS section is measured again with today's devel, with the TLS
streams and envoy. report.py takes the TLS streams and 1 MB answers for
bulk data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 13:00:21 +03:00
Vladimir Dubrovin
97b8b9d7fb bench: TLS streams, envoy, a table for each machine
tls-term-stream* and tls-init-stream* run iperf3 streams through the TLS
relays. iperf3 has no TLS of its own, so bench/mix gets a TLS wrapper
mode, run on the client to begin TLS towards a proxy ending it and at the
origin to end the TLS a proxy begins.

--proxy envoy measures envoy where nginx and haproxy are measured: as an
HTTP proxy for the origin, as a TCP relay and in the TLS scenarios, its
circuit breakers lifted for the scenarios opening more than 1024
connections.

report.py --machine with a single machine gives its medians alone, with
the client- or origin-limited ones marked; --overall marks only the best
of each row. The mix client's -errlog prints every failed exchange.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:21:37 +03:00
Vladimir Dubrovin
a146570533 Benchmarks: splice by direction, grace delay, tunnels, more proxies
bench.py:
- 2000 clients posting 2 KB and getting 50 KB back, next to the GET one
- haproxy with splice-response and splice-request, like -s1 and -s2
- CONNECT and SOCKSv5 scenarios: wrk and iperf3 run under proxychains-ng,
  so every connection asks the proxy for a tunnel; and the same loads
  through a TCP relay to a fixed destination
- tinyproxy and squid (HTTP proxy, CONNECT), dante (SOCKS); each proxy
  takes part only in the scenarios it supports
- 3proxy also gets its socks service and a tcppm to the web server

report.py: one throughput table for several machines (--machine), each
cell their medians and their average; bold for the best of a group, * for
the best of the row; --split puts the splice proxies in a table of their
own, --prefix picks scenarios.

RESULTS.md: the comparison as one table for both machines, splice by
direction (devel -s0/-s1/-s3 against haproxy's settings) and grace delay
with splice, with their data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 00:40:19 +03:00
Vladimir Dubrovin
c13c048f3f Benchmarks: measure the proxy under stress, add results
bench.py:
- the proxy gets one CPU, the client four, the origin three (8 CPUs), so
  the proxy is what runs out first
- CPU time is the busy time of a role's CPUs from /proc/stat, softirqs
  included: with IRQ time accounting the cgroup's own figure leaves out
  much of the network work
- every run records which side set its pace (proxy, client, origin), by
  the busy share of the role's CPUs and of its busiest thread
- a 50 KB keep-alive scenario with 2000 clients
- haproxy with splice: haproxy::splice-auto and haproxy::splice
- wrk timeouts counted apart from errors; tools found by absolute path;
  leftovers of an interrupted run are cleaned up

report.py turns runs into Markdown tables: throughput, the proxy's CPU
per gigabyte or per request, its peak memory, splice and copying proxies
in groups of their own, the best of each group marked.

RESULTS.md has the comparison of 0.9.4, 1.0.1, devel, nginx and haproxy,
with and without splice, on an Apple M4 and an Intel Skylake virtual
machine, and how it was measured; data/ has the measurements.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 22:04:47 +03:00