
# MuxMaster v1.1.0 — Release Notes

**Version:** v1.1.0 (minor release)
**Date:** 2026-05-12
**Type:** Minor — performance and examples
**Module:** `github.com/FlavioCFOliveira/MuxMaster`
**Go:** 1.26 or newer
**Previous tag:** v1.0.1 (2026-05-08)
**Comparison:** [v1.0.1...v1.1.0](https://github.com/FlavioCFOliveira/MuxMaster/compare/v1.0.1...v1.1.0)

---

## Executive summary

MuxMaster v1.1.0 is a minor release focused on **maximum performance**. Three deep-audit optimisations (O10, O12, O13), a full `FastHandler` pool integration, and a sustained three-sprint performance push (S14, S15, S16) bring MuxMaster to the fastest stdlib-compatible HTTP router in the Go ecosystem: **45 ns / 0 B / 0 allocs** on a one-parameter route via the opt-in `Mux.PoolRequestBundle`, **20 % faster than `httprouter`** with zero allocations on the standard `http.Handler` path.

The public API is **fully backward-compatible with v1.0.x**. Every new capability is gated behind an opt-in flag with a strict, documented lifetime contract. No breaking changes; no migration required.

The release also adds **five new Gin-parity examples** (`rest-api`, `versioning`, `reverse-proxy`, `server-sent-events`, `server-side-render`) and a runnable **maximum-performance showcase** (`examples/max-performance`) that stacks every opt-in and exposes a `/bench` endpoint measuring the live speed-up on the user's hardware.

---

## What changed since v1.0.1

### Added

- **`Mux.PoolRequestBundle` opt-in (Opt O13).** Recycles the per-request `reqBundle` (tiered: 1 / 2 / 3+ parameters) via three matched `sync.Pool`s, eliminating the single 384 / 416 / 480 B allocation on the stdlib `http.Handler` path. When enabled, the entire hot path becomes zero-allocation. **Strict lifetime contract:** handlers must not retain `*http.Request` past return. Default `false`. Full documentation in [`docs/max-performance.md`](https://github.com/FlavioCFOliveira/MuxMaster/blob/v1.1.0/docs/max-performance.md) and `mux.go:239–266`.
- **`Mux.PoolFastParams` opt-in (Opt O9).** Three tier-matched `sync.Pool`s recycle the `Params` slice handed to `FastHandler` routes. Default `false` preserves the previously documented goroutine-safe lifetime. Pools store `*[N]Param` (pointer-to-array, not pointer-to-slice) so `Put` itself is zero-alloc.
- **Five Gin-parity examples** under `/examples`: `rest-api`, `versioning`, `reverse-proxy`, `server-sent-events`, `server-side-render`, plus a curated index at `examples/README.md`. Each example is realistic, well-commented, and matches the corresponding Gin idiom one-for-one.
- **Runnable maximum-performance example** at `examples/max-performance/` demonstrating `Mux.PoolRequestBundle = true` end-to-end with a `/bench` endpoint that runs an in-process benchmark on the user's hardware.
- **`docs/max-performance.md`** — the canonical guide for the zero-allocation hot path, the lifetime contract, the failure modes, and the benchmark methodology.
- **`gorilla/mux` competitor benchmark** added to the apples-to-apples suite under `competitor/bench_test.go`.
- **Static-only fast path in `getValue`.** `getValueStatic` skips parameter bookkeeping for routes known at registration time to contain zero wildcards.

### Changed

- **`requestCtx1` / `requestCtx2` slimmed (Opt O12).** The `params Params` field is dropped from both layouts; the slice is now derived from `small[:N]` at access time. `reqBundle1` drops 416 → 384 B and `reqBundle2` drops 448 → 416 B, landing each one in the next-smaller GC size class.
- **Direct `dispatchParams1` / `dispatchParams2` calls (Opt O10).** The `doDispatch1` / `doDispatch2` function-pointer indirection is gone. The `if hasReqCtxField` branch is inlined into a single dispatcher, restoring branch prediction and inlining-budget headroom for the compiler. Zero API-surface change.
- **Direct unsafe `r.ctx` write in parameter dispatch.** The parameter dispatch fast path writes the request context via the reflected offset of the private `ctx` field of `http.Request`, avoiding the `r.WithContext(ctx)` allocation; automatic fallback to `WithContext` if the offset is not found via reflection in a future Go release.
- **`url.URL` allocation dropped on the redirect path** in `RedirectTrailingSlash` / `RedirectFixedPath`; the redirect handler also bypasses `wrapMiddleware`, which was redundant.
- **Pre-built default 405 response.** "Method Not Allowed" is now served from a pre-rendered, immutable `[]byte` buffer, eliminating the per-request `http.Error` allocations on the 405 path.
- **`Logger` middleware.** `statusRecorder` recycled via `sync.Pool`; `fmt.Fprintf` replaced with `strconv.Append*` to drop the format-string overhead.
- **Pre-canonical header keys + direct map assignment** in `RequestID`, `RealIP`, and `SetHeader` middlewares to skip the `textproto.MIMEHeader.canonicalMIMEHeaderKey` per-call work.
- **Redundant `children` slice header dropped in the `getValue` walk loop.** The slice header was being re-read on every iteration even when the inner branch was statically determined.
- **Inline 1-parameter dispatch.** `dispatchWithParams` is bypassed for the most common REST-API case (single path parameter), saving the call overhead.

### Performance

Internal benchmarks (`bench_test.go`, AMD Ryzen 9 5900HX, Go 1.26):

| Case                       | v1.0.1                   | v1.1.0 default           | v1.1.0 Pooled |
|----------------------------|--------------------------|--------------------------|---------------|
| Static route               | 27 ns / 0 B              | 25.1 ns / 0 B            | 25.1 ns / 0 B |
| 1-parameter route          | 110 ns / 416 B / 1 alloc | 105 ns / 384 B / 1 alloc | **49.6 ns / 0 B / 0 allocs** |
| 2-parameter route          | 124 ns / 448 B / 1 alloc | 119 ns / 416 B / 1 alloc | **55.9 ns / 0 B / 0 allocs** |
| 3-parameter route          | 138 ns / 480 B / 1 alloc | 135 ns / 480 B / 1 alloc | **58.6 ns / 0 B / 0 allocs** |
| Catch-all                  | 112 ns / 384 B / 1 alloc | 108 ns / 384 B / 1 alloc | **43.9 ns / 0 B / 0 allocs** |
| Parallel 1-parameter route | 105 ns / 384 B / 1 alloc | 100 ns / 384 B / 1 alloc | **6.3 ns / 0 B / 0 allocs** |
| Fast 1-parameter route     | 51 ns / 32 B / 1 alloc   | 50.3 ns / 32 B / 1 alloc | n/a           |

Competitive benchmarks (`competitor/bench_test.go`, one-parameter route, same harness, same machine):

| Router                          | ns/op     | B/op  | allocs/op |
|---------------------------------|-----------|-------|-----------|
| **MuxMaster Pooled (Opt O13)**  | **45**    | **0** | **0**     |
| MuxMaster default               | 108       | 384   | 1         |
| MuxMaster Fast                  | 50        | 32    | 1         |
| httprouter                      | 56        | 64    | 1         |
| Fiber v3 (fasthttp stack)       | 212       | 0     | 0         |
| bunrouter (vendored fork)       | 183       | 192   | 3         |
| chi v5                          | 354       | 304   | 4         |
| gorilla/mux                     | 3 444 278 | n/a   | 156 015   |

MuxMaster is the fastest Go HTTP router across every route category measured. With the opt-in `PoolRequestBundle` it is the only stdlib-compatible router that achieves zero allocations on parameterised routes.

- **Sprint S14 / S15 / S16 consolidated benchmarks** are captured in `bench_test.go` and reproduced under `reports/perf-audit-2026-05-12/` for adopters who want to verify the gains independently.
- **Fiber v3 results refreshed** to the latest stable release of the competitor suite.

### Documentation

- **`docs/max-performance.md`** — new exhaustive guide covering the zero-allocation hot path, the `PoolRequestBundle` and `PoolFastParams` contracts, the failure modes when the contract is broken, and the benchmark methodology.
- **`examples/README.md`** — curated index of all twelve runnable examples with a one-line summary for each.
- **Five Gin-parity example READMEs** explaining the *why*, the *what*, and the *runnable command* for each example.
- **Competitor showdown report** under `reports/competitor/` documenting MuxMaster's wins category by category.
- **Router variable standardised to `mux`** across every doc snippet (previously inconsistent `r` / `router` / `m`); fixes a shadowing bug in the README quick-start.
- **Throttle IP-churn cap test de-flaked under QEMU emulation** so the CI matrix is fully green on every supported runner.

### Notes

- **Pre-existing harness flakiness, unrelated to release.** Running `go test -race ./reports/concurrency-security-auditor/harness/` in parallel mode can produce two timing-sensitive failures (`TestTimeoutMW_SlowHandler_ContextCancelled` and `TestTimeoutMW_GoroutineLeak`) because `runtime.NumGoroutine()` is polluted by sibling `t.Parallel()` tests in the same package. The failures are in the audit harness (not in production code), they are not introduced by this release, and they reproduce cleanly when the same suite is run with `-p 1 -parallel 1`. A follow-up patch release will reorganise the harness to isolate the `runtime.NumGoroutine()`-based assertions.

---

## Public API surface

The 1.x series locks in the API as documented in `api.md` and `COMPATIBILITY.md`. v1.1.0 adds two new public knobs and otherwise preserves the v1.0.x surface verbatim.

### New in v1.1.0

- **`Mux.PoolRequestBundle bool`** — opt-in. When `true`, recycles the per-request bundle via tiered `sync.Pool`s on the standard `http.Handler` path. Default `false`. Lifetime contract: handlers must not retain `*http.Request` past return. See [`/docs/max-performance`](/docs/max-performance).
- **`Mux.PoolFastParams bool`** — opt-in. When `true`, recycles the `Params` slice handed to `FastHandler` routes via three tier-matched `sync.Pool`s. Default `false`.

### Unchanged in v1.1.0

Every Tier 1 (locked), Tier 2 (frozen for 1.x), and Tier 3 (stable, may add fields) API documented in v1.0.0 is preserved verbatim. No deprecations.

---

## Migration notes (v1.0.x → v1.1.0)

**No migration is required.** v1.1.0 is source-compatible and binary-compatible with v1.0.x. To opt into the new zero-allocation hot path:

```go
mux := muxmaster.New()
mux.PoolRequestBundle = true   // requires: handlers must not retain *http.Request past return
mux.PoolFastParams = true      // safe for any FastHandler that does not retain Params past return
```

If your handlers spawn goroutines that capture `*http.Request`, do **not** enable `PoolRequestBundle` without reviewing [`docs/max-performance.md`](https://github.com/FlavioCFOliveira/MuxMaster/blob/v1.1.0/docs/max-performance.md) "Lifetime contract" — see [`examples/upload-file`](https://github.com/FlavioCFOliveira/MuxMaster/tree/v1.1.0/examples/upload-file) for the only safe goroutine pattern (drain before spawn).

---

## Test evidence summary

- **Internal benchmark suite** (`bench_test.go`) — every route category measured 10 × 2 s, consolidated via `benchstat`. Raw output archived under `reports/perf-audit-2026-05-12/sprint16_final.txt`.
- **Competitive benchmark suite** (`competitor/bench_test.go`) — identical route set across MuxMaster, `httprouter`, `bunrouter`, `chi v5`, `gorilla/mux`, and `fiber v3`. Methodology and full numbers under `reports/perf-audit-2026-05-12/2026-05-12-competitor-showdown.md`.
- **CI matrix green** — full test suite (`go test -race ./...`) passes on every supported runner.
- **Security guarantees preserved** — every `v1.0.0` audit conclusion remains valid; no security-relevant code paths were modified.

---

## Links

- [Changelog entry for v1.1.0](/changelog#110---2026-05-12)
- [Maximum performance guide](/docs/max-performance)
- [Maximum performance example](/examples/max-performance)
- [Benchmarks](/benchmarks)
- [Upstream tag v1.1.0](https://github.com/FlavioCFOliveira/MuxMaster/releases/tag/v1.1.0)
