# WebSocket Performance Limits in law-chain-hot/websocket-devtools: Complete Guide to MAX_MESSAGES_PER_CONNECTION and Memory Safeguards

> Discover WebSocket performance limits in law-chain-hot/websocket-devtools, including MAX_MESSAGES_PER_CONNECTION. Learn how these limits prevent memory exhaustion and ensure UI responsiveness during heavy traffic.

- Repository: [Brian 阿布/websocket-devtools](https://github.com/law-chain-hot/websocket-devtools)
- Tags: deep-dive
- Published: 2026-03-05

---

**The law-chain-hot/websocket-devtools extension enforces strict WebSocket performance limits—including a 5,000 message cap per connection and 20,000 total messages across all connections—to prevent browser memory exhaustion and maintain DevTools UI responsiveness under heavy traffic.**

The **websocket-devtools** browser extension monitors WebSocket traffic in real-time, but high-frequency applications can generate millions of messages. To keep the DevTools panel responsive, the codebase implements hard ceilings on message storage, deduplication sets, and binary payload processing. These WebSocket performance limits are defined as constants in the source code and enforced through automatic truncation logic.

## Hard Limits Defined in the Source Code

The extension defines six primary performance boundaries across three core files. These constants prevent memory leaks and UI lag when debugging applications with high message throughput.

### Per-Connection Message Cap (MAX_MESSAGES_PER_CONNECTION)

In [`src/devtools/panel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/devtools/panel.jsx) at line 17, the extension sets **MAX_MESSAGES_PER_CONNECTION** to `5000`. This limit restricts how many events the panel retains for any single WebSocket connection. When a specific connection exceeds this threshold, the oldest messages are automatically discarded to make room for new entries.

### Global Message Pool (MAX_TOTAL_MESSAGES)

Also in [`src/devtools/panel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/devtools/panel.jsx) at line 18, **MAX_TOTAL_MESSAGES** is set to `20000`. This represents the absolute upper bound of events stored across all active connections combined. The panel uses this ceiling to ensure the total memory footprint remains bounded regardless of how many WebSocket connections are being monitored simultaneously.

### Deduplication Safeguards (MAX_PROCESSED_IDS)

At line 19 of [`src/devtools/panel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/devtools/panel.jsx), the code defines **MAX_PROCESSED_IDS** as `50000`. This governs the size of the `Set` used to track incoming message IDs for deduplication purposes. Once the set grows beyond this limit, the extension purges the oldest half of the IDs to prevent unbounded growth of the deduplication cache.

### UI Animation Limits (MAX_HIGHLIGHTED_MESSAGES)

The hook in [`src/hooks/useNewMessageHighlight.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/hooks/useNewMessageHighlight.js) at line 4 sets **MAX_HIGHLIGHTED_MESSAGES** to `50`. This caps how many recent messages can simultaneously display the "new message" highlight animation. Excess highlights are pruned automatically to prevent DOM performance degradation.

### Binary Payload Truncation (MAX_PREVIEW_SIZE)

In [`src/content/injected.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/content/injected.js) at line 28, **MAX_PREVIEW_SIZE** is defined as `100` KB (100,000 bytes). When a binary WebSocket payload exceeds this size, the extension truncates the data before attempting Protobuf decoding, displaying a warning to the user rather than processing the entire buffer.

### Batch Processing Thresholds

Lines 99–100 of [`src/content/injected.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/content/injected.js) define two throughput-tuning constants:
- **BATCH_SIZE_THRESHOLD** = `65` (events)
- **BATCH_TIME_THRESHOLD** = `70` ms

These control how many incoming events are grouped together before being sent to the DevTools panel, reducing `postMessage` overhead while maintaining acceptable latency.

## How Limits Are Enforced in Practice

The extension applies these caps through specific truncation algorithms in the message processing pipeline.

### Trimming Message History in panel.jsx

When new events arrive, the panel appends them to the `websocketEvents` array. If the resulting collection exceeds `MAX_TOTAL_MESSAGES`, the code slices the array to retain only the newest entries:

```javascript
// src/devtools/panel.jsx (simplified)
setWebsocketEvents(prev => {
  const newEvents = [...prev, ...validEvents];
  // Drop oldest entries once we exceed the total-message limit
  return newEvents.length > MAX_TOTAL_MESSAGES
    ? newEvents.slice(-MAX_TOTAL_MESSAGES)
    : newEvents;
});

```

The same `slice(-MAX_MESSAGES_PER_CONNECTION)` logic applies per-connection to enforce the individual connection limit.

### Managing Deduplication ID Sets

The deduplication mechanism stores message IDs in a React ref (`processedMessageIds`). When the set size exceeds `MAX_PROCESSED_IDS`, the extension retains only the newest half:

```javascript
// src/devtools/panel.jsx (simplified)
if (processedMessageIds.current.size > MAX_PROCESSED_IDS) {
  const idsArray = Array.from(processedMessageIds.current);
  // Keep the newest half of the IDs
  processedMessageIds.current = new Set(
    idsArray.slice(-MAX_PROCESSED_IDS / 2)
  );
}

```

This aggressive pruning ensures the deduplication cache never grows beyond 50,000 entries.

### Highlight Animation Capping

The `useNewMessageHighlight` hook automatically expires old highlights when the map exceeds 50 entries:

```javascript
// src/hooks/useNewMessageHighlight.js (simplified)
if (updated.size > MAX_HIGHLIGHTED_MESSAGES) {
  // Keep only the newest N highlights
  const entries = Array.from(updated.entries())
    .sort((a, b) => a[1] - b[1])               // oldest first
    .slice(-MAX_HIGHLIGHTED_MESSAGES);        // retain newest
  return new Map(entries);
}

```

### Large Binary Payload Handling

For binary messages exceeding 100 KB, the injected script truncates the payload before decoding:

```javascript
// src/content/injected.js (simplified)
if (size > MAX_PREVIEW_SIZE) {
  // Show only the first MAX_PREVIEW_SIZE bytes
  const truncated = data.subarray(0, MAX_PREVIEW_SIZE);
  const decodeResult = tryDecodeAsProtobuf(truncated);
  return {
    isProtobuf: true,
    protobufDecoded: {
      warning: `Data truncated (${size} bytes) – showing first ${MAX_PREVIEW_SIZE} bytes`,
      partialDecode: decodeResult.decoded,
    },
    protobufRaw: decodeResult.raw + ` … [truncated]`,
    protobufError: decodeResult.error,
  };
}

```

## Summary

- **MAX_MESSAGES_PER_CONNECTION** (`5000`) restricts individual connection history in [`src/devtools/panel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/devtools/panel.jsx) to prevent single connections from dominating memory.
- **MAX_TOTAL_MESSAGES** (`20000`) provides a global ceiling across all connections, enforced via array slicing.
- **MAX_PROCESSED_IDS** (`50000`) bounds the deduplication set; the extension purges the oldest 50% when the limit is breached.
- **MAX_HIGHLIGHTED_MESSAGES** (`50`) limits simultaneous highlight animations to maintain DOM performance.
- **MAX_PREVIEW_SIZE** (`100` KB) truncates large binary payloads before Protobuf decoding to avoid freezing the UI.
- **Batch thresholds** (`65` events or `70` ms) optimize throughput in [`src/content/injected.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/content/injected.js) by grouping rapid-fire events.

## Frequently Asked Questions

### What happens when MAX_MESSAGES_PER_CONNECTION is reached?

When a single connection accumulates 5,000 messages, the extension automatically discards the oldest entries to maintain the cap. The `setWebsocketEvents` updater in [`src/devtools/panel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/devtools/panel.jsx) uses `slice(-MAX_MESSAGES_PER_CONNECTION)` to retain only the newest 5,000 events, ensuring the UI remains responsive while preserving recent context.

### Why does the extension limit binary payload previews to 100 KB?

The **MAX_PREVIEW_SIZE** constant prevents the Protobuf decoder from freezing the browser when handling massive binary frames. As implemented in [`src/content/injected.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/content/injected.js), payloads larger than 100 KB are truncated before decoding, and the user sees a warning indicating the data has been partially displayed.

### How does the deduplication system prevent memory leaks?

The extension tracks processed message IDs in a `Set` that cannot exceed **MAX_PROCESSED_IDS** (50,000). When this limit is reached, the code in [`src/devtools/panel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/devtools/panel.jsx) converts the set to an array, slices the newest 25,000 IDs, and reconstructs the set, effectively garbage-collecting the oldest 50% of tracked IDs.

### Are these WebSocket performance limits configurable by users?

No. According to the source code in law-chain-hot/websocket-devtools, these limits are hardcoded as constants in the source files. Users cannot adjust **MAX_MESSAGES_PER_CONNECTION**, **MAX_TOTAL_MESSAGES**, or other thresholds through the extension settings; they must modify the source code and rebuild the extension to change these values.