# How the Headroom TransformPipeline Manages Sequential Compression

> Discover how Headroom's TransformPipeline manages sequential compression, executing transforms on the proxy and returning applied results to the client SDK.

- Repository: [Tejas Chopra/headroom](https://github.com/chopratejas/headroom)
- Tags: internals
- Published: 2026-06-07

---

**Headroom’s TransformPipeline executes compression transforms sequentially on the proxy server, returning an ordered list of applied transforms to the client SDK through `CompressResult.transformsApplied` and post-compress hooks.**

The `chopratejas/headroom` repository implements a sophisticated compression system where the **TransformPipeline** orchestrates multiple compression strategies in a deterministic order. Unlike client-side processing, this pipeline runs entirely on the Headroom proxy, ensuring consistent behavior across different SDK implementations while maintaining full observability of the sequential compression steps.

## Request Flow: From SDK to Proxy

The compression workflow begins in the TypeScript SDK and delegates heavy processing to the Headroom proxy.

### Building the CompressContext

In [`sdk/typescript/src/compress.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/compress.ts), the high-level `compress` function initializes the process by constructing a `CompressContext`. This function detects the input format, converts messages to the OpenAI format, and invokes `HeadroomClient.compress` to communicate with the proxy. Before sending the request, the SDK executes any registered `preCompress` hooks, allowing users to inspect or modify the payload before it enters the transform pipeline.

### Sequential Execution on the Proxy

Once the request reaches the Headroom proxy, the actual **TransformPipeline** takes over. The proxy receives the request body containing `messages`, `model`, and optional parameters like `token_budget`. Each registered transform—such as `smart_crusher` or `cache_aligner`—executes in the order defined by the proxy configuration. The pipeline operates sequentially: the output of one transform becomes the input of the next, creating a deterministic processing chain that ensures predictable compression behavior.

## Result Propagation and Transform Tracking

After pipeline execution completes, the results flow back to the client with full metadata about the transforms applied.

### Mapping Proxy Responses in the SDK

The low-level `_doCompress` method in [`sdk/typescript/src/client.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/client.ts) parses the proxy's JSON response, specifically extracting the `transforms_applied` field. This ordered array maps directly to the SDK's `CompressResult.transformsApplied` property, preserving the exact execution sequence from the server. This mapping ensures that clients receive an accurate, ordered record of which compression strategies were utilized.

### Post-Compress Hooks and Observability

Back in [`sdk/typescript/src/compress.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/compress.ts), the SDK constructs a `CompressEvent` containing the `transformsApplied` array and passes it to any registered `postCompress` hooks. This design allows callers to observe the specific sequence of transforms executed by the pipeline, enabling debugging, analytics, and conditional logic based on which compression steps were applied.

## Code Examples

The following examples demonstrate how to inspect the sequential transform pipeline in your application.

### Inspecting Applied Transforms

Access the ordered list of transforms through the `transformsApplied` property:

```typescript
import { compress } from "headroom";

const messages = [
  { role: "user", content: "Explain quantum computing in 200 words." },
];

const result = await compress(messages, { model: "gpt-4o" });

console.log("Compressed messages:", result.messages);
console.log("Transforms applied (in order):", result.transformsApplied);

```

*Example output:*

```

Compressed messages: [{ role: "user", content: "Explain quantum computing…" }]
Transforms applied (in order): ["smart_crusher"]

```

### Logging Transforms with Hooks

Use post-compress hooks to monitor pipeline execution:

```typescript
import { compress } from "headroom";

await compress(messages, {
  model: "gpt-4o",
  hooks: {
    async postCompress(event) {
      console.log(
        `Compression used ${event.transformsApplied.length} transforms:`,
        event.transformsApplied.join(", ")
      );
    },
  },
});

```

### Simulating Compression Without LLM Calls

Test the pipeline behavior without making actual API calls:

```typescript
import { HeadroomClient } from "headroom";

const client = new HeadroomClient();
const sim = await client.chat.completions.simulate({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Summarize this text." }],
});

console.log("Simulated transforms:", sim.transformsApplied);

```

## Key Implementation Files

Understanding the **TransformPipeline** requires familiarity with these source files in the `chopratejas/headroom` repository:

- [`sdk/typescript/src/compress.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/compress.ts) – High-level `compress` function that orchestrates hooks, format detection, and proxy communication.
- [`sdk/typescript/src/client.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/client.ts) – Low-level HTTP client containing `_doCompress` which parses `transforms_applied` from proxy responses.
- [`sdk/typescript/src/types.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/types.ts) – TypeScript definitions for `CompressResult` and the `transformsApplied` field.
- [`sdk/typescript/src/hooks.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/hooks.ts) – Interface definitions for `preCompress` and `postCompress` hooks that expose transform metadata.

## Summary

- The **TransformPipeline** executes sequentially on the Headroom proxy, not the client, ensuring consistent compression across platforms.
- In [`sdk/typescript/src/compress.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/compress.ts), the `compress` function builds a `CompressContext` and delegates to `HeadroomClient.compress`.
- The proxy processes transforms in order, with each transform's output feeding into the next transform's input.
- Results return to the SDK via `_doCompress` in [`sdk/typescript/src/client.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/client.ts), mapping `transforms_applied` to `transformsApplied`.
- Post-compress hooks receive a `CompressEvent` containing the ordered transform list for observability and debugging.

## Frequently Asked Questions

### Where does the TransformPipeline actually run?

The **TransformPipeline** runs entirely on the Headroom proxy server. The client-side SDK forwards the request to the proxy, which executes all registered transforms sequentially before returning the compressed result and metadata to the client.

### How can I see which transforms were applied to my request?

The `compress` function returns a `CompressResult` object with a `transformsApplied` property containing an ordered array of transform identifiers. Alternatively, implement a `postCompress` hook to receive a `CompressEvent` with the same transform list for logging or analytics purposes.

### What determines the order of transform execution?

The execution order is defined by the proxy configuration. Transforms run sequentially in the order they are registered, with each transform receiving the output of the previous transform as its input, creating a deterministic processing chain.

### Can I modify the transform pipeline from the client SDK?

No. The **TransformPipeline** configuration and execution logic reside on the proxy server. The client SDK only forwards requests and receives results; it cannot alter which transforms run or their execution order. Configuration changes must be made on the proxy side.