# SESSION_TTL_MS in ego-browser: Understanding Session Caching with 2-Second TTL

> Understand SESSION_TTL_MS in ego-browser. Learn how this 2-second constant optimizes Chrome DevTools Protocol session caching for efficient debugging and development.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: internals
- Published: 2026-08-29

---

**SESSION_TTL_MS is a 2000-millisecond constant that controls how long ego-browser caches Chrome DevTools Protocol (CDP) sessions before requiring re-attachment.**

The `SESSION_TTL_MS` constant in the ego-lite repository governs session lifecycle management for browser automation. This article examines its implementation in [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts), explains the caching mechanism, and shows how the 2-second TTL balances performance against connection reliability.

## What SESSION_TTL_MS Controls

In ego-browser, `SESSION_TTL_MS` is defined as `2000` (2 seconds) and serves as the **time-to-live threshold** for cached CDP sessions. The runtime maintains session state through two properties:

- `state.sessionId` — the active CDP session identifier
- `state.sessionAt` — timestamp when the session was established

The `ensureSession` function checks these values against the TTL before deciding whether to reuse or recreate a session.

## How the TTL Logic Works

The session caching implementation follows a straightforward pattern. When `ensureSession` is called, it evaluates whether the cached session remains valid:

```typescript
// From browser-runtime.ts — core TTL check
if (state.sessionId && Date.now() - state.sessionAt < SESSION_TTL_MS) {
  // Session is fresh; reuse without re-attaching
  return;
}
// TTL expired or no session exists; attach new CDP session

```

This logic appears in [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) approximately at lines 5 (constant definition) and 108 (usage in session validation).

## Why 2 Seconds? Performance vs. Reliability

The **2000 ms value** represents a deliberate engineering trade-off:

- **Shorter TTL** — More frequent re-attachment, higher overhead, but fresher connections
- **Longer TTL** — Better performance, but risk of stale sessions causing CDP errors

Two seconds accommodates typical request/response cycles while preventing session desynchronization in long-running browser tasks.

## Practical Implementation Example

The following pattern shows how application code leverages the cached session mechanism:

```typescript
import { ensureSession, sendCDPMessage } from 'ego-browser';

async function navigateWithCachedSession(url: string) {
  // Triggers TTL check; may reuse existing session
  await ensureSession();
  
  // Execute CDP command on validated session
  await sendCDPMessage('Page.navigate', { url });
  
  // Subsequent calls within 2 seconds reuse same session
  await sendCDPMessage('Runtime.evaluate', {
    expression: 'document.title'
  });
}

```

The second CDP call benefits from zero session overhead if executed within the TTL window.

## Testing TTL Behavior

The test suite in `browser-runtime.test.mjs` validates both caching and expiration scenarios:

```typescript
test('returns cached session within TTL', async () => {
  await ensureSession();
  const cachedAt = state.sessionAt;
  
  // 500ms delay — well within 2000ms TTL
  await delay(500);
  await ensureSession();
  
  // Same timestamp confirms cache hit
  assert.strictEqual(state.sessionAt, cachedAt);
});

test('re-attaches after TTL expiration', async () => {
  await ensureSession();
  
  // Force expiration by backdating sessionAt
  state.sessionAt = Date.now() - 3000; // 3 seconds ago
  
  const beforeReattach = state.sessionAt;
  await ensureSession();
  
  // New timestamp proves re-attachment occurred
  assert.notStrictEqual(state.sessionAt, beforeReattach);
});

```

These tests exercise the boundary conditions at `SESSION_TTL_MS / 2` and `SESSION_TTL_MS * 1.5` to ensure correct behavior.

## Source File Reference

| File | Purpose | Key Lines |
|------|---------|-----------|
| [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) | TTL constant and `ensureSession` implementation | [L5, L108](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) |
| `package/ego-browser/src/browser-runtime.test.mjs` | Unit tests for session caching logic | [Full test suite](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.test.mjs) |
| [`package/ego-browser/src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/state.ts) | Mutable runtime state (`sessionId`, `sessionAt`) | [State definitions](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/state.ts) |

## Customizing SESSION_TTL_MS

For applications with different latency requirements, modify the constant in [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts):

```typescript
// For high-frequency operations: extend TTL to 5000ms
export const SESSION_TTL_MS = 5000;

// For critical stability: reduce TTL to 500ms
export const SESSION_TTL_MS = 500;

```

Changes require rebuilding the `ego-browser` package. Consider environment-based configuration for deployment flexibility.

## Summary

- **SESSION_TTL_MS = 2000ms** defines the maximum age of reusable CDP sessions in ego-browser
- **Cached sessions** avoid re-attachment overhead when `Date.now() - sessionAt < 2000`
- **Automatic re-attachment** occurs when the TTL expires, ensuring connection health
- **Implementation** spans [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts) (logic), [`state.ts`](https://github.com/citrolabs/ego-lite/blob/main/state.ts) (storage), and `browser-runtime.test.mjs` (validation)

## Frequently Asked Questions

### What happens if SESSION_TTL_MS is set to zero?

Setting `SESSION_TTL_MS = 0` forces re-attachment on every `ensureSession` call. This eliminates caching entirely, increasing CDP overhead but guaranteeing fresh sessions. Use this configuration only when debugging persistent session corruption issues.

### Can multiple concurrent calls race during session re-attachment?

The implementation synchronizes through `state` mutation. While `ensureSession` itself may execute concurrently, the session identifier and timestamp updates occur atomically within the runtime state object. The test suite includes concurrent invocation scenarios to verify consistency.

### Why not use a longer TTL like 30 seconds?

Longer TTLs risk `Session detached` errors when the underlying browser process terminates sessions unexpectedly. The 2-second default reflects empirical testing against Chrome/Chromium stability patterns. Production workloads experiencing frequent re-attachment may benefit from TTL extension combined with health-check polling.