From 6d043674c2dae3b09c0c6ad58ef9aa4306ad9025 Mon Sep 17 00:00:00 2001 From: Markus Hartung Date: Thu, 20 Aug 2026 20:34:19 -0300 Subject: [PATCH] fix: skip expensive RTK compression stats computation on no-op runs (#10765) --- .../10765-rtk-unconditional-stats-cpu.md | 1 + .../services/compression/engines/rtk/index.ts | 12 +++++++ tests/unit/compression/rtk-engine.test.ts | 3 +- tests/unit/probe-10765-rtk-noop-stats.test.ts | 32 +++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 changelog.d/fixes/10765-rtk-unconditional-stats-cpu.md create mode 100644 tests/unit/probe-10765-rtk-noop-stats.test.ts diff --git a/changelog.d/fixes/10765-rtk-unconditional-stats-cpu.md b/changelog.d/fixes/10765-rtk-unconditional-stats-cpu.md new file mode 100644 index 0000000000..ff36462d47 --- /dev/null +++ b/changelog.d/fixes/10765-rtk-unconditional-stats-cpu.md @@ -0,0 +1 @@ +- fix(compression): skip the expensive `createCompressionStats()` pass in RTK when no message was actually compressed, matching every sibling stacked engine (#10765) diff --git a/open-sse/services/compression/engines/rtk/index.ts b/open-sse/services/compression/engines/rtk/index.ts index 33b6c90b59..b3791bfc54 100644 --- a/open-sse/services/compression/engines/rtk/index.ts +++ b/open-sse/services/compression/engines/rtk/index.ts @@ -656,6 +656,18 @@ export function applyRtkCompression( }; }); + // Mirror the sibling stacked engines (headroom, session-dedup, ccr, relevance, + // ionizer, readLifecycle): skip the expensive createCompressionStats() pass + // (full JSON.stringify + tokenizer over the whole body, twice) when nothing + // actually changed. Untouched messages keep their original reference above, + // so a reference-identity scan is enough to detect the no-op case (#10765). + const anyMessageChanged = compressedMessages.some( + (message, index) => message !== messages[index] + ); + if (!anyMessageChanged) { + return { body, compressed: false, stats: null }; + } + const compressedBody = { ...adapter.body, messages: compressedMessages }; const stats = createCompressionStats( adapter.body, diff --git a/tests/unit/compression/rtk-engine.test.ts b/tests/unit/compression/rtk-engine.test.ts index 7406f53634..4741ddb6e6 100644 --- a/tests/unit/compression/rtk-engine.test.ts +++ b/tests/unit/compression/rtk-engine.test.ts @@ -70,7 +70,8 @@ describe("RTK compression engine", () => { assert.equal(rtkEngine.validateConfig({ intensity: "invalid" }).valid, false); assert.equal(rtkEngine.validateConfig({ rawOutputRetention: "always" }).valid, true); - const body = { messages: [{ role: "tool", content: "same\nsame\nsame\nsame" }] }; + const repeated = Array.from({ length: 20 }, () => "same").join("\n"); + const body = { messages: [{ role: "tool", content: repeated }] }; assert.equal( rtkEngine.apply(body, { config: { rtkConfig: { enabled: true } } }).stats?.engine, "rtk" diff --git a/tests/unit/probe-10765-rtk-noop-stats.test.ts b/tests/unit/probe-10765-rtk-noop-stats.test.ts new file mode 100644 index 0000000000..2826af2a71 --- /dev/null +++ b/tests/unit/probe-10765-rtk-noop-stats.test.ts @@ -0,0 +1,32 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { applyRtkCompression } from "../../open-sse/services/compression/engines/rtk/index.ts"; + +// Issue #10765: enabling RTK causes ~100% CPU even when the engine finds nothing to +// compress ("It also occurs when the engine does not modify the request and reports +// no token savings."). Root cause: applyRtkCompression() unconditionally calls +// createCompressionStats() at the end of the function — which does a full +// JSON.stringify() (+ tiktoken tokenize for Codex bodies) of the ENTIRE request body, +// TWICE (original + compressed) — even when zero messages were touched. +// +// Every sibling stacked engine (headroom, session-dedup, ccr, relevance, ionizer, +// readLifecycle) returns `stats: null` early when nothing changed, skipping this +// expensive computation entirely. RTK is the outlier: it always pays the cost. +test("RTK no-op run should skip the expensive stats computation (like sibling engines)", () => { + const body = { + model: "codex/gpt-5", + provider: "codex", + messages: [ + { role: "user", content: "hello, this is a simple message with nothing to compress" }, + ], + }; + + const result = applyRtkCompression(body, { config: { enabled: true } }); + + assert.equal(result.compressed, false, "RTK made no changes"); + assert.equal( + result.stats, + null, + "RTK should return stats: null on a no-op run, like every sibling stacked engine" + ); +});