File size: 7,702 Bytes
ad6f44c
 
 
 
 
 
 
 
 
 
 
 
 
c0fb63f
 
ad6f44c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# Headroom Latency Benchmarks

Measured compression overhead across content types and sizes to answer: **does the token savings outweigh the processing time?**

Generated: 2026-02-24 01:11 UTC

## Environment

- **Platform**: macOS-26.1-arm64-arm-64bit
- **Processor**: arm
- **Python**: 3.11.11
- **Headroom**: v0.3.7

> **Note:** These benchmarks were captured on v0.3.7. Since then, v0.5.6 added parallel message compression, eliminated redundant token counting, and optimized hot-path hashing. Expect lower latency on current versions. Re-benchmarking is planned.

## TL;DR

- Average compression: **93%** token reduction
- Maximum compression overhead: **12213ms** (p50)
- Net latency win: **11/12** scenarios against Claude Sonnet 4.5

## Compression Overhead by Scenario

| Scenario | Tokens In | Tokens Out | Saved | Ratio | p50 (ms) | p95 (ms) | Mean (ms) |
|----------|-----------|------------|-------|-------|----------|----------|-----------|
| JSON: Search Results (100 items) | 10.2K | 1.5K | 8.7K | 86% | 189 | 231 | 196 |
| JSON: Search Results (500 items) | 50.2K | 1.5K | 48.7K | 97% | 943 | 955 | 943 |
| JSON: Search Results (1K items) | 100.5K | 1.5K | 99.0K | 99% | 2012 | 2198 | 2032 |
| JSON: Search Results (5K items) | 502.6K | 1.5K | 501.2K | 100% | 12213 | 12804 | 12223 |
| JSON: API Responses (500 items) | 38.9K | 1.1K | 37.8K | 97% | 743 | 776 | 744 |
| JSON: Database Rows (1K rows) | 43.7K | 605 | 43.1K | 99% | 961 | 1104 | 986 |
| JSON: String Array (100 strings) | 1.1K | 231 | 820 | 78% | 15.0 | 15.4 | 15.0 |
| JSON: String Array (500 strings) | 4.9K | 233 | 4.6K | 95% | 71.9 | 80.3 | 72.7 |
| JSON: String Array (1K strings) | 9.6K | 242 | 9.4K | 97% | 146 | 160 | 147 |
| JSON: Number Array (200 numbers) | 1.2K | 192 | 1.1K | 85% | 30.9 | 61.9 | 33.8 |
| JSON: Number Array (1K numbers) | 6.1K | 243 | 5.8K | 96% | 301 | 307 | 300 |
| JSON: Mixed Array (250 items) | 2.3K | 368 | 1.9K | 84% | 38.4 | 39.8 | 38.4 |

## Per-Transform Latency Breakdown

| Scenario | Transform | p50 (ms) | % of Total |
|----------|-----------|----------|------------|
| JSON: Search Results (100 items) | cache_aligner | 2.2 | 1% |
| JSON: Search Results (100 items) | content_router | 186 | 98% |
| JSON: Search Results (100 items) | rolling_window | <0.01 | 0% |
| JSON: Search Results (500 items) | cache_aligner | 10.7 | 1% |
| JSON: Search Results (500 items) | content_router | 927 | 98% |
| JSON: Search Results (500 items) | rolling_window | <0.01 | 0% |
| JSON: Search Results (1K items) | cache_aligner | 21.0 | 1% |
| JSON: Search Results (1K items) | content_router | 1980 | 98% |
| JSON: Search Results (1K items) | rolling_window | <0.01 | 0% |
| JSON: Search Results (5K items) | cache_aligner | 105 | 1% |
| JSON: Search Results (5K items) | content_router | 11985 | 98% |
| JSON: Search Results (5K items) | rolling_window | <0.01 | 0% |
| JSON: API Responses (500 items) | cache_aligner | 8.8 | 1% |
| JSON: API Responses (500 items) | content_router | 729 | 98% |
| JSON: API Responses (500 items) | rolling_window | <0.01 | 0% |
| JSON: Database Rows (1K rows) | cache_aligner | 9.3 | 1% |
| JSON: Database Rows (1K rows) | content_router | 946 | 99% |
| JSON: Database Rows (1K rows) | rolling_window | <0.01 | 0% |
| JSON: String Array (100 strings) | cache_aligner | 0.27 | 2% |
| JSON: String Array (100 strings) | content_router | 14.5 | 97% |
| JSON: String Array (100 strings) | rolling_window | <0.01 | 0% |
| JSON: String Array (500 strings) | cache_aligner | 0.95 | 1% |
| JSON: String Array (500 strings) | content_router | 70.2 | 98% |
| JSON: String Array (500 strings) | rolling_window | <0.01 | 0% |
| JSON: String Array (1K strings) | cache_aligner | 1.9 | 1% |
| JSON: String Array (1K strings) | content_router | 143 | 98% |
| JSON: String Array (1K strings) | rolling_window | <0.01 | 0% |
| JSON: Number Array (200 numbers) | cache_aligner | 0.66 | 2% |
| JSON: Number Array (200 numbers) | content_router | 29.6 | 96% |
| JSON: Number Array (200 numbers) | rolling_window | <0.01 | 0% |
| JSON: Number Array (1K numbers) | cache_aligner | 2.5 | 1% |
| JSON: Number Array (1K numbers) | content_router | 297 | 99% |
| JSON: Number Array (1K numbers) | rolling_window | <0.01 | 0% |
| JSON: Mixed Array (250 items) | cache_aligner | 0.58 | 1% |
| JSON: Mixed Array (250 items) | content_router | 37.4 | 97% |
| JSON: Mixed Array (250 items) | rolling_window | <0.01 | 0% |

## Cost-Benefit Analysis

Net latency benefit = LLM time saved from fewer tokens - compression overhead.

| Scenario | Compress (ms) | LLM Saved (ms)* | Net Benefit | $/1K Requests** |
|----------|---------------|-----------------|-------------|-----------------|
| JSON: Search Results (100 items) | 189 | 261 | +71.8ms | $26.13 |
| JSON: Search Results (500 items) | 943 | 1461 | +517.5ms | $146.06 |
| JSON: Search Results (1K items) | 2012 | 2969 | +956.9ms | $296.91 |
| JSON: Search Results (5K items) | 12213 | 15035 | +2822.2ms | $1503.53 |
| JSON: API Responses (500 items) | 743 | 1134 | +390.7ms | $113.38 |
| JSON: Database Rows (1K rows) | 961 | 1292 | +330.7ms | $129.16 |
| JSON: String Array (100 strings) | 15.0 | 24.6 | +9.6ms | $2.46 |
| JSON: String Array (500 strings) | 71.9 | 139 | +67.1ms | $13.90 |
| JSON: String Array (1K strings) | 146 | 282 | +135.9ms | $28.16 |
| JSON: Number Array (200 numbers) | 30.9 | 31.6 | +0.7ms | $3.16 |
| JSON: Number Array (1K numbers) | 301 | 175 | -126.3ms | $17.45 |
| JSON: Mixed Array (250 items) | 38.4 | 56.6 | +18.2ms | $5.66 |

\* LLM time saved based on Claude Sonnet 4.5 prefill rate (0.03ms/token)
\*\* Cost savings at $3.0/MTok input pricing

## Break-Even Across Models

Compression overhead (p50) vs. LLM time saved for different model speed tiers:

| Scenario | Compress (ms) | GPT-4o Mini | GPT-4o | Claude Sonnet 4.5 | Claude Opus 4 |
|----------|---------------|------------|------------|------------|------------|
| JSON: Search Results (100 items) | 189 | -102ms | +71.8ms | +71.8ms | +507ms |
| JSON: Search Results (500 items) | 943 | -456ms | +518ms | +518ms | +2952ms |
| JSON: Search Results (1K items) | 2012 | -1022ms | +957ms | +957ms | +5905ms |
| JSON: Search Results (5K items) | 12213 | -7201ms | +2822ms | +2822ms | +27881ms |
| JSON: API Responses (500 items) | 743 | -365ms | +391ms | +391ms | +2280ms |
| JSON: Database Rows (1K rows) | 961 | -530ms | +331ms | +331ms | +2483ms |
| JSON: String Array (100 strings) | 15.0 | -6.8ms | +9.6ms | +9.6ms | +50.6ms |
| JSON: String Array (500 strings) | 71.9 | -25.6ms | +67.1ms | +67.1ms | +299ms |
| JSON: String Array (1K strings) | 146 | -51.9ms | +136ms | +136ms | +605ms |
| JSON: Number Array (200 numbers) | 30.9 | -20.4ms | +0.68ms | +0.68ms | +53.3ms |
| JSON: Number Array (1K numbers) | 301 | -243ms | -126ms | -126ms | +165ms |
| JSON: Mixed Array (250 items) | 38.4 | -19.5ms | +18.2ms | +18.2ms | +113ms |

## Key Takeaways

1. **Compression pays for itself in latency** for 11/12 compressing scenarios (json). For these, the LLM prefill time saved exceeds compression overhead.
2. **ContentRouter is 98% of pipeline cost** on average — it does the actual compression work. CacheAligner and context management are <2% of total time.
3. **Cost savings are substantial regardless of latency.** The highest-compression scenario (JSON: Search Results (5K items)) saves $1504/1K requests at Claude Sonnet 4.5 pricing.
4. **Slower/pricier models benefit most.** Claude Opus shows a net latency win in 12/12 scenarios vs 11 for Claude Sonnet 4.5, with 0.08ms/token prefill.

---

*Benchmarks run with `python benchmarks/bench_latency.py`. Results vary based on hardware, Python version, and content characteristics.*