Skip to content

Research. What we measure, and the latest results.

Updated 2026-11-01

App sharing

How a shared app feels to the person watching or driving it, measured with the viewer on the same Mac as the host.

DaVinci Resolve playback: input to screen latency

Starting timeline playback in a shared Resolve running on the hidden display, viewer on the same machine (WebRTC). Includes Resolve's own playback start.

360 ms

DaVinci Resolve playback: frame rate

Starting timeline playback in a shared Resolve running on the hidden display, viewer on the same machine (WebRTC). Includes Resolve's own playback start.

35.7 fps

Heavy Blender viewport: input to screen latency

Orbiting a dense scene in Material Preview in a shared app view, viewer on the same machine (WebRTC).

127 ms

Heavy Blender viewport: frame rate

Orbiting a dense scene in Material Preview in a shared app view, viewer on the same machine (WebRTC).

41.5 fps

Text editor: input to screen latency

Typing in a shared TextEdit window, viewer on the same machine (WebRTC).

79 ms

Text editor: frame rate

Typing in a shared TextEdit window, viewer on the same machine (WebRTC).

40.1 fps

App sharing, every run

Machine: Mac15,6, Apple M3 Pro, 18 GB, macOS 26.3.1. Input to photon on the viewer's clock: one input through the control path, injected into the app on the host, captured (ScreenCaptureKit through Electron), encoded, sent, and timed at the first painted frame whose 96x60 downsample changed. Each input makes a large change (Blender's sidebar opening or closing, Resolve starting playback, one 160 pt character typed or deleted in TextEdit), 15 samples per row. The input is sent only after the picture has been still for 400 ms. Hidden display rows: the shared window runs on a virtual display off the host's screen and input is posted to the app alone; the host's cursor and front app are untouched. Frame rate: painted frames per second on the viewer over 10 s of constant motion. Capture only delivers frames when pixels change. Host CPU: top's second sample, summed over the desktop app's processes and lp-appctl (100 = one core). Baseline local-capture: the same input injected on the host and timed on raw capture frames, no encode or network. Viewer and host are the same Mac (loopback), so the network adds nothing and the viewer's decode shares the CPU. No TURN relay exists yet; none is measured.

Blender 5.2.2, 16 subdivided monkeys, Material Preview: webrtc-p2p-loopback

VP8, 1686x1050, host CPU 74.3%

127 ms p50 · 41.5 fps

p95 203 ms

Blender 5.2.2, 16 subdivided monkeys, Material Preview: local-capture-baseline

none (raw capture), 1686x1050, host CPU 77.2%

106 ms p50 · 53.7 fps

p95 158 ms

Blender 5.2.2, 16 subdivided monkeys, Material Preview: jpeg-relay-via-server-loopback

jpeg q0.72, 15 fps cap, 1600x996, host CPU 100.5%. Measured before the relay queue fix (commit 27850b8cac): the server could queue frames for a viewer, so fast-changing pictures arrive late.

345 ms p50 · 13.4 fps

p95 381 ms

TextEdit (macOS 26), 160 pt text, typing 20 keys/s: webrtc-p2p-loopback

VP8, 586x488, host CPU 28.1%

79 ms p50 · 40.1 fps

p95 128 ms

TextEdit (macOS 26), 160 pt text, typing 20 keys/s: local-capture-baseline

none (raw capture), 586x488, host CPU 24.2%

37 ms p50 · 53 fps

p95 46 ms

TextEdit (macOS 26), 160 pt text, typing 20 keys/s: jpeg-relay-via-server-loopback

jpeg q0.72, 15 fps cap, 586x488, host CPU 28.9%. Measured before the relay queue fix (commit 27850b8cac): the server could queue frames for a viewer, so fast-changing pictures arrive late.

166 ms p50 · 13.2 fps

p95 215 ms

Blender 5.2.2, 16 subdivided monkeys, Material Preview: webrtc-p2p-loopback-hidden-display

VP8, 1686x1050, host CPU 76.7%

169 ms p50 · 37.2 fps

p95 258 ms

Blender 5.2.2, 16 subdivided monkeys, Material Preview: local-capture-baseline-hidden-display

none (raw capture), 1686x1050, host CPU 74.7%

112 ms p50 · 51.4 fps

p95 177 ms

Blender 5.2.2, 16 subdivided monkeys, Material Preview: jpeg-relay-via-server-loopback-hidden-display

jpeg q0.72, 15 fps cap, 1600x996, host CPU 95.8%. Measured before the relay queue fix (commit 27850b8cac): the server could queue frames for a viewer, so fast-changing pictures arrive late.

392 ms p50 · 13 fps

p95 461 ms

TextEdit (macOS 26), 160 pt text, typing 20 keys/s: webrtc-p2p-loopback-hidden-display

VP8, 602x504, host CPU 27.2%

74 ms p50 · 38.4 fps

p95 152 ms

TextEdit (macOS 26), 160 pt text, typing 20 keys/s: local-capture-baseline-hidden-display

none (raw capture), 602x504, host CPU 28.2%

37 ms p50 · 48 fps

p95 69 ms

TextEdit (macOS 26), 160 pt text, typing 20 keys/s: jpeg-relay-via-server-loopback-hidden-display

jpeg q0.72, 15 fps cap, 602x504, host CPU 29.1%. Measured before the relay queue fix (commit 27850b8cac): the server could queue frames for a viewer, so fast-changing pictures arrive late.

161 ms p50 · 13.4 fps

p95 196 ms

DaVinci Resolve 21.1.2 (free), Edit page, 1080p test clip: webrtc-p2p-loopback-hidden-display

VP8, 1686x1050, host CPU 58.7%

360 ms p50 · 35.7 fps

p95 634 ms

DaVinci Resolve 21.1.2 (free), Edit page, 1080p test clip: local-capture-baseline-hidden-display

none (raw capture), 1686x1050, host CPU 44.1%

232 ms p50 · 52.1 fps

p95 815 ms

DaVinci Resolve 21.1.2 (free), Edit page, 1080p test clip: jpeg-relay-via-server-loopback-hidden-display

jpeg q0.72, 15 fps cap, 1600x996, host CPU 72.3%. Measured before the relay queue fix (commit 27850b8cac): the server could queue frames for a viewer, so fast-changing pictures arrive late. Resolve playback shows it: about 3.5 s of queued frames. Not re-measured yet.

3479 ms p50 · 12.8 fps

p95 3755 ms

any: turn-relay

No TURN server is deployed (nothing paid; a self-hosted coturn is the documented next step), so relay beyond the LAN is not measured.

Not measured

resolve-playback: webrtc-p2p-loopback (on screen)

Resolve was measured on the hidden display only, so the host's screen was not taken over.

Not measured

Test suites

Automated runs of the real app, end to end, before a release goes out.

Cloud end to end (our cloud, coming soon)

Sign up, project from a real GitHub repo, invite, agent turns, sync. Run against our cloud host before it was set to coming soon in 0.1.10; the cloud is not available to use.

9/9 passed

2026-10-31

Cloud end to end, joining by invite link (our cloud, coming soon)

The same flow joining through an invite link, without agent turns.

7/7 passed

2026-11-01

Server tests, LogicPacks modules

Every test in the LogicPacks server modules.

139/139 passed

2026-11-01

Any-app demo

Play, pause, window switching and the full 72 second timeline.

19/19 passed

Member sandbox (our cloud, coming soon)

Checks of the design that keeps members of a cloud workspace apart from the host and from each other. Our cloud is coming soon and is not available yet.

Each member runs as their own sandbox user

Agent turns run as a separate Unix user per member, with a scrubbed environment and no host credentials.

In place

2026-11-01

One member cannot drive another member's agent server

Request to another member's local agent server without its password.

Refused (401)

2026-11-01

A member cannot read host secrets

Reading host credential files from a member sandbox.

Check running

A member cannot read another member's files

Listing another member's home and project folders.

Check running