2026-07-18 · 7 min read

How Tessera streams live browser viewports to an infinite canvas

Every live tile on a Tessera canvas is a real Chromium page, not a screenshot and not a scaled iframe. This post covers the pipeline that makes a wall of them affordable: CDP screencast over WebSocket, binary JPEG frames, offscreen pausing, and the SSRF-safe proxy every page connection routes through.

One browser, many contexts

The rendering service (FastAPI + Playwright) launches a single headless browser at startup. Each live tile gets its own browser context (isolated cookies and storage) with a viewport set to exact device dimensions and pixel ratio. Contexts are cheap compared to whole browsers, but they are still the marginal cost of the product, which is why plans meter concurrent live sessions.

Frames: CDP screencast → binary WebSocket

Chrome DevTools Protocol has a built-in screencast. The server subscribes and relays each frame straight down a WebSocket as a binary JPEG message. No base64, no JSON envelope. That is roughly a third less wire traffic, and the client never parses megabyte strings; it turns each Blob into an object URL and swaps an <img>.

# per connected client cdp.on("Page.screencastFrame", enqueue) # bounded queue (2) await ws.send_bytes(b64decode(frame)) # binary JPEG await cdp.send("Page.screencastFrameAck") # keep frames flowing

The queue is two frames deep. If a client is slow, old frames are acknowledged and dropped rather than buffered, so latency stays flat under load.

Offscreen tiles cost nothing

A canvas full of devices only pays for what you can see. An IntersectionObserver on each tile sends pause / resume over the socket; the server stops the screencast for hidden tiles, so Chromium stops encoding entirely. Off-screen tiles keep their last frame as a preview and release their session for others to use.

Input goes back up the same socket

Mouse, wheel, and keyboard events are forwarded as small JSON messages and dispatched via Input.dispatchMouseEvent / dispatchKeyEvent. Resizes ride the socket too: a corner-drag updates the live viewport instead of tearing down the context, which is what makes breakpoint scrubbing feel instant.

The product is an SSRF, so handle it accordingly

A service whose job is "navigate a real browser to any URL" is a server-side request forgery generator by design. Validating the URL once at request time is not enough: redirects and DNS rebinding defeat it. Instead, every browser context routes through a local validating forward proxy that resolves and checks the target IP at connect time. That covers every redirect hop and sub-resource, not just the initial navigation.

See it live

The fastest way to understand it is to feel the latency yourself, and the demo needs no signup.