Inspecting WebSockets and SSE in Firefox Network Monitor

This article provides a comprehensive overview of how the Firefox Network Monitor captures, processes, and displays real-time data frames for WebSockets and Server-Sent Events (SSE). It covers the underlying browser architecture that intercepts these persistent connections, how developers can locate and filter these streams in the user interface, and the specific tools available for decoding and analyzing live message payloads as they happen.

The Underlying Architecture

Firefox inspects live frames without interrupting the data flow between the client and the server by utilizing its internal networking library, Necko, alongside the DevTools Server-Actor architecture.

When a WebSocket or SSE connection is established, Firefox attaches a specialized listener (an Actor) to the network channel. Instead of waiting for a request to finish—which does not apply to persistent connections—the Actor intercepts individual data frames as they pass through the browser's networking layer. It timestamps the frames, calculates their size, and asynchronously streams them to the Network Monitor UI in real time.

Inspecting WebSocket Frames

WebSockets provide bidirectional communication. To inspect these frames in Firefox:

  1. Open the Firefox Developer Tools and select the Network panel.
  2. Click the WS filter button in the toolbar to isolate WebSocket connections.
  3. Reload the page or trigger the action that initiates the WebSocket handshake.
  4. Click on the request that returns a 101 Switching Protocols status code.
  5. Select the Response tab in the details pane on the right.

Once inside the Response tab, Firefox displays a live table of frames as they are sent and received.

  • Direction Indicators: Outgoing frames (client to server) are marked with an upward-pointing green arrow. Incoming frames (server to client) are marked with a downward-pointing orange arrow.
  • Columns: By default, the view shows the Data preview, Size, and Time. You can right-click the table header to toggle additional columns like OpCode, MaskBit, and FinBit.
  • Payload Inspection: Clicking on any individual frame opens a bottom pane. If the payload is formatted in JSON, Firefox automatically parses it into an expandable tree view alongside the raw text. Binary frames are displayed in a hexadecimal view.

Inspecting Server-Sent Events (SSE)

Server-Sent Events provide unidirectional communication from the server to the browser over standard HTTP. Firefox uses the same interface used for WebSockets to inspect SSE streams.

  1. In the Network panel, ensure the All or Other filter is selected.
  2. Locate the request that establishes the stream. You can identify this by looking for the text/event-stream value in the Type column.
  3. Click the request and open the Response tab.

As the server pushes updates, Firefox populates the table in real time. Because SSE is unidirectional, all frames will show as incoming. For SSE, you can right-click the table header to enable specific columns relevant to the protocol, such as Event Name, Last Event ID, and Retry. Clicking an event frame will parse the data field in the bottom pane, converting JSON strings into inspectable objects automatically.

Managing Live Traffic in the UI

Because WebSockets and SSE can generate thousands of frames per minute, the Firefox Network Monitor includes specific controls at the top of the Response tab to manage live data:

  • Filter: A text input box allows you to filter visible frames by their payload content. Typing a keyword immediately hides frames that do not contain that string.
  • Frame Type Filtering (WebSockets only): You can filter out control frames (like Ping/Pong) to only view actual data frames.
  • Clear Frames: Clicking the trash can icon clears the current list of captured frames from the UI. This does not close the connection; it simply resets the view so you can focus on newly incoming frames.
  • Pause/Resume: While there is no explicit pause button for the socket itself, scrolling up in the frame list stops the UI from auto-scrolling, allowing you to inspect a specific frame while new frames continue to populate at the bottom of the list.