# RustProxy 0.34.0 verification report ## Acceptance status **Source candidate, not verified production release.** Rust (`cargo`, `rustc`) is not installed in this execution environment, and the runtime has no access to its dependency registry. Consequently the modified Rust source was **not compiled**, the new Rust tests were **not executed**, and no 0.34.0 RustProxy binary or live throughput figures are supplied. Source inspection and simulated UI/cache tests do not close the runtime acceptance gate. ## Later 0.34.0 reverse-proxy optimization revision The refreshed source archive additionally reuses immutable route handles, limits lazy host wildcard allocation, fast-paths one-backend non-cookie LB, atomically caches healthy state and exchange scalar log fields, shares compiled per-member health policies across leases, and avoids unneeded fallback/retry header clones and empty-subscriber broadcast clones. The existing cache/sendfile work and all panel controls remain. Added Rust regression cases and the source-only hot-path guard are **not a substitute** for compilation and live HTTP, health, capacity, sticky, and H2 retry tests. No RPS improvement, corrected nginx gap, or full functional parity has been measured for this new revision. Details: `docs/PROXY_HOTPATH_0.34.0.md`. ## Changes and correctness boundaries - Operational per-vhost saves (upstream keepalive/recycling, connection limits, load-balancing/health policy, timeouts, request gate and diagnostics) retain HOT and COLD entries. Backend origin, routing, content, cache and transform changes retain conservative invalidation. Vhost-specific changes purge only that vhost; global cache, transform, forwarding, headers and Web Service or PHP-FPM profile changes may conservatively purge all tiers. - Scope-specific cold-cache records persist an origin/content compatibility fingerprint. COLD startup rejects stale scope records and deletes their cache artifacts. Legacy COLD metadata defaults its fingerprint to zero; production vhosts have a nonzero SHA-derived fingerprint. A one-time cold refill can occur on the 0.33.8 -> 0.34.0 upgrade because the global identity changed. - A separate administrative configuration revision acts as a cache-ticket publication barrier: a request bound to a pre-save routing snapshot cannot create a new cache ticket after the save. The data revision stays stable for operational-only saves, so previously cached objects remain available. - Reverse-proxy response-body byte metering captures the backend lease once at wrapper creation instead of acquiring a backend-selection mutex per DATA frame. Request-body accounting, error paths and exchange ownership remain. - An **opt-in `sendfile: auto`** setting is wired through Web Service serde, compiled config, the Delivery UI and documented API. The Linux HTTP/1.1 TCP transport adapter calls `libc::sendfile` for eligible static files; cache-enabled, ranged, compressed, transformed and TLS/H2/H3 paths retain existing streaming. It is **disabled by default** and must pass native compilation, correctness, transport and load tests before use. No persisted SQLite schema migration or LB UI change is required. ## Local verification | Check | Outcome | Coverage / caveat | |---|---|---| | `./dev.sh doctor` | PASS | Project source layout and tool inventory | | SQL migration/preset test | PASS | All ten migrations re-applied, preset access and limits | | Upgrade test | PASS | Stop/lock guards, SQLite/.env/language preservation, symlink rejection | | Python compileall | PASS | Python syntax only | | Vhost LB/Cache Chromium test | PASS | Simulated browser quick-view, 320/375/768/1440px | | Other Chromium scripts | 15 PASS | Simulated API/CSS/JS, not a live Rust server | | Sidebar navigation Chromium test | INCOMPLETE | Execution time budget; not counted as a pass | | Three Node dashboard scripts | PASS | Simulated UI logic | | `./dev.sh check` and `./dev.sh test` | BLOCKED | `cargo`/`rustc` unavailable | | Rust unit/integration tests (including new scoped COLD regression) | NOT RUN | Requires Rust toolchain | | Live HTTP/protocol/LB regressions | NOT RUN | Requires built 0.34.0 binary | | 0.33.8 / 0.34.0 / nginx paired RPS benchmarks | NOT RUN | No verified 0.34.0 binary | | Zero-copy sendfile WWW setting | SOURCE IMPLEMENTED / NOT RUNTIME VERIFIED | Linux plain H1 static GET only, `off` by default | | Sendfile editor Chromium save/reload | PASS | 375/1440px, simulated admin API, off -> auto -> off | | Sendfile Rust adapter + fallback test code | ADDED / NOT RUN | TCP marker replacement, persistent socket, HEAD, range, conditional; compiler unavailable | | Amdahl sendfile/nginx sensitivity study | PASS MODEL | No runtime evidence for simulated improvements | The 0.33.8 report in the supplied evidence archive recorded **706 passing Rust tests**, **152 HTTP assertions**, **111 transport assertions** and **17 LB assertions**. Those are *prior-version* results and are **not evidence that 0.34.0 passes**. This report never transfers previous pass counts. ## Synthetic cache-retention scenario (not an RPS measurement) Run: ```bash python3 scripts/performance/simulate_cache_034.py ``` Assume 20 vhosts, 100 HOT + 100 COLD objects each, all public/cacheable with infinite TTL and adequate cache capacity; 1,000 configuration saves (800 operational-only, 200 content changes to one vhost), followed by 500 uniformly random GETs per save. A miss immediately reloads an object into its original tier. No networking, filesystem, CPU timing, origin delay or concurrency is modeled. Results with seed 3400: | Synthetic metric | Old global purge | 0.34.0 scoped retention | |---|---:|---:| | Object invalidations | 473,540 | 37,300 | | GET misses | 470,006 | 37,069 | | GET hits | 29,994 | 462,931 | | HIT ratio | 5.999% | 92.586% | The modeled change yields **92.123% fewer invalidations**, **92.113% fewer misses**, and **+86.587 percentage points** of synthetic cache HIT ratio. **Measured 0.34.0 requests/s gain: unknown.** These values must not be presented as a real speedup or a projection against nginx. ## Previously measured comparison (0.33.8, not this candidate) From the attached 0.33.8 evidence, five paired benchmark runs with cache OFF, median RPS: | Mode / payload | 0.33.8 RPS | nginx RPS | 0.33.8 / nginx | |---|---:|---:|---:| | Reverse proxy 1,040 B | 29,334.12 | 170,610.16 | 17.19% | | Reverse proxy 64 KiB | 20,735.07 | 35,393.29 | 58.58% | | Reverse proxy 1 MiB | 4,461.19 | 2,730.23 | 163.40% | | WWW 1,040 B | 24,906.20 | 351,605.13 | 7.08% | | WWW 64 KiB | 20,856.67 | 203,709.91 | 10.24% | | WWW 1 MiB | 2,833.71 | 12,611.49 | 22.47% | The 0.33.8 1 MiB proxy path was **2.77% slower than rebuilt 0.33.7**. Removing a per-response-frame mutex is a performance candidate but is **not** a measured correction of that regression. No throughput gains are attributed here to the new source changes. ## Hypothetical 0.34.0/nginx gap sensitivity (NOT MEASURED) Run `python3 scripts/performance/simulate_nginx_gap_034.py`. Using the **real 0.33.8 measured medians** above, assume zero-copy removes 50% of the read/copy part of per-request cost; that part hypothetically accounts for 20/40/60% of *total* cost for eligible static files. Model **1/3/5%** total service-time savings from removed proxy-frame mutexes, independently. Amdahl: `RPS_sim = RPS_0.33.8 / (1 - hypothetical_fraction_saved)`. The result is a sensitivity calculation, **not a prediction or 0.34.0 benchmark**. | Workload | Measured 0.33.8/nginx | Modeled low | Modeled middle | Modeled high | |---|---:|---:|---:|---:| | Proxy 1040 B | 17.19% | 17.37% | 17.73% | 18.10% | | Proxy 64 KiB | 58.58% | 59.18% | 60.40% | 61.67% | | Proxy 1 MiB | 163.40% | 165.05% | 168.45% | 172.00% | | WWW 1040 B | 7.08% | 7.08% | 7.08% | 7.08% | | WWW 64 KiB | 10.24% | 11.38% | 12.80% | 14.63% | | WWW 1 MiB | 22.47% | 24.97% | 28.09% | 32.10% | These ratios apply only to eligible Linux plain HTTP/1.1 static workloads with cache OFF. TLS, HTTP/2, HTTP/3, ranged, compressed and object-cached responses are **not** accelerated by this bridge. Bandwidth, contention, queueing, realistic filesystem and actual CPU profiles are not modeled. Even the favorable modeled 1 MiB case remains ~3.1x slower than nginx WWW; small WWW remains ~14.1x slower. Proxy 1 MiB already exceeds nginx in the **prior baseline**, not as a demonstrated new 0.34.0 improvement. ## Required rollout gates 1. On a trusted Linux build worker with the pinned Rust toolchain, run `./dev.sh check`, `CARGO_INCREMENTAL=0 ./dev.sh test`, and a locked release build. Resolve any compiler/test issues before a deployment. 2. Follow `scripts/performance/README.md` to run `regression.py`, `transport_regression.py`, `lb_regression.py`, and `concurrency_regression.py` against verified 0.33.8 and 0.34.0 binaries. 3. Exercise administration saves during simultaneous requests: save keepalive values and confirm unchanged HOT/COLD entries and hashes; change one backend origin and confirm only its scope is purged, both before/after restart. Check that old snapshots cannot recreate invalidated objects. 4. Run the five-repeat, 15-second paired benchmark against 0.33.8, 0.34.0 and nginx on the *same host and affinity*, including large proxy responses, CPU, RSS, resource limits and response correctness. 5. Compile the source-level Linux `sendfile` bridge and validate on a running RustProxy process: plain HTTP/1 sendfile path, headers/body exactness, keepalive/pipelining, slow clients, cancellation, HEAD, range, cache, compression, TLS/H2/H3 fallback, symlink security and observability. Do **not** activate Auto on production before that gate passes. 6. Complete a mixed-traffic soak and staged rollback rehearsal. Until then, do not describe 0.34.0 as production-accepted.