AI & Agents

WebSocket Message Size Limits: RFC 6455 Framing, Browser Buffers, and Agent Streaming

While the WebSocket specification (RFC 6455) theoretically permits message frames up to 9 exabytes, real-world WebSocket implementations enforce message size limits between 128 KB and 100 MB to prevent socket buffer exhaustion and Denial of Service. This guide breaks down frame header encoding, server runtime defaults, browser buffer backpressure, and how autonomous agent systems offload large file transfers to persistent cloud workspaces.

Tom Langridge 20 min read Updated
Bridging theoretical RFC 6455 message limits with real-world cloud gateways and persistent workspaces.

What Are the RFC 6455 and Cloud WebSocket Message Limits?

Under RFC 6455, the WebSocket protocol specification defines an extended payload length of up to 2^64 bytes encoded in an 8-byte field within the frame header, yet Amazon API Gateway restricts WebSocket message payloads to 128 KB with a 32 KB maximum frame size, closing connections that exceed the limit with status code 1009. That operational gap between theoretical protocol capacity and cloud infrastructure reality is where production WebSocket architectures break.

Developers frequently assume that because WebSockets operate over TCP, message streams can transport arbitrarily large payloads. In practice, WebSockets are a framing protocol layered on top of a byte stream: every piece of data must fit into discrete frames bounded by physical network buffers, reverse proxies, and cloud gateways.

RFC 6455 Framing Mechanics and Payload Encoding

The WebSocket standard, formalized in RFC 6455 by the Internet Engineering Task Force (IETF), governs how data is packetized into frames. A WebSocket frame begins with a two-byte base header followed by optional extended payload length bytes, masking keys, and the application payload itself:

  • FIN (Bit 0): Indicates whether this frame is the final fragment in a message. Unfragmented messages set FIN to 1. Fragmented messages set FIN to 0 on initial frames and 1 on the concluding frame.
  • RSV1, RSV2, RSV3 (Bits 1-3): Reserved for protocol extensions negotiated during the HTTP handshake. Must remain 0 unless an extension defines them.
  • Opcode (Bits 4-7): Defines payload interpretation: 0x1 for UTF-8 text, 0x2 for binary data, 0x8 for connection close, 0x9 for ping, 0xA for pong, and 0x0 for continuation frames.
  • MASK (Bit 8): Indicates whether payload data is masked with a 4-byte key. Client-to-server frames must be masked; server-to-client frames are unmasked.
  • Payload Length (Bits 9-15): A 7-bit field encoding payload scale.

The 7-bit payload length field determines how the frame calculates boundaries:

  1. Payloads of 125 bytes or smaller: Encoded directly within the 7-bit field.
  2. Payloads between 126 bytes and 65,535 bytes: The 7-bit field holds 126, followed by a 16-bit unsigned integer containing the byte count.
  3. Payloads larger than 65,535 bytes: The 7-bit field holds 127, followed by a 64-bit unsigned integer containing the byte count.

Under RFC 6455 Section 5.2, when the payload length field holds 127, the following 8 bytes interpreted as a 64-bit unsigned integer represent the length. The specification mandates that the most significant bit must be 0, creating a mathematical upper bound of 2^63 - 1 bytes, which equals 9,223,372,036,854,775,807 bytes.

Comparing Theoretical Protocol Capacity with Production Implementations

A theoretical ceiling of 9 exabytes exists purely as a specification detail to avoid protocol renegotiation in future hardware. In actual runtimes, operating systems cannot buffer exabytes of transient socket frames. When a receiver ingests an incoming frame, it allocates system memory to reassemble the payload. If clients transmit oversized binary frames concurrently, the server process rapidly exhausts its memory pool, triggering out-of-memory crashes.

To maintain service availability, real-world runtimes, browsers, and cloud load balancers enforce defensive constraints:

Environment or Protocol Layer Default Message Limit Maximum Frame Size Breach Behavior Primary Constraint Type Checked Date
RFC 6455 Specification 2^63 - 1 bytes (~9.22 EB) Unbounded Undefined Theoretical protocol envelope October 2026
Node.js ws Library 100 MB (104,857,600 bytes) Unbounded Close code 1009 Server process heap protection October 2026
Socket.IO (Engine.IO) 1 MB (1,000,000 bytes) 1 MB Socket disconnection Transport memory threshold October 2026
Amazon API Gateway WebSocket 128 KB 32 KB Close code 1009 Managed infrastructure quota October 2026
Cloudflare Workers 32 MB 32 MB Connection reset Edge isolate memory ceiling October 2026
Mozilla Firefox 2 GB (2,147,483,647 bytes) 2 GB Disconnection / Error Browser tab heap configuration October 2026
Google Chrome / Chromium Dynamic (V8 Heap Bound) Dynamic Tab crash or termination V8 String / TypedArray allocation October 2026

Understanding these real-world thresholds allows system architects to design predictable real-time messaging pipelines that avoid silent connection failures.

Why Cloud Gateways and Server Runtimes Cap WebSocket Payloads

In production deployments, the true bottleneck for WebSocket message size is rarely application code. It is the runtime defaults of backend libraries and the hard quotas of cloud infrastructure gateways.

When a message exceeds the receiver's accepted size threshold, RFC 6455 defines close status code 1009, designated as "Message Too Big". The specification notes that status code 1009 indicates an endpoint is terminating the connection because it has received a message that is too large for it to process. Once code 1009 fires, the socket is torn down, terminating in-flight operations and dropping real-time state.

Runtime Protection in Node.js ws and Socket.IO

Node.js is a standard environment for WebSocket servers. The ws library sets a default maximum payload limit on every server instance to protect the single-threaded Node.js event loop.

Node.js manages binary data using Buffer instances allocated outside the V8 heap. When an incoming message arrives, the ws library concatenates incoming frame chunks into memory. Ingesting oversized messages forces garbage collection pauses, spikes memory usage, and blocks incoming network I/O for concurrent connections.

Developers configure this limit using the maxPayload option when instantiating WebSocketServer:

import { WebSocketServer } from 'ws';

// Restrict maximum message payload for memory safety
const wss = new WebSocketServer({
  port: 8080,
  maxPayload: 10485760 // 10 MB limit
});

wss.on('connection', (ws) => {
  ws.on('message', (data, isBinary) => {
    console.log(`Received message of length: ${data.length}`);
  });
  ws.on('close', (code, reason) => {
    if (code === 1009) {
      console.warn('Connection closed: payload exceeded limit');
    }
  });
});

Setting maxPayload to 0 removes the limit entirely, allowing frames of any size. Doing so in production exposes the server process to denial-of-service crashes if a client transmits a massive payload.

Socket.IO, which builds on top of the Engine.IO transport protocol, enforces an even tighter threshold through its maxHttpBufferSize option. Because Socket.IO wraps raw payloads in JSON envelopes containing event names and namespace identifiers, sending oversized files immediately closes the socket connection unless maxHttpBufferSize is explicitly adjusted in server configuration.

Cloud Gateway Quotas: AWS API Gateway and Edge Intermediaries

When applications move from self-hosted servers to managed cloud platforms, message limits drop by orders of magnitude. The most prominent example is Amazon API Gateway WebSocket APIs.

Amazon API Gateway terminates WebSocket connections at AWS edge locations, routing decoded messages to serverless backends like AWS Lambda, HTTP endpoints, or Amazon EventBridge. To maintain predictable resource consumption across multi-tenant edge nodes, AWS enforces strict limits documented in official service specifications. Specifically, Amazon API Gateway restricts WebSocket message payloads to 128 KB with a 32 KB maximum frame size, closing connections that exceed the limit with status code 1009.

These AWS quotas are fixed and cannot be increased. If an application attempts to send a message exceeding 128 KB through API Gateway, the gateway drops the connection with status code 1009 before the message reaches the backend Lambda function.

Furthermore, API Gateway's 32 KB maximum frame size means that even a message within the 128 KB limit must be fragmented into frames of 32 KB or smaller at the WebSocket protocol layer. If a client sends an unfragmented frame larger than 32 KB, API Gateway severs the connection immediately.

Reverse proxies enforce similar boundaries:

  • Nginx: While Nginx supports WebSocket proxying, directives like client_max_body_size govern the initial HTTP upgrade request. If an edge proxy buffers incoming responses, large messages can cause proxy buffer overflows or trigger timeout disconnects when transfers take longer than default windows.
  • Cloudflare Workers: WebSocket messages passing through Cloudflare edge workers are capped by edge isolate memory thresholds. Attempting to send larger data results in immediate connection resets.

How Browser Buffers and Backpressure Affect WebSocket Streaming

On the client side, web browsers introduce their own memory hurdles. While the WebSocket API in modern browsers does not publish an arbitrary message size limit, transfers are bounded by browser process memory, JavaScript engine heap limits, and socket buffer queues.

Attempting to transmit or receive massive payloads inside a browser tab can freeze the user interface, drop animation frames, and trigger out-of-memory tab terminations.

Memory Allocation and V8 Heap Constraints in the Browser

Browsers process WebSocket data through JavaScript engines such as V8 and SpiderMonkey. In these environments, incoming text messages are parsed into JavaScript strings, while binary messages are received as Blob or ArrayBuffer objects.

Each engine enforces internal allocation ceilings:

  • V8 String Ceilings: In Chromium-based browsers, a JavaScript string cannot exceed maximum string lengths enforced by V8. If a server sends an oversized JSON string over a WebSocket, the browser cannot allocate the string in memory and throws an invalid string length error, terminating the socket listener.
  • ArrayBuffer Allocations: Binary payloads bypass string parsing but must allocate contiguous virtual memory. In memory-constrained mobile devices, allocating large buffers for an incoming WebSocket message often fails if memory is fragmented, causing the browser tab to crash.
  • Firefox Configuration: Firefox includes an internal configuration preference in about:config named network.websocket.max-message-size. While this permits large frames in theory, receiving an oversized payload in a single message causes severe UI unresponsiveness while SpiderMonkey parses the buffer.

Monitoring WebSocket.bufferedAmount for Client-Side Backpressure

A common pitfall in client-side WebSocket programming is the absence of automatic flow control when sending data.

When you call send() on a WebSocket in browser JavaScript, the method returns immediately. It does not wait for data to be transmitted over the physical network card, nor does it wait for an acknowledgment from the receiving server. Instead, the browser queues the data in an internal user-agent send buffer.

If a client reads a large file from a local input and pushes it into send(), the entire dataset is copied into browser memory. If the user is on a mobile connection or slow uplink, the network card transmits data slowly while the browser's internal queue remains saturated.

To manage this, the W3C WebSocket standard provides the bufferedAmount property. This read-only attribute returns the number of bytes of application data that have been queued using send() but not yet emitted to the network.

A well-designed client monitors bufferedAmount and applies backpressure, pausing outgoing transmissions when the buffer crosses a high-water mark:

export class BackpressuredWebSocketSender {
  private socket: WebSocket;
  private readonly highWaterMark: number;
  private readonly lowWaterMark: number;
  constructor(socket: WebSocket, highWaterMark = 65536, lowWaterMark = 16384) {
    this.socket = socket;
    this.highWaterMark = highWaterMark;
    this.lowWaterMark = lowWaterMark;
  }
  async sendBufferWithBackpressure(data: ArrayBuffer, sliceSize = 16384): Promise<void> {
    const totalBytes = data.byteLength;
    let offset = 0;
    while (offset < totalBytes) {
      if (this.socket.bufferedAmount > this.highWaterMark) {
        await this.waitForBufferDrain();
      }
      const chunk = data.slice(offset, offset + sliceSize);
      this.socket.send(chunk);
      offset += sliceSize;
    }
  }
  private waitForBufferDrain(): Promise<void> {
    return new Promise((resolve) => {
      const checkInterval = setInterval(() => {
        if (this.socket.bufferedAmount <= this.lowWaterMark) {
          clearInterval(checkInterval);
          resolve();
        }
      }, 25);
    });
  }
}

By regulating transmissions against bufferedAmount, client applications prevent browser tab memory exhaustion and keep the main UI thread responsive during data-heavy operations.

Fastio features

Bypass WebSocket Message Size Limits with Persistent Workspaces

Connect autonomous agents to persistent cloud workspaces instead of streaming heavy files over WebSockets. Index documents for RAG and search via remote MCP. Monthly plans start with a 14-day free trial.

How to Chunk and Reassemble Large WebSocket Payloads

When an application must operate across cloud gateways like AWS API Gateway, sending files directly over standard WebSocket calls requires an application-level chunking protocol.

Application chunking divides an oversized asset into uniform slices, wraps each slice in a metadata envelope, transmits the slices across the socket, and reconstructs the original asset on the receiving end.

Chunk Framing Specification and Envelope Design

A reliable chunking protocol requires structured metadata to verify ordering, detect dropped packets, and validate data integrity upon reassembly.

A standard JSON envelope for binary chunk transfers contains the following attributes:

  • transferId: A unique identifier grouping all chunks belonging to a single logical file.
  • chunkIndex: A zero-indexed integer indicating the chunk sequence position.
  • totalChunks: The total count of chunks comprising the complete asset.
  • chunkChecksum: A cryptographic hash of the individual chunk, ensuring bytes were not corrupted in transit.
  • data: The actual chunk data, formatted as a binary buffer or encoded in Base64 if traversing text-only channels.

The following diagram illustrates how an oversized payload is split into structured envelopes that safely navigate gateway frame limits:

[ Original File ]
         │
         ├── Slice 0 (30 KB) ──► Envelope { id: "tx-1", index: 0, total: 4 } ──► Cloud Gateway (< 128 KB)
         ├── Slice 1 (30 KB) ──► Envelope { id: "tx-1", index: 1, total: 4 } ──► Cloud Gateway (< 128 KB)
         ├── Slice 2 (30 KB) ──► Envelope { id: "tx-1", index: 2, total: 4 } ──► Cloud Gateway (< 128 KB)
         └── Slice 3 (30 KB) ──► Envelope { id: "tx-1", index: 3, total: 4 } ──► Cloud Gateway (< 128 KB)
                                                                                        │
                                                                                  [ Receiver ]
                                                                                        │
                                                                              Verify SHA-256 Hashes
                                                                                        │
                                                                             [ Reconstructed File ]

End-to-End Implementation of a Chunked Transfer Pipeline

The following Node.js implementation demonstrates a chunking pipeline. The producer slices an incoming file into 30 KB chunks to conform to cloud gateway frame limits, while the receiver tracks in-flight transfers, verifies chunk ordering, and reassembles the complete buffer.

import { createHash } from 'node:crypto';

export interface ChunkEnvelope {
  transferId: string;
  chunkIndex: number;
  totalChunks: number;
  chunkChecksum: string;
  data: string;
}

export class ChunkedTransferManager {
  private activeTransfers = new Map<string, {
    totalChunks: number;
    receivedChunks: Map<number, Buffer>;
  }>();
  static sliceBuffer(transferId: string, buffer: Buffer, chunkSize = 30720): ChunkEnvelope[] {
    const totalChunks = Math.ceil(buffer.length / chunkSize);
    const envelopes: ChunkEnvelope[] = [];
    for (let index = 0; index < totalChunks; index++) {
      const start = index * chunkSize;
      const end = Math.min(start + chunkSize, buffer.length);
      const slice = buffer.subarray(start, end);
      const hash = createHash('sha256').update(slice).digest('hex');
      envelopes.push({
        transferId,
        chunkIndex: index,
        totalChunks,
        chunkChecksum: hash,
        data: slice.toString('base64'),
      });
    }
    return envelopes;
  }
  processIncomingChunk(envelope: ChunkEnvelope): Buffer | null {
    const chunkBuffer = Buffer.from(envelope.data, 'base64');
    const calculatedHash = createHash('sha256').update(chunkBuffer).digest('hex');
    if (calculatedHash !== envelope.chunkChecksum) {
      throw new Error(`Checksum mismatch on chunk ${envelope.chunkIndex} for transfer ${envelope.transferId}`);
    }
    if (!this.activeTransfers.has(envelope.transferId)) {
      this.activeTransfers.set(envelope.transferId, {
        totalChunks: envelope.totalChunks,
        receivedChunks: new Map(),
      });
    }
    const transfer = this.activeTransfers.get(envelope.transferId)!;
    transfer.receivedChunks.set(envelope.chunkIndex, chunkBuffer);
    if (transfer.receivedChunks.size === transfer.totalChunks) {
      const sortedChunks: Buffer[] = [];
      for (let i = 0; i < transfer.totalChunks; i++) {
        const part = transfer.receivedChunks.get(i);
        if (!part) {
          throw new Error(`Missing chunk index ${i} during reassembly`);
        }
        sortedChunks.push(part);
      }
      this.activeTransfers.delete(envelope.transferId);
      return Buffer.concat(sortedChunks);
    }
    return null;
  }
}

The Overhead of WebSocket Chunking

While application-level chunking circumvents strict gateway limits, it introduces operational costs:

  1. Protocol and Serialization Bloat: Encoding binary chunks into Base64 strings expands payload size substantially compared to raw binary bytes, consuming extra network bandwidth and CPU cycles during serialization and deserialization.
  2. State Management Overhead: The receiving server must hold partial chunks in memory or write them to temporary storage while awaiting the remaining pieces. If a client disconnects partway through an upload, the server must run cleanup routines to prune orphaned transfers.
  3. Event Loop Congestion: Slicing, hashing, and encoding thousands of chunks on the server or client main thread causes micro-stalls in the JavaScript event loop, degrading the responsiveness of concurrent real-time features like chat or live cursor tracking.

How Agent Workspaces Stream Control Events and Offload Heavy Artifacts

The expansion of autonomous AI agents, multi-agent swarms, and AI coding assistants has exacerbated WebSocket payload friction.

Modern software agents (such as Claude Code, Codex, Cursor, Gemini, and OpenClaw) operate in fast feedback loops, streaming thoughts, tool calls, and workspace changes over real-time communication channels.

Attempting to stream large generated files, research PDFs, raw datasets, or media assets directly through an agent's WebSocket event stream immediately trips gateway ceilings like AWS API Gateway's 128 KB cap, triggering code 1009 disconnects that terminate the run.

The Claim-Check Pattern: Decoupling Control Signals from Payload Data

High-performance agent architectures avoid streaming heavy payloads over WebSockets by implementing the Claim-Check Pattern.

In this pattern, the WebSocket connection is reserved for lightweight control signals, telemetry, tool-call execution metadata, and real-time status updates. When an agent generates or ingests a large file, the asset is written directly to persistent cloud workspace storage. The agent then passes a lightweight reference pointer across the WebSocket stream.

[ AI Agent Workflow ]
         │
         ├── 1. Upload Artifact (Chunked REST / S3) ──► [ Persistent Cloud Workspace ]
         │                                                      │
         │                                               Auto-Index for RAG
         │                                                      │
         └── 2. Emit Event Pointer (WebSocket < 1 KB) ──────────┼─────────────────────► [ Human UI / Client ]
                { type: "artifact_ready", workspace_id: "...", file_id: "..." }                 │
                                                                                              │
                                                    3. Query via MCP / Search Excerpts ◄────────┘

This decoupled architecture delivers three fundamental advantages:

  1. Gateway Immunity: Event messages stay compact, easily clearing cloud gateway message ceilings.
  2. Context Window Preservation: Large documents do not flood the LLM's context window. Sockets transmit citations and summary cards rather than megabytes of raw text.
  3. Resilient Collaboration: Heavy assets persist in shared storage, where human teammates and peer agents can view, edit, and audit them without keeping socket connections open.

Context Ceilings and the Multi-File Corpus Problem

The limitation of streaming large files directly into AI agent workflows mirrors the constraints of AI model context windows. For AI assistants like Claude, file upload limits depend on the session type: standard chats enforce per-file size caps and file count limits, while projects accept individual files up to the documented project cap without a fixed file-count limit.

Claude Projects has no fixed file-count cap, but the practical ceiling on a project is the model context window, and reaching it is when teams with a large corpus look for another path. When teams attempt to attach dozens of enterprise documents, design files, or API specifications into a project, the cumulative token count exhausts the context window. Once the context window fills, the assistant degrades in reasoning quality or refuses additional attachments. Reaching this context ceiling is precisely when engineering teams with large document corpora transition from raw file uploads to indexed cloud workspaces.

Integrating Remote MCP Workspaces for Large-Corpus Agent Operations

Instead of passing massive files across fragile WebSockets or cramming entire document libraries into LLM context windows, modern agent systems offload corpus management to intelligent workspaces on Fast.io.

Fast.io provides persistent, organization-owned cloud workspaces built for human and AI agent collaboration:

  • Chunked Workspace Uploads: Agents upload large assets using reliable chunked uploads directly to workspace storage, completely bypassing WebSocket frame caps.
  • Automated Indexing with Intelligence Mode: When files land in a workspace, Intelligence Mode indexes documents for hybrid search (combining full-text search, semantic vector retrieval, and search-by-metadata-value). AI agents query relevant document excerpts on demand, receiving citation-backed answers that consume minimal context tokens.
  • Remote Model Context Protocol (MCP) Server: Agents connect to Fast.io workspaces through a consolidated MCP toolset hosted at https://mcp.fast.io/mcp/tools for Claude and general MCP clients and at https://mcp.fast.io/mcp/code for coding agents. Through MCP tools like storage and search, agents inspect directories, search files, and extract passages across persistent workspaces. For complete developer setup guides, see Storage for AI Agents.
  • Structured Document Extraction with Metadata Views: Rather than writing custom parsing scripts, teams configure Metadata Views to convert unstructured files into typed, queryable spreadsheet schemas that agents inspect via MCP.
  • Concurrency Control with Advisory File Locks: In multi-agent swarms, multiple workers often coordinate over shared assets. Fast.io provides advisory per-file leases acquired, heartbeated, and released through MCP storage tools (storage_manage actions lock-acquire and lock-release, and storage action lock-status) to coordinate concurrent writers while per-file version history preserves every iteration.
  • Real-Time Workspace Activity Monitoring: To keep agents synchronized without pushing heavy file contents across WebSockets, Fast.io provides a workspace activity feed accessible via WebSocket or long-poll subscription. Agents subscribe to activity events to learn when files are added or modified, retrieving document content on demand through MCP.
  • Collaborative Notes and Branded Portals: Agents and humans document projects using shared markdown notes kept in workspaces and indexed for AI grounding, while finished deliverables are shared with clients via branded Send, Receive, or Exchange portals that support password protection, download restrictions, and access expiration.
  • Multi-Cloud Sync and Import: Workspaces ingest files from existing enterprise repositories. Cloud Sync maintains scheduled or on-demand one-way or two-way synchronization with Google Drive, Dropbox, Box, and OneDrive (including SharePoint libraries via the OneDrive connector). One-time cloud import is also available.

Fast.io operates on a paid subscription model. Monthly plans start with a 14-day free trial, which requires a credit card. Paid subscriptions include Starter, Business, and Enterprise plans, providing team seats, dedicated storage, and credits for workspace intelligence:

Subscription Plan Monthly Rate Storage Capacity Team Seats Included AI Credits
Starter $9.99 250 GB 3 seats 100,000 monthly
Business $49.99 5 TB 10 seats 600,000 monthly
Enterprise $199.99 25 TB 30 seats 3,000,000 monthly

By coupling lightweight WebSocket event signaling with persistent, indexed cloud workspaces, developers build agent workflows that remain responsive, avoid infrastructure disconnects, and scale across massive document corpora.

Sources

References used to verify factual claims in this guide.

  1. The WebSocket protocol specification defines an extended payload length of up to 2^64 bytes encoded in an 8-byte field within the frame header.

  2. Amazon API Gateway restricts WebSocket message payloads to 128 KB with a 32 KB maximum frame size, closing connections that exceed the limit with status code 1009.

Frequently Asked Questions

Is there a size limit on WebSocket messages?

Yes. While the RFC 6455 protocol specification defines an extended payload length of up to 2^64 bytes, production environments enforce defensive message size limits. Cloud gateways such as Amazon API Gateway restrict message payloads to 128 KB, while server frameworks configure bounded buffer thresholds to prevent memory exhaustion and denial of service.

What is the maximum payload size for a WebSocket frame?

Under RFC 6455, the maximum frame payload size depends on the header length encoding. Payloads can use 7-bit, 16-bit, or 64-bit extended lengths. However, intermediate infrastructure frequently restricts individual frames: for example, Amazon API Gateway enforces a maximum frame size of 32 KB.

How do you send large files over WebSockets?

To send large files over WebSockets without triggering message size limits, you can either implement application-level chunking (slicing data into frames wrapped in sequence envelopes) or adopt the Claim-Check pattern. With the Claim-Check pattern, files are uploaded directly to cloud workspace storage, and only lightweight file references are passed across the WebSocket.

What is the WebSocket 1009 close status code?

WebSocket close status code 1009 means 'Message Too Big'. It is defined in RFC 6455 Section 7.4.1 to indicate that an endpoint is terminating the connection because it received a message that exceeds the maximum payload size it is configured or willing to process.

Why does AWS API Gateway enforce a 128 KB WebSocket limit?

Amazon API Gateway restricts WebSocket message payloads to 128 KB with a 32 KB maximum frame size to protect multi-tenant edge infrastructure from buffer exhaustion and ensure predictable low-latency message routing to serverless backends like AWS Lambda.

How does WebSocket.bufferedAmount prevent memory exhaustion in the browser?

The browser WebSocket.bufferedAmount property reports how many bytes have been queued with send() but not yet transmitted across the physical network. Checking this value allows client applications to pause outbound transmissions when buffers fill, applying backpressure and preventing browser tab memory crashes.

What happens when a WebSocket message exceeds the server payload threshold?

When an incoming message exceeds the configured payload threshold, standard WebSocket servers terminate the connection immediately. RFC 6455 defines close status code 1009 for this condition, indicating that an endpoint dropped the connection because it received a message too large to process.

Why should AI agents avoid streaming large files directly over WebSockets?

Streaming heavy files across agent WebSockets risks connection drops from cloud gateway limits (such as AWS 128 KB), blocks single-threaded event loops, and bloats model context windows. Decoupling file storage into persistent cloud workspaces allows agents to transmit lightweight pointers while indexing documents for semantic search.

Related Resources

Fastio features

Bypass WebSocket Message Size Limits with Persistent Workspaces

Connect autonomous agents to persistent cloud workspaces instead of streaming heavy files over WebSockets. Index documents for RAG and search via remote MCP. Monthly plans start with a 14-day free trial.