permessage-deflate
extensionRFC 7692permessage-deflate (RFC 7692) compresses each WebSocket message using the DEFLATE algorithm (zlib). Negotiated during the HTTP Upgrade handshake via Sec-WebSocket-Extensions. Reduces message size by 60-80% for text-heavy JSON payloads. The RSV1 bit in the WebSocket frame header signals compression. Supported by all major browsers and WebSocket libraries.
Details
permessage-deflate is the standard WebSocket compression extension, defined in RFC 7692.
Negotiation: Client includes in handshake: Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits Server responds with: Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=12 If the server omits the extension from the response, compression is not used.
Compression context: By default, both sides maintain a single DEFLATE compression context across all messages (sliding window). This gives better compression ratios because repetition across messages is exploited.
client_no_context_takeover: client resets compression context after each message. Required when the client may send messages to multiple servers (e.g., load balancer scenario). Reduces compression ratio. server_no_context_takeover: server resets context after each message.
Window bits: client_max_window_bits / server_max_window_bits: LZ77 sliding window size (8-15 bits, default 15 = 32KB). Smaller windows use less memory but compress less effectively.
RSV1 bit: When RSV1=1 in a WebSocket frame, the payload is DEFLATE-compressed (after removal of the 4-byte flush marker 00 00 FF FF appended by DEFLATE). RSV1=0 means uncompressed. A message that doesn't compress well (already-compressed binary) can be sent uncompressed even when the extension is negotiated.
Performance: CPU cost of DEFLATE compression is usually justified by bandwidth savings. For high-frequency small messages (trading systems, gaming), disabling context takeover trades compression ratio for lower CPU overhead. For large JSON payloads over slow connections, permessage-deflate dramatically reduces latency.
Handshake example
# Client Upgrade request with permessage-deflate GET /ws HTTP/1.1 Host: api.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits; client_no_context_takeover # Server response (accepts with modified parameters) HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=12 # Compressed frame: RSV1 bit set # Binary: 1100 0010 (FIN=1, RSV1=1, opcode=0x2 binary) # ↑ RSV1=1 signals DEFLATE compression