# Event Queue Buffer Capacity and Overflow Handling in ego-browser

> Discover ego-browser's event queue buffer capacity of 10,000 events. Learn how overflow is handled by discarding old entries to prevent memory issues.

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

---

**The `ego-browser` event queue buffers up to 10,000 CDP events and handles overflow by discarding the oldest entries to prevent unbounded memory growth.**

The `ego-browser` package, maintained in the `citrolabs/ego-lite` repository, provides a lightweight runtime for Chrome DevTools Protocol (CDP) automation. Understanding its internal buffering behavior is essential for building reliable automation scripts that consume browser events without risking memory exhaustion or data loss.

## Where the Buffer Capacity Is Defined

The event queue capacity is controlled by the **`MAX_BUFFERED_EVENTS`** constant in [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts):

```ts
// package/ego-browser/src/browser-runtime.ts (lines 6-9)
const MAX_BUFFERED_EVENTS = 10000;

```

This single constant determines the hard limit for the internal FIFO queue that stores CDP events received from the browser runtime.

## How Overflow Handling Works

When the browser runtime receives a new CDP message, the `handleMessage` function processes it according to the following logic found in [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts) (lines 86-90):

```ts
events.push(data);
if (events.length > MAX_BUFFERED_EVENTS) {
  // Drop the oldest entries so that the queue never exceeds its cap.
  events.splice(0, events.length - MAX_BUFFERED_EVENTS);
}

```

The overflow strategy operates in three steps:

1. **Push incoming event** — New CDP events are appended to the `events` array
2. **Check capacity** — The runtime immediately verifies if the array exceeds 10,000 items
3. **Trim oldest entries** — `splice(0, events.length - MAX_BUFFERED_EVENTS)` removes surplus events from the front of the queue

This approach guarantees **bounded memory usage** while preserving the most recent 10,000 events for downstream consumers.

## Practical Code Examples

### Reading Buffered Events

To retrieve and clear the current event queue without risking overflow side effects:

```ts
import { drainBrowserEvents } from "ego-browser";

// Retrieve and clear the current event queue.
const recentEvents = drainBrowserEvents();
console.log(`Got ${recentEvents.length} CDP events`);

```

The `drainBrowserEvents` helper empties the buffer entirely, giving you direct control over memory management.

### Subscribing to Specific Events

For production automation, prefer targeted subscriptions that bypass the buffer entirely:

```ts
import { subscribeBrowserEvent } from "ego-browser";

const unsubscribe = subscribeBrowserEvent(
  "Network.responseReceived",
  undefined,                // no session filter
  (event) => console.log(event)   // handle the event
);

// Later, when you no longer need the listener:
unsubscribe();

```

**`subscribeBrowserEvent`** delivers events directly to your callback without queuing, eliminating overflow concerns for high-frequency CDP domains.

### Waiting for Specific Events with Timeout

To consume events while respecting the bounded queue:

```ts
import { waitForBrowserEvent } from "ego-browser";

// Wait for a particular event while the internal queue stays bounded.
await waitForBrowserEvent(
  (e) => e.method === "Page.loadEventFired",
  5000 // timeout in ms
);

```

The `waitForBrowserEvent` helper polls the buffer efficiently and respects the same 10,000-event window.

## Key Source Files

Understanding the event queue buffer capacity requires familiarity with these files in the `ego-browser` package:

| File | Purpose |
|------|---------|
| [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts) | Defines `MAX_BUFFERED_EVENTS`, implements `handleMessage`, and contains the overflow trimming logic |
| [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) | Holds the singleton runtime state used by the event system |
| [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) | Exposes public APIs: `drainBrowserEvents`, `subscribeBrowserEvent`, `waitForBrowserEvent` |
| `src/browser-runtime.test.mjs` | Test coverage verifying queuing behavior and overflow edge cases |

## Summary

- **Capacity**: 10,000 events maximum, defined by `MAX_BUFFERED_EVENTS` in [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts)
- **Overflow behavior**: Oldest events discarded via `splice` when capacity exceeded
- **Memory safety**: Bounded growth prevents runtime memory exhaustion
- **Best practice**: Use `subscribeBrowserEvent` for production code to avoid buffer dependency

## Frequently Asked Questions

### What happens to events when the buffer is full?

The oldest events are permanently removed. When `events.length` exceeds 10,000, `splice(0, events.length - MAX_BUFFERED_EVENTS)` trims surplus entries from the front of the array. Only the 10,000 most recent events are retained.

### Can I increase the event queue buffer capacity?

The `MAX_BUFFERED_EVENTS` constant is hardcoded at 10,000 in [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts). There is no runtime configuration option. To process more events, use `subscribeBrowserEvent` for direct delivery or implement external buffering in your application code.

### How do I avoid losing events to buffer overflow?

Subscribe to specific CDP events using **`subscribeBrowserEvent`** instead of draining the general queue. This method registers direct listeners that receive events immediately without the 10,000-item buffer limitation.