v1. Compresses LLM chat history inside busbar
using headroom's Rust
compression core (TextCrusher, pure BM25: no model, no network, no proxy).
A rewrite gate on busbar's hook wire; targets busbar 1.3.0 and pins a
headroom-core rev.
Measured the way busbar measures itself: from busbar's own clock. Busbar reports
its internal processing time — total request time minus the upstream round-trip — in
a standard Server-Timing: busbar;dur=<ms> header on every response. The Headroom
gate runs synchronously inside that window (busbar calls the hook and waits for the
rewrite before dispatch), so busbar;dur captures exactly what the hook adds, on
busbar's clock, with none of the benchmark harness's own round-trip in it. Every
number below is reproducible — see bench/.
busbar;dur, in µs, concurrency 1, 1,000 requests per row, 11 KB noisy tool-log
history, openai → openai:
| p50 | p90 | p99 | |
|---|---|---|---|
| Busbar alone | 22 |
25 |
30 |
| Busbar + Headroom | 569 |
601 |
634 |
| Headroom's added cost | 547 |
576 |
604 |
Cross-protocol (anthropic → openai) is within noise: 34 base / 584 with-hook /
550 added, p50.
Two things this shows. Busbar itself is tens of µs (22 µs p50 here; its own
benchmark sweeps 37–93 µs across
protocols and payloads) — the gateway is not where your latency goes. And Headroom
adds ~547 µs to compress an 11 KB history, with a tight tail: p99 is only
~1.1× p50, because busbar and the hook are single Rust binaries with no garbage
collector — nothing in the path pauses to sweep memory. Compression cost scales with
history size (direct socket driver, p50): 150 µs at 2 KB, 380 µs at 8 KB, 720 µs
at 16 KB, 2,900 µs at 64 KB.
On a two-second inference call, 547 µs is 0.03% of the request.
This is not a compression benchmark — measuring how well Headroom compresses is the Headroom project's job, and it reports higher ratios than the ~50% seen here (66–94% on some content types), with more to gain from tuning the keep-ratio. What matters here is that the plumbing is sound: the mock upstream tallies the tokens it actually received, so these are the prompts that really shipped to the provider, not hook-side accounting.
| content (11 KB) | input tokens before | after | saved |
|---|---|---|---|
| noisy tool log | 2,832 |
1,422 |
49.8% |
| RAG dump | 4,211 |
2,127 |
49.5% |
| short chat | 22 |
22 |
0% (abstains) |
Short conversational chats pass through byte-identical (100% abstain over 100 short chats; 0% over 100 compressible histories) — nothing to trim, nothing touched. And if the hook is ever slow, wrong, or down, the request proceeds with its original body.
Headroom's own HTTP proxy reports, from production telemetry (50,000+ sessions, 250+ instances), a 52 ms median overhead — which, as they rightly note, is negligible against multi-second inference. Running the same compression core as a busbar gate, the added cost measures 547 µs on busbar's clock. Both are small next to the model call; we make no claim about how their proxy is deployed — only that the same core, run as a socket gate on busbar's path, measures in the hundreds of microseconds. Full credit to the Headroom project for the core; busbar just puts it in front of every model you call.
Reproduce every number: see bench/README.md.
The hook is a small binary you run alongside busbar; busbar connects to it over a Unix socket. You own its lifecycle — busbar never spawns it; it lazy-connects and reconnects across restarts, so start order doesn't matter.
Two tiny images, one shared socket — copy, paste, running:
curl -fsSL -O https://raw.githubusercontent.com/GetBusbar/headroom-hook/main/docker-compose.yml
curl -fsSL -o config.yaml https://raw.githubusercontent.com/GetBusbar/headroom-hook/main/config.example.yaml
export ANTHROPIC_KEY=sk-ant-... # or edit config.yaml for your provider
docker compose upbusbar (:8080) and the compression hook come up together and Headroom is on
every request. The starter config registers the hook
globally over one Anthropic pool — edit it for your own pools/providers. The
images are getbusbar/headroom-hook and getbusbar/busbar.
Grab it from the latest release:
# Linux x86_64
curl -fsSL -o headroom-hook https://github.com/GetBusbar/headroom-hook/releases/latest/download/headroom-hook-linux-x86_64
# Linux arm64
curl -fsSL -o headroom-hook https://github.com/GetBusbar/headroom-hook/releases/latest/download/headroom-hook-linux-aarch64
# macOS (Apple Silicon)
curl -fsSL -o headroom-hook https://github.com/GetBusbar/headroom-hook/releases/latest/download/headroom-hook-macos-arm64
chmod +x headroom-hookEach release ships a SHA256SUMS; verify with sha256sum -c SHA256SUMS. Then run it on a socket:
HEADROOM_SOCKET=/tmp/headroom.sock ./headroom-hookNeeds a Rust toolchain (rustup); the pinned headroom-core rev is in Cargo.toml.
git clone https://github.com/GetBusbar/headroom-hook && cd headroom-hook
cargo build --release # binary: target/release/headroom-hookHEADROOM_TARGET_RATIO (default 0.5, the fraction of tokens to keep),
HEADROOM_MIN_SAVINGS_PCT (default 10, abstain below this saving), and
HEADROOM_PRICE_UDOLLARS_PER_KTOK (default 2500, the $-estimate price) SEED the
startup values — once busbar pushes settings over the wire, the push wins. Point
busbar at the socket (see the config block below) or register the hook live over
the admin API. That's it.
OS support. The hook speaks a Unix socket, so it runs on Linux and macOS (any arch). There is no native Windows build and no HTTP mode — on Windows, run busbar and the hook together inside WSL2 or a Linux container, where the socket works normally.
Newline-delimited JSON on one kept-alive Unix-socket connection, dispatched by the top-level key:
| message | direction | this hook's reply |
|---|---|---|
configure |
busbar → hook, first line of every connection + live on a settings PATCH | {"ack":{"settings_version":N}} echoing the pushed version — only if the settings applied cleanly (commit-on-ack) |
describe |
busbar → hook, any time | {schema, dashboard} — the settings JSON Schema (GET /api/v1/admin/hooks/headroom/schema) + the dashboard widget layout |
status |
busbar → hook, any time | {status:{settings, metrics:[…]}} — observed settings + self-reported metrics (see Metrics) |
| decide / transform | busbar → hook, per request | {"rewrite":{...}} or {} (abstain) |
| notify | busbar → hook, fire-and-forget (taps only) | none read |
Settings (target_ratio, min_savings_pct, price_udollars_per_ktok)
arrive as desired state: a key absent from the push resets to its default, a
rejected push (unknown key, bad value) is never acked and busbar keeps the
previous settings. Retune live, no restart:
curl -X PATCH localhost:8080/api/v1/admin/hooks/headroom/settings \
-d '{"target_ratio": 0.3, "min_savings_pct": 20}'The hook reports its own operational metrics on the status message, and busbar surfaces them two
ways from that one source:
- Live JSON —
GET /api/v1/admin/hooks/headroom/statusqueries the hook on the spot (you set the resolution by how often you poll: hit it every second, get one-second-fresh data). - Prometheus — busbar's
/metrics/hooksscrape renders the same metrics as standard text, with the metric names verbatim and an automatichook="headroom"label.
The names follow Headroom's own vocabulary where they map —
proxy_compression_ratio_by_strategy{strategy,content_type},
proxy_compression_rejected_by_token_check_total, proxy_passthrough_bytes_modified_total — so a
dashboard built against Headroom points at busbar and lights up. Alongside them, busbar-native
per-pool extras: tokens_saved_total, dollars_saved (an estimate, priced off
price_udollars_per_ktok, marked estimated with a confidence interval — busbar's /usage is the
measured spend), compress_latency_us (a p50/p90/p99 histogram), and the request counters. Every
series carries a pool label, so one process serving N pools shows N rows.
hooks:
headroom:
kind: gate
socket: /tmp/headroom.sock
prompt: rw # the rewrite grant
global: true # fire on every request
timeout_ms: 25 # ~550 µs typical; 25 ms is generous headroom
on_error: nothing # a broken compressor never touches a request
settings: # pushed to the hook as the first line of every connection
target_ratio: 0.5
min_savings_pct: 10The clean experiment: one busbar, two pools over the same model — one with
the hook, one without — and point half your traffic at each. Compare
per-pool tokens and latency in /metrics or GET /api/v1/admin/usage.
pools:
with-headroom:
hooks: [headroom] # drop `global: true` from the hook definition
members: [ { target: claude-sonnet, weight: 1 } ]
baseline:
members: [ { target: claude-sonnet, weight: 1 } ]Status: pool-scoped rewrite gates are not fired by the current 1.3.0-dev engine yet (the transform pass is global-only), and on same-protocol passthrough the engine's pristine-bytes fast path can skip the rewritten body — both found while building this POC and tracked for the engine. Until then, A/B with two busbar instances (one with
global: true, one without), which is how the numbers above were measured.
scripts/smoke.sh proves the socket protocol without busbar: the
configure-ack handshake, a describe, and a rewrite round-trip on one
connection, in busbar's order.
The bench/ directory has the full measurement rig and results.