Skip to content

fix(memory): cap local embedder CPU thread oversubscription (#198)#1559

Merged
JerrettDavis merged 1 commit into
headroomlabs-ai:mainfrom
Krishnachaitanyakc:fix/memory-embedder-thread-cap-198
Jul 1, 2026
Merged

fix(memory): cap local embedder CPU thread oversubscription (#198)#1559
JerrettDavis merged 1 commit into
headroomlabs-ai:mainfrom
Krishnachaitanyakc:fix/memory-embedder-thread-cap-198

Conversation

@Krishnachaitanyakc

@Krishnachaitanyakc Krishnachaitanyakc commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Description

The torch/sentence-transformers LocalEmbedder ran encodes on the shared default executor with no BLAS/OpenMP thread cap. Under concurrent load each encode() fans out to ~os.cpu_count() BLAS/OpenMP threads, so N in-flight encodes spawn ~N × cpu_count OS threads — oversubscribing the CPU, slowing the memory_context stage and (on smaller boxes) starving the asyncio event loop. The ONNX embedder already bounds its threads (create_cpu_session_options(intra_op_num_threads=1, inter_op_num_threads=1)); this brings the torch path to parity.

Supersedes #691 by @oxura — closed only for the open-PR cap, with an explicit invitation to resubmit; no technical objection was raised, and its CI was fully green. Credit to @oxura for the original diagnosis and fix. That PR capped threads by setting BLAS/OpenMP env vars at import time plus torch.set_num_threads; this PR instead runs CPU encodes on a dedicated, size-limited executor whose workers each pin their thread pool — which additionally bounds in-flight encode concurrency (the issue's Fix B/C) and keeps the cap contained to the embedder rather than mutating process-global env at import.

Closes #198

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Performance improvement

Changes Made

  • CPU encodes now run on a dedicated, size-limited executor whose worker initializer pins each worker's torch intra-op pool (and sets BLAS/OpenMP env defaults). torch's OpenMP thread count is per-thread, so a one-shot cap misses pooled executor workers — the per-worker initializer caps every worker deterministically.
  • Total embedding threads are bounded by HEADROOM_EMBED_CONCURRENCY (default min(4, os.cpu_count())) × HEADROOM_EMBED_NUM_THREADS (default 1); invalid/non-positive values fall back safely (≥1).
  • Mirrors the existing MPS dedicated-single-worker-executor pattern; CUDA keeps the shared default executor (GPU compute is off-CPU). setdefault never overrides an operator's explicit OMP_NUM_THREADS.

Testing

  • Unit tests pass (pytest)
  • Linting passes (ruff check .)
  • Type checking passes (mypy headroom)
  • New tests added for new functionality
  • Manual testing performed

Test Output

$ uv run pytest tests/test_memory/test_embedder_thread_cap.py tests/test_memory/test_embedder_mps_serialization.py -q
13 passed

$ uv run pytest tests/test_memory/ tests/test_cli_proxy_embedding_server.py -q
533 passed        # no regressions from the executor change

$ uv run ruff check .  &&  uv run ruff format --check .
All checks passed!   /   1016 files already formatted

$ uv run mypy headroom --ignore-missing-imports
Success: no issues found in 404 source files

New tests/test_memory/test_embedder_thread_cap.py: env resolution for both knobs (default / positive / invalid / clamped), worker-init env application + operator-override safety, and a behavioral test that loads the real CPU embedder and asserts every executor worker is pinned to the configured intra-op thread count. Updated test_embedder_mps_serialization.py to the new CPU contract.

Real Behavior Proof

  • Environment: built this branch into a CPU-only Linux container, removed onnxruntime so the proxy falls back to the torch LocalEmbedder; a container has no MPS/CUDA, so it resolves to device=cpu — the deployment where [BUG] Memory embedder oversubscribes BLAS/OMP threads under concurrent load; /livez p99 spikes to 4+s #198 occurs. Python 3.12, torch 2.12.1, all-MiniLM-L6-v2, container capped to 4 CPUs, 32 concurrent clients.
  • Exact command / steps: headroom proxy --host 0.0.0.0 --memory in-container; a concurrent /v1/messages driver from the host (invalid key — memory_context runs before the upstream call); measured the memory_context stage from /metrics before vs after the cap.
  • Observed result: the embedder stage this PR targets improved — memory_context avg 73.5 ms → 58.7 ms and max 279 ms → 242 ms (uncapped 12×8 = 96 threads vs fix 4×1): ~20% faster and steadier inside the real proxy. Isolated component benchmarks (heavy concurrent embed_batch; LocalBackend.search_memories) show a larger effect — tail event-loop stall ~16–24 ms → ~3 ms, and search throughput +57%. Unit/regression: 13 new tests + 533 memory-suite tests pass; ruff + mypy clean.
  • Not tested: the issue's absolute multi-second /livez spike. On my hardware/synthetic load, /livez stalls were dominated by the upstream-connection path (invalid-key DNS/TLS), not the ~250 ms memory_context stage, so I can't attribute the multi-second figure to the embedder here — the original report was on an 8-core box with real Claude Code transcripts that drove memory_context itself to several seconds. Linux/CUDA hardware not exercised; no live LLM provider used; ONNX path unchanged. This PR removes the documented thread oversubscription and brings the torch path to ONNX parity; it does not claim to single-handedly resolve the 4 s figure.

Measured memory_context stage timing (real containerized proxy, torch CPU embedder, 4 CPUs, 32 concurrent clients):

memory_context avg max
Before (uncapped, 12×8 = 96 threads) 73.5 ms 279 ms
After (fix, 4×1) 58.7 ms 242 ms

Review Readiness

  • I have performed a self-review
  • This PR is ready for human review

Additional Notes

Default-behavior change: CPU encodes use a dedicated bounded pool instead of the shared default executor (close() tears it down). Both knobs are opt-in overrides with safe defaults. No new dependencies.

…labs-ai#198)

The torch/sentence-transformers LocalEmbedder ran encodes on the shared default
executor with no BLAS/OpenMP thread cap, so under concurrent load each encode
fanned out to ~os.cpu_count() threads and oversubscribed the CPU, slowing the
memory_context stage and starving the event loop. The ONNX embedder already caps
its threads; this brings the torch path to parity.

CPU encodes now run on a dedicated, size-limited executor whose workers each pin
their torch intra-op pool (torch's OpenMP count is per-thread, so a one-shot cap
misses pooled workers). Total embedding threads are bounded by
HEADROOM_EMBED_CONCURRENCY (default min(4, cpu)) x HEADROOM_EMBED_NUM_THREADS
(default 1), with safe fallbacks.

Closes headroomlabs-ai#198

Signed-off-by: Krishnachaitanyakc <krishnabkc15@gmail.com>
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

PR governance

This PR follows the template and is marked ready for human review.

@github-actions github-actions Bot added status: needs author action Pull request body or readiness checklist still needs author updates status: ready for review Pull request body is complete and the author marked it ready for human review and removed status: needs author action Pull request body or readiness checklist still needs author updates labels Jun 29, 2026

@JerrettDavis JerrettDavis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the CPU embedder cap. The dedicated executor is scoped to CPU, MPS serialization remains intact, env parsing has safe fallbacks, and close tears down the executor. The tests cover both env resolution and the actual worker thread cap. Looks ready from my pass.

@JerrettDavis JerrettDavis merged commit b84afbf into headroomlabs-ai:main Jul 1, 2026
32 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 1, 2026
chopratejas pushed a commit that referenced this pull request Jul 3, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>0.29.0</summary>

##
[0.29.0](v0.28.0...v0.29.0)
(2026-07-03)


### Features

* **proxy:** add --lossless no-CCR mode with format-native compaction
([#1721](#1721))
([c75ebde](c75ebde))
* **stats:** surface Codex WS compression counters in /stats summary
([#1680](#1680))
([2fe19c3](2fe19c3))
* **transforms:** adaptive Otsu KEEP/DROP threshold (+ land relevance
split on main)
([#1726](#1726))
([eea667a](eea667a))


### Bug Fixes

* **bedrock:** fail fast when session-token auth lacks botocore
([#1553](#1553))
([54cfa36](54cfa36))
* **bedrock:** route ARNs via converse, named AWS profiles, and au. re…
([#1456](#1456))
([7d87aa2](7d87aa2))
* **ccr:** honor workspace dir for sqlite store
([#1564](#1564))
([96e1dfe](96e1dfe))
* **claude:** surface Remote Control proxy incompatibility
([#1610](#1610))
([4bf7f92](4bf7f92))
* **cli:** stop advertising unwired compression tuning env vars in
banner
([#1634](#1634))
([d5bf98d](d5bf98d))
* **codex:** avoid duplicate headroom provider config
([#1431](#1431))
([ddd4adf](ddd4adf))
* **compression:** reject lossy unmarked tool output in unit router path
([#1479](#1479))
([de24cd5](de24cd5))
* **cortex-code:** migrate to current Cortex REST API endpoints + add
e2e benchmarks
([#1474](#1474))
([f00ace6](f00ace6))
* **dashboard:** align token savings headline denominator
([#1653](#1653))
([646e705](646e705))
* **dashboard:** derive per-project setup URL from live origin
([#1511](#1511))
([e035aef](e035aef))
* **detection:** contain unidiff panic on orphaned +++ target line
([#1548](#1548))
([e386c09](e386c09))
* **evals:** CJK-aware F1 tokenization + token estimation
([#1527](#1527))
([99a8540](99a8540))
* **install:** close parent log fd in start_detached_agent
([#1576](#1576))
([816cb85](816cb85))
* **install:** use Windows-safe PID liveness probe in runtime_status
([#1544](#1544))
([#1560](#1560))
([6b227b9](6b227b9))
* **learn:** aggregate verbosity baselines across projects instead of
overwriting
([#1288](#1288))
([27a5468](27a5468))
* **mcp:** show lifetime totals and label rolling session scope in
headroom_stats
([#1428](#1428))
([1c0e152](1c0e152))
* **memory:** cap local embedder CPU thread oversubscription
([#198](#198))
([#1559](#1559))
([b84afbf](b84afbf))
* **memory:** singleflight LocalBackend init to stop cold-start races
([#1691](#1691))
([bec47a1](bec47a1))
* **openclaw:** detect uv-installed headroom binary in ~/.local/bin
([#1459](#1459))
([adaeb88](adaeb88))
* **opencode:** preserve custom OpenAI gateway paths
([#1596](#1596))
([c19347c](c19347c))
* **opencode:** route native providers + load transport plugin, fix
Serena context
([#1573](#1573))
([ad0034f](ad0034f))
* preserve anthropic passthrough tool order
([#1427](#1427))
([a932247](a932247))
* **proxy/auth:** match real Anthropic OAuth token prefix (sk-ant-oat)
([#1672](#1672))
([8cddf9b](8cddf9b))
* **proxy:** expose persistent savings metrics
([#1647](#1647))
([5fe4e7b](5fe4e7b))
* **proxy:** fail open when kompress saturation would exhaust
pre-upstream budget
([#1430](#1430))
([15ac650](15ac650))
* **proxy:** handle streaming CCR retrieval
([#1451](#1451))
([d337e3b](d337e3b))
* **proxy:** include system/tools/sampling in cache key
([#1473](#1473))
([312129a](312129a))
* **proxy:** preserve Responses passthrough bytes
([#1598](#1598))
([2a34a82](2a34a82))
* **proxy:** strip Codex lite header on the HTTP /responses path
([#1663](#1663))
([9fbd47b](9fbd47b))
* **proxy:** wire --compression-max-workers /
HEADROOM_COMPRESSION_MAX_WORKERS
([#1632](#1632))
([814ffa3](814ffa3))
* **savings:** count cache-read tokens in input cost estimate
([#1429](#1429))
([72ade37](72ade37))
* skip Magika backend on x86 CPUs without AVX2
([#1162](#1162))
([64783d8](64783d8))
* **transforms/content-router:** route grep/log output away from HTML
extractor
([#1719](#1719))
([0d18ef2](0d18ef2))
* **transforms:** bound native content detection with a Windows watchdog
([#575](#575))
([#1563](#1563))
([95abca3](95abca3))
* Vertex AI support for Claude Code with ANTHROPIC_VERTEX_BASE_URL
([#1393](#1393))
([cff7247](cff7247))
* **wrap:** detach the shared proxy on Windows so it survives an
ungraceful agent close
([#1464](#1464))
([6cba441](6cba441))
* **wrap:** preserve custom Vertex base URL
([#1477](#1477))
([75427bb](75427bb))
* **wrap:** remove rtk instructions from Codex AGENTS.md on unwrap
([#1604](#1604))
([c9d717c](c9d717c))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
JerrettDavis pushed a commit to peterlodri-sec/headroom that referenced this pull request Jul 14, 2026
…labs-ai#198) (headroomlabs-ai#1559)

## Description

The torch/sentence-transformers `LocalEmbedder` ran encodes on the
shared default executor with **no BLAS/OpenMP thread cap**. Under
concurrent load each `encode()` fans out to ~`os.cpu_count()`
BLAS/OpenMP threads, so N in-flight encodes spawn ~`N × cpu_count` OS
threads — oversubscribing the CPU, slowing the `memory_context` stage
and (on smaller boxes) starving the asyncio event loop. The ONNX
embedder already bounds its threads
(`create_cpu_session_options(intra_op_num_threads=1,
inter_op_num_threads=1)`); this brings the torch path to parity.

Supersedes headroomlabs-ai#691 by @oxura — closed only for the open-PR cap, with an
explicit invitation to resubmit; no technical objection was raised, and
its CI was fully green. Credit to @oxura for the original diagnosis and
fix. That PR capped threads by setting BLAS/OpenMP env vars at import
time plus `torch.set_num_threads`; this PR instead runs CPU encodes on a
dedicated, size-limited executor whose workers each pin their thread
pool — which additionally bounds in-flight encode concurrency (the
issue's Fix B/C) and keeps the cap contained to the embedder rather than
mutating process-global env at import.

Closes headroomlabs-ai#198

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)
- [x] Performance improvement

## Changes Made

- CPU encodes now run on a **dedicated, size-limited executor** whose
worker `initializer` pins each worker's torch intra-op pool (and sets
BLAS/OpenMP env defaults). torch's OpenMP thread count is per-thread, so
a one-shot cap misses pooled executor workers — the per-worker
initializer caps every worker deterministically.
- Total embedding threads are bounded by `HEADROOM_EMBED_CONCURRENCY`
(default `min(4, os.cpu_count())`) × `HEADROOM_EMBED_NUM_THREADS`
(default `1`); invalid/non-positive values fall back safely (≥1).
- Mirrors the existing MPS dedicated-single-worker-executor pattern;
CUDA keeps the shared default executor (GPU compute is off-CPU).
`setdefault` never overrides an operator's explicit `OMP_NUM_THREADS`.

## Testing

- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check .`)
- [x] Type checking passes (`mypy headroom`)
- [x] New tests added for new functionality
- [x] Manual testing performed

### Test Output

```text
$ uv run pytest tests/test_memory/test_embedder_thread_cap.py tests/test_memory/test_embedder_mps_serialization.py -q
13 passed

$ uv run pytest tests/test_memory/ tests/test_cli_proxy_embedding_server.py -q
533 passed        # no regressions from the executor change

$ uv run ruff check .  &&  uv run ruff format --check .
All checks passed!   /   1016 files already formatted

$ uv run mypy headroom --ignore-missing-imports
Success: no issues found in 404 source files
```

New `tests/test_memory/test_embedder_thread_cap.py`: env resolution for
both knobs (default / positive / invalid / clamped), worker-init env
application + operator-override safety, and a behavioral test that loads
the real CPU embedder and asserts every executor worker is pinned to the
configured intra-op thread count. Updated
`test_embedder_mps_serialization.py` to the new CPU contract.

## Real Behavior Proof

- Environment: built this branch into a CPU-only Linux container,
removed `onnxruntime` so the proxy falls back to the torch
`LocalEmbedder`; a container has no MPS/CUDA, so it resolves to
`device=cpu` — the deployment where headroomlabs-ai#198 occurs. Python 3.12, torch
2.12.1, `all-MiniLM-L6-v2`, container capped to 4 CPUs, 32 concurrent
clients.
- Exact command / steps: `headroom proxy --host 0.0.0.0 --memory`
in-container; a concurrent `/v1/messages` driver from the host (invalid
key — `memory_context` runs before the upstream call); measured the
`memory_context` stage from `/metrics` before vs after the cap.
- Observed result: the embedder stage this PR targets improved —
`memory_context` avg 73.5 ms → 58.7 ms and max 279 ms → 242 ms (uncapped
12×8 = 96 threads vs fix 4×1): ~20% faster and steadier inside the real
proxy. Isolated component benchmarks (heavy concurrent `embed_batch`;
`LocalBackend.search_memories`) show a larger effect — tail event-loop
stall ~16–24 ms → ~3 ms, and search throughput +57%. Unit/regression: 13
new tests + 533 memory-suite tests pass; `ruff` + `mypy` clean.
- Not tested: the issue's absolute multi-second `/livez` spike. On my
hardware/synthetic load, `/livez` stalls were dominated by the
upstream-connection path (invalid-key DNS/TLS), not the ~250 ms
`memory_context` stage, so I can't attribute the multi-second figure to
the embedder here — the original report was on an 8-core box with real
Claude Code transcripts that drove `memory_context` itself to several
seconds. Linux/CUDA hardware not exercised; no live LLM provider used;
ONNX path unchanged. This PR removes the documented thread
oversubscription and brings the torch path to ONNX parity; it does not
claim to single-handedly resolve the 4 s figure.

Measured `memory_context` stage timing (real containerized proxy, torch
CPU embedder, 4 CPUs, 32 concurrent clients):

| `memory_context` | avg | max |
|---|---|---|
| Before (uncapped, 12×8 = 96 threads) | 73.5 ms | 279 ms |
| After (fix, 4×1) | 58.7 ms | 242 ms |

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Additional Notes

Default-behavior change: CPU encodes use a dedicated bounded pool
instead of the shared default executor (`close()` tears it down). Both
knobs are opt-in overrides with safe defaults. No new dependencies.

Signed-off-by: Krishnachaitanyakc <krishnabkc15@gmail.com>
JerrettDavis pushed a commit to peterlodri-sec/headroom that referenced this pull request Jul 14, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>0.29.0</summary>

##
[0.29.0](headroomlabs-ai/headroom@v0.28.0...v0.29.0)
(2026-07-03)


### Features

* **proxy:** add --lossless no-CCR mode with format-native compaction
([headroomlabs-ai#1721](headroomlabs-ai#1721))
([c75ebde](headroomlabs-ai@c75ebde))
* **stats:** surface Codex WS compression counters in /stats summary
([headroomlabs-ai#1680](headroomlabs-ai#1680))
([2fe19c3](headroomlabs-ai@2fe19c3))
* **transforms:** adaptive Otsu KEEP/DROP threshold (+ land relevance
split on main)
([headroomlabs-ai#1726](headroomlabs-ai#1726))
([eea667a](headroomlabs-ai@eea667a))


### Bug Fixes

* **bedrock:** fail fast when session-token auth lacks botocore
([headroomlabs-ai#1553](headroomlabs-ai#1553))
([54cfa36](headroomlabs-ai@54cfa36))
* **bedrock:** route ARNs via converse, named AWS profiles, and au. re…
([headroomlabs-ai#1456](headroomlabs-ai#1456))
([7d87aa2](headroomlabs-ai@7d87aa2))
* **ccr:** honor workspace dir for sqlite store
([headroomlabs-ai#1564](headroomlabs-ai#1564))
([96e1dfe](headroomlabs-ai@96e1dfe))
* **claude:** surface Remote Control proxy incompatibility
([headroomlabs-ai#1610](headroomlabs-ai#1610))
([4bf7f92](headroomlabs-ai@4bf7f92))
* **cli:** stop advertising unwired compression tuning env vars in
banner
([headroomlabs-ai#1634](headroomlabs-ai#1634))
([d5bf98d](headroomlabs-ai@d5bf98d))
* **codex:** avoid duplicate headroom provider config
([headroomlabs-ai#1431](headroomlabs-ai#1431))
([ddd4adf](headroomlabs-ai@ddd4adf))
* **compression:** reject lossy unmarked tool output in unit router path
([headroomlabs-ai#1479](headroomlabs-ai#1479))
([de24cd5](headroomlabs-ai@de24cd5))
* **cortex-code:** migrate to current Cortex REST API endpoints + add
e2e benchmarks
([headroomlabs-ai#1474](headroomlabs-ai#1474))
([f00ace6](headroomlabs-ai@f00ace6))
* **dashboard:** align token savings headline denominator
([headroomlabs-ai#1653](headroomlabs-ai#1653))
([646e705](headroomlabs-ai@646e705))
* **dashboard:** derive per-project setup URL from live origin
([headroomlabs-ai#1511](headroomlabs-ai#1511))
([e035aef](headroomlabs-ai@e035aef))
* **detection:** contain unidiff panic on orphaned +++ target line
([headroomlabs-ai#1548](headroomlabs-ai#1548))
([e386c09](headroomlabs-ai@e386c09))
* **evals:** CJK-aware F1 tokenization + token estimation
([headroomlabs-ai#1527](headroomlabs-ai#1527))
([99a8540](headroomlabs-ai@99a8540))
* **install:** close parent log fd in start_detached_agent
([headroomlabs-ai#1576](headroomlabs-ai#1576))
([816cb85](headroomlabs-ai@816cb85))
* **install:** use Windows-safe PID liveness probe in runtime_status
([headroomlabs-ai#1544](headroomlabs-ai#1544))
([headroomlabs-ai#1560](headroomlabs-ai#1560))
([6b227b9](headroomlabs-ai@6b227b9))
* **learn:** aggregate verbosity baselines across projects instead of
overwriting
([headroomlabs-ai#1288](headroomlabs-ai#1288))
([27a5468](headroomlabs-ai@27a5468))
* **mcp:** show lifetime totals and label rolling session scope in
headroom_stats
([headroomlabs-ai#1428](headroomlabs-ai#1428))
([1c0e152](headroomlabs-ai@1c0e152))
* **memory:** cap local embedder CPU thread oversubscription
([headroomlabs-ai#198](headroomlabs-ai#198))
([headroomlabs-ai#1559](headroomlabs-ai#1559))
([b84afbf](headroomlabs-ai@b84afbf))
* **memory:** singleflight LocalBackend init to stop cold-start races
([headroomlabs-ai#1691](headroomlabs-ai#1691))
([bec47a1](headroomlabs-ai@bec47a1))
* **openclaw:** detect uv-installed headroom binary in ~/.local/bin
([headroomlabs-ai#1459](headroomlabs-ai#1459))
([adaeb88](headroomlabs-ai@adaeb88))
* **opencode:** preserve custom OpenAI gateway paths
([headroomlabs-ai#1596](headroomlabs-ai#1596))
([c19347c](headroomlabs-ai@c19347c))
* **opencode:** route native providers + load transport plugin, fix
Serena context
([headroomlabs-ai#1573](headroomlabs-ai#1573))
([ad0034f](headroomlabs-ai@ad0034f))
* preserve anthropic passthrough tool order
([headroomlabs-ai#1427](headroomlabs-ai#1427))
([a932247](headroomlabs-ai@a932247))
* **proxy/auth:** match real Anthropic OAuth token prefix (sk-ant-oat)
([headroomlabs-ai#1672](headroomlabs-ai#1672))
([8cddf9b](headroomlabs-ai@8cddf9b))
* **proxy:** expose persistent savings metrics
([headroomlabs-ai#1647](headroomlabs-ai#1647))
([5fe4e7b](headroomlabs-ai@5fe4e7b))
* **proxy:** fail open when kompress saturation would exhaust
pre-upstream budget
([headroomlabs-ai#1430](headroomlabs-ai#1430))
([15ac650](headroomlabs-ai@15ac650))
* **proxy:** handle streaming CCR retrieval
([headroomlabs-ai#1451](headroomlabs-ai#1451))
([d337e3b](headroomlabs-ai@d337e3b))
* **proxy:** include system/tools/sampling in cache key
([headroomlabs-ai#1473](headroomlabs-ai#1473))
([312129a](headroomlabs-ai@312129a))
* **proxy:** preserve Responses passthrough bytes
([headroomlabs-ai#1598](headroomlabs-ai#1598))
([2a34a82](headroomlabs-ai@2a34a82))
* **proxy:** strip Codex lite header on the HTTP /responses path
([headroomlabs-ai#1663](headroomlabs-ai#1663))
([9fbd47b](headroomlabs-ai@9fbd47b))
* **proxy:** wire --compression-max-workers /
HEADROOM_COMPRESSION_MAX_WORKERS
([headroomlabs-ai#1632](headroomlabs-ai#1632))
([814ffa3](headroomlabs-ai@814ffa3))
* **savings:** count cache-read tokens in input cost estimate
([headroomlabs-ai#1429](headroomlabs-ai#1429))
([72ade37](headroomlabs-ai@72ade37))
* skip Magika backend on x86 CPUs without AVX2
([headroomlabs-ai#1162](headroomlabs-ai#1162))
([64783d8](headroomlabs-ai@64783d8))
* **transforms/content-router:** route grep/log output away from HTML
extractor
([headroomlabs-ai#1719](headroomlabs-ai#1719))
([0d18ef2](headroomlabs-ai@0d18ef2))
* **transforms:** bound native content detection with a Windows watchdog
([headroomlabs-ai#575](headroomlabs-ai#575))
([headroomlabs-ai#1563](headroomlabs-ai#1563))
([95abca3](headroomlabs-ai@95abca3))
* Vertex AI support for Claude Code with ANTHROPIC_VERTEX_BASE_URL
([headroomlabs-ai#1393](headroomlabs-ai#1393))
([cff7247](headroomlabs-ai@cff7247))
* **wrap:** detach the shared proxy on Windows so it survives an
ungraceful agent close
([headroomlabs-ai#1464](headroomlabs-ai#1464))
([6cba441](headroomlabs-ai@6cba441))
* **wrap:** preserve custom Vertex base URL
([headroomlabs-ai#1477](headroomlabs-ai#1477))
([75427bb](headroomlabs-ai@75427bb))
* **wrap:** remove rtk instructions from Codex AGENTS.md on unwrap
([headroomlabs-ai#1604](headroomlabs-ai#1604))
([c9d717c](headroomlabs-ai@c9d717c))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: ready for review Pull request body is complete and the author marked it ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Memory embedder oversubscribes BLAS/OMP threads under concurrent load; /livez p99 spikes to 4+s

2 participants