Describe the bug
Sanitization is now applied consistently across user-authored response fields, but the current pipeline performs repeated rune conversion and multiple full-string passes. At high request rates this becomes allocation- and GC-bound on list/comment-heavy responses.
Measured examples on current main:
- 100 comments × 1 KiB: about 3.35 ms and 2.06 MiB allocated per conversion.
- 30 issues with 2 KiB bodies: about 2.14 ms and 1.30 MiB allocated.
- A 64 KiB body: about 2.38 ms and 1.21 MiB allocated.
At roughly 1,250 requests/second, workloads dominated by these shapes can require several CPU cores and produce multi-gigabyte/second allocation rates.
Affected version
Current main as of 2026-08-19, after the sanitizer coverage and post-normalization Unicode filtering changes.
Steps to reproduce the behavior
- Benchmark
sanitize.Sanitize for short titles, 1 KiB comments, and 64 KiB bodies.
- Benchmark representative minimal-converter pages containing 30 issues or 100 comments.
- Compare CPU time and allocations with the pre-sanitization converter paths.
- Observe repeated
[]rune conversion and post-normalization passes dominating CPU and allocations.
Expected vs actual behavior
Expected: sanitization preserves the current output and security policy with negligible overhead for ordinary clean text.
Actual: benign content pays for repeated allocating scans and HTML-policy processing, making high-throughput response conversion GC-bound.
Optimize without weakening behavior:
- Make invisible-character filtering scan first and return the original string without allocation when no filtered rune exists.
- Skip the post-HTML invisible/code-fence pass when normalization returned unchanged content.
- Add only a conservative, proven-safe fast path for clean printable ASCII that cannot contain HTML/entity syntax.
- Preserve byte-for-byte sanitizer output across a broad corpus, fuzz/property tests, and all existing edge cases.
- Add committed benchmarks and report before/after CPU and allocation results for representative response shapes.
Logs
N/A
Describe the bug
Sanitization is now applied consistently across user-authored response fields, but the current pipeline performs repeated rune conversion and multiple full-string passes. At high request rates this becomes allocation- and GC-bound on list/comment-heavy responses.
Measured examples on current main:
At roughly 1,250 requests/second, workloads dominated by these shapes can require several CPU cores and produce multi-gigabyte/second allocation rates.
Affected version
Current
mainas of 2026-08-19, after the sanitizer coverage and post-normalization Unicode filtering changes.Steps to reproduce the behavior
sanitize.Sanitizefor short titles, 1 KiB comments, and 64 KiB bodies.[]runeconversion and post-normalization passes dominating CPU and allocations.Expected vs actual behavior
Expected: sanitization preserves the current output and security policy with negligible overhead for ordinary clean text.
Actual: benign content pays for repeated allocating scans and HTML-policy processing, making high-throughput response conversion GC-bound.
Optimize without weakening behavior:
Logs
N/A