On this page

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


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.Pools, 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 and mux.go:239–266.
  • Mux.PoolFastParams opt-in (Opt O9). Three tier-matched sync.Pools 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.Pools on the standard http.Handler path. Default false. Lifetime contract: handlers must not retain *http.Request past return. See /docs/max-performance.
  • Mux.PoolFastParams bool — opt-in. When true, recycles the Params slice handed to FastHandler routes via three tier-matched sync.Pools. 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:

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 "Lifetime contract" — see 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.