Browsers

Browsers, QUIC, and what watson can and cannot see

watson watches native apps passively, from the wire. Browsers add two problems. Every web app's traffic comes from one process, and most browsers speak HTTP/3 (QUIC), which passive capture cannot see into. This page explains how watson handles both and what you see in each case.

The short version

What you see in each situation

SituationPassive captureRowNetwork evidenceScore
HTTP/2 (TCP), watch started before the connection openedsees the handshake, names the connectionbrowserround-trip, retransmits, stallsfull: health, TTFB, stalls. High once baselines fill
HTTP/2, connection already open when watch startedblind (no handshake)browser-only, flag h2first hop only (macOS)TTFB only, shown 100~. Medium
HTTP/3 (QUIC)blind (see below)browser-only, flag h3first hop only (macOS)TTFB only, shown 100~. Medium
No extension installednames TCP connections it saw, as multiplexed pieces; nothing for QUICpassive piecesyes, for TCPnormal, Low (multiplexed)
Extension running, watch not runningn/anothing: serve stores the report, but watch skips reports from before it started

The reason on a browser-only row says which case it is:

A TTFB-only score is drawn as 100~ ttfb in the terminal (dimmed) and as a dashed pill on the page, so a weaker score looks weaker.

How a browser stream becomes one record

Passive capture often splits one long stream with pauses into several multiplexed pieces on one connection, so the extension's report cannot be matched one-to-one with a passive interaction. Instead:

  1. The extension sends the report when the stream ends: host, start time, headers time, chunk times and sizes, and the protocol.
  2. watch holds it for the quiet period plus a second (passive capture announces an interaction only after 2 s of quiet), then until the overlapping passive pieces have settled (at most 90 s).
  3. It builds the record from the report (exact first byte, last byte, pauses) and attaches the retransmit and round-trip evidence of the pieces that overlap it, from browser processes only. The first-hop and machine samples for the same window are attached too.
  4. The covered pieces are listed in the record (covers) and hidden in both watch and serve, so only the merged record shows.

If no piece overlaps, the record is browser-only.

Why QUIC is invisible

QUIC runs over UDP and encrypts its transport headers, so there are no sequence numbers, ACKs or retransmissions on the wire to read. For a QUIC flow watson sees datagram sizes and times and nothing about loss or round trips. For the same reason, native Claude Desktop over QUIC gets only a TTFB-based score.

A QUIC flow also has no readable ClientHello, so only its destination address says what it is. Addresses are shared: Google's front ends serve every Google API, and an idle browser keepalive was once reported as "Google Vertex". watson therefore accepts an address-only match only from a known client app. A browser is not one, so its QUIC flows are ignored.

Relaxing that rule would gain nothing. Naming the flow would give watson datagram timing, which the page already has more precisely, and QUIC would still hide the retransmits and round trips that matter. The extension's report is already the best source for a QUIC stream. What is missing is path health, and no passive change can add it.

What is still visible under QUIC

These causes come from samplers that never look at the stream, so they work the same for a QUIC or browser-only record (all macOS only for now):

Weak Wi-Fi alone does not name a QUIC pause, and nothing can name it upstream: telling "past the router" apart needs the path round trip that QUIC hides. A pause with none of the above stays ? (unattributed). The score stays TTFB only either way.

What QUIC costs you

KeptLost
exact first byte (headers), duration, chunk cadenceround-trip time to the server
where the pauses are and how longretransmits
rCV, pattern, throughputtelling an upstream stall from a provider wait (those pauses show ?)
a score, against the app's own baselineany score component except TTFB
first-hop and machine causes (macOS)

For a model that takes a while before it writes, the TTFB-only score is nearly constant. The headers arrive in 40 to 120 ms, and the wait that varies is a provider wait, which never lowers the score.

The "started before the browser" limit

watson cannot name a connection it did not see open (no handshake), even over TCP. Chromium browsers reuse HTTP/2 connections for a long time, so starting watch after the browser has been in use gives browser-only rows until it reconnects.

To get a full row:

  1. Start watch first.
  2. Quit the browser completely and reopen it. Check that it is gone: for Chrome, pgrep -f "Google Chrome" prints nothing. Chromium browsers can stay alive in the background and keep their connections.
  3. Use the web app.

How to check which protocol the browser is using