# How to Configure CCR TTL and Storage for Reversible Compression in Headroom

> Learn to configure CCR TTL and storage for reversible compression in Headroom. Set store_ttl_seconds and store_max_entries using environment variables or programmatically.

- Repository: [Tejas Chopra/headroom](https://github.com/chopratejas/headroom)
- Tags: how-to-guide
- Published: 2026-06-14

---

**Configure CCR TTL and storage in Headroom by setting `store_ttl_seconds` and `store_max_entries` in `CCRConfig`, either via environment variables (`HEADROOM_CCR_TTL_SECONDS`, `HEADROOM_CCR_STORE_MAX_ENTRIES`) or programmatically when constructing your `HeadroomConfig`.**

Headroom’s reversible compression feature relies on the Compress-Cache-Retrieve (CCR) architecture to preserve original payloads after compression. To configure CCR TTL and storage for reversible compression in Headroom effectively, you must tune the `CCRConfig` class—defined in [`headroom/config.py`](https://github.com/chopratejas/headroom/blob/main/headroom/config.py)—to balance latency, memory usage, and data durability. The CCR store acts as a key-value cache where compressed content is hashed and stored, allowing the LLM to retrieve full payloads later via the `headroom_retrieve` tool.

## Understanding the CCR Architecture

The CCR (Compress-Cache-Retrieve) architecture powers Headroom’s reversible compression through a simple but robust storage layer. When a transform such as `SmartCrusher` (implemented in [`headroom/transforms/smart_crusher.py`](https://github.com/chopratejas/headroom/blob/main/headroom/transforms/smart_crusher.py)) compresses a large payload, the original data is written to a CCR store keyed by a unique hash. The LLM can subsequently request the full content using the `headroom_retrieve` tool, provided the entry has not exceeded its TTL.

The underlying storage is handled by the `CompressionStore` class in [`headroom/transforms/compression_store.py`](https://github.com/chopratejas/headroom/blob/main/headroom/transforms/compression_store.py), which supports both in-memory and persistent backends.

## Configuring CCR TTL Settings

The time-to-live (TTL) determines how long compressed data remains retrievable before automatic expiration.

### Default TTL Behavior

By default, `store_ttl_seconds` is set to `300` seconds (5 minutes). The `CompressionStore` records the timestamp when each entry is added, and a background cleanup routine purges entries whose age exceeds this threshold. Once expired, the store returns an "Entry not found or expired" error, prompting the LLM to regenerate the original data rather than retrying the fetch.

### Adjusting TTL via Environment Variables

For runtime configuration, set the `HEADROOM_CCR_TTL_SECONDS` environment variable before launching the Headroom proxy:

```bash
export HEADROOM_CCR_TTL_SECONDS=7200  # 2 hours

export HEADROOM_CCR_STORE_MAX_ENTRIES=5000
headroom serve

```

### Programmatic TTL Configuration

To configure CCR settings within your application, instantiate `CCRConfig` and pass it to `HeadroomConfig`:

**Python:**

```python
from headroom.config import HeadroomConfig, CCRConfig

# Configure CCR with 2-hour TTL and increased capacity

ccr_cfg = CCRConfig(
    store_ttl_seconds=7200,
    store_max_entries=5000,
    inject_retrieval_marker=True
)

cfg = HeadroomConfig(ccr=ccr_cfg)
client = HeadroomClient(cfg)

```

**TypeScript:**

```typescript
import { HeadroomConfig, CCRConfig } from "headroom-ai";

const cfg: HeadroomConfig = {
  ccr: {
    store_ttl_seconds: 7200,   // 2 hours
    store_max_entries: 5000,
    inject_retrieval_marker: true,
  },
};

```

## Managing CCR Storage Limits

Control memory consumption using `store_max_entries`, which defaults to `1000` entries. When the store reaches this limit, new compressed payloads may evict older entries depending on the specific backend implementation. Configure this via the `HEADROOM_CCR_STORE_MAX_ENTRIES` environment variable or programmatically through `CCRConfig` as shown above.

## Advanced CCR Configuration Options

Beyond TTL and storage size, `CCRConfig` exposes several behavioral flags that control how the CCR system interacts with the LLM:

- **`inject_retrieval_marker`**: Default `True`. When enabled, compressed output includes a marker string (e.g., `"[… Retrieve more: hash=abc123. Expires in 5m.]"`). Set to `False` to omit these markers.
- **`inject_tool`**: Default `True`. Automatically injects the `headroom_retrieve` tool definition into the LLM’s available tool list.
- **`feedback_enabled`**: Default `True`. Logs retrieval events back to the learning component (TOIN) for future compression-policy tuning.

These settings are processed in [`headroom/transforms/smart_crusher.py`](https://github.com/chopratejas/headroom/blob/main/headroom/transforms/smart_crusher.py) and [`headroom/transforms/content_router.py`](https://github.com/chopratejas/headroom/blob/main/headroom/transforms/content_router.py) during the compression and routing phases.

## Storage Backend Configuration

By default, the CCR store resides in the proxy process’s memory, providing fast access but volatile durability. For production deployments requiring persistence across restarts, configure a SQLite backend via the `store_url` field in `HeadroomConfig`:

```python
from headroom.config import HeadroomConfig, CCRConfig

ccr_cfg = CCRConfig(store_ttl_seconds=7200)
cfg = HeadroomConfig(
    ccr=ccr_cfg,
    store_url="sqlite:///headroom.db"
)

```

The TTL expiration logic remains consistent regardless of whether you use the in-memory `CompressionStore` or a persistent SQLite backend.

## Retrieval Flow and TTL Expiration

When the LLM encounters a compression marker, it initiates a tool call to `headroom_retrieve` with the hash argument:

```json
{
  "tool_call_id": "toolu_ccr_001",
  "name": "headroom_retrieve",
  "arguments": {
    "hash": "abc123def456",
    "query": null
  }
}

```

If the entry exists and is within its TTL window, the proxy returns the original JSON payload. If the entry has expired or been evicted, the proxy returns an explicit error, forcing the LLM to re-run the original command rather than attempting stale data retrieval.

## Summary

- **Set CCR TTL** using `store_ttl_seconds` (default 300 seconds) via the `HEADROOM_CCR_TTL_SECONDS` environment variable or programmatic `CCRConfig`.
- **Control storage capacity** with `store_max_entries` (default 1000) via `HEADROOM_CCR_STORE_MAX_ENTRIES` or code-level configuration.
- **Enable persistence** by setting `store_url` in `HeadroomConfig` to a SQLite database path (e.g., `sqlite:///headroom.db`).
- **Tune behavior** using `inject_retrieval_marker`, `inject_tool`, and `feedback_enabled` to match your LLM integration requirements.
- **Handle expiration gracefully**: Expired entries return explicit errors, ensuring the LLM regenerates data rather than consuming stale compressed content.

## Frequently Asked Questions

### What is the default CCR TTL in Headroom?

The default `store_ttl_seconds` is **300 seconds** (5 minutes), defined in [`headroom/config.py`](https://github.com/chopratejas/headroom/blob/main/headroom/config.py). After this period, entries are automatically purged from the `CompressionStore` in [`headroom/transforms/compression_store.py`](https://github.com/chopratejas/headroom/blob/main/headroom/transforms/compression_store.py).

### How do I make CCR storage persistent across restarts?

Set the `store_url` field in `HeadroomConfig` to a SQLite database path (e.g., `sqlite:///headroom.db`). This persists the CCR store to disk while maintaining the same TTL expiration logic regardless of backend type.

### What happens when the CCR store reaches its entry limit?

When the store reaches `store_max_entries` (default 1000), new compressed payloads may trigger eviction of older entries depending on the specific `CompressionStore` implementation. Monitor entry counts in production to avoid premature eviction of frequently accessed data.

### Can I disable the retrieval marker in compressed output?

Yes. Set `inject_retrieval_marker` to `False` in `CCRConfig`. This omits the marker string (e.g., `"[… Retrieve more: hash=abc123...]"`) from compressed responses, though you must ensure the LLM knows how to construct `headroom_retrieve` calls independently.