# \[Bug\]: Agent preview recordings ignore the "Browser recording frame rate" setting and are capped at 30 fps · Issue \#19442 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/issues/19442)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: backlog

Priority: 0

## Description

[Discussion and activity](https://git.cafe/pingdotgg/t3code/issues/19442)

---

### Before submitting

- [x] I searched existing issues and did not find a duplicate.
- [x] I included enough detail to reproduce or investigate the problem.

### Area

apps/server

### Steps to reproduce

1. In Settings → Browser, set **Browser recording frame rate** to 60 fps.
2. Serve a page that repaints every frame, for example:
   ```html
   <div id="n">0</div>
   <script>let n=0;(function f(){document.getElementById('n').textContent=++n;requestAnimationFrame(f)})()</script>
   ```
3. From an agent: `preview_open` that page, `preview_recording_start`, wait 4 seconds, `preview_recording_stop`.
4. Count the frames in the returned MP4, for example with `ffprobe -count_frames`, and the gaps between their timestamps.

### Expected behavior

Up to 60 fps, as the setting says ("Maximum recording rate. 30 fps saves CPU and storage; 60 fps is smoother."). Before #15328, agent recordings went through the same recorder as the record button and followed this setting.

### Actual behavior

The page ran at 60 fps inside the tab (counted with `requestAnimationFrame`), but the recording has about 29 fps:

| Viewport | MP4 size | Frames / duration | Mean gap | Longest gap |
|---|---|---|---|---|
| 1600×900 | 3200×1800 | 159 / 5.45 s | 34.3 ms | 232 ms |
| 800×450 | 1600×900 | 141 / 4.91 s | 34.8 ms | 266 ms |

A quarter of the pixels gives the same rate, so the limit is not frame size. A 140 ms CSS fade, which is what I was recording, gets three or four frames.

From the source at 26c48bb:

- The agent's recording is encoded on the server, with a fixed rate: [`canvas.captureStream(30)`](https://github.com/pingdotgg/t3code/blob/26c48bbc0a9ddc23acdd20a733fe209d423e848a/apps/server/src/preview/ServerBrowserPage.ts#L587-L588), and the bitrate formula also assumes 30. The screencast it reads from is [`RECORDING_SCREENCAST`](https://github.com/pingdotgg/t3code/blob/26c48bbc0a9ddc23acdd20a733fe209d423e848a/apps/server/src/preview/ServerBrowser.ts#L98).
- `browserRecordingFrameRate` is read only by the record button's path ([`startBrowserRecording`](https://github.com/pingdotgg/t3code/blob/26c48bbc0a9ddc23acdd20a733fe209d423e848a/apps/web/src/browser/browserRecording.ts#L543-L544), which passes it to [`getDisplayMedia`](https://github.com/pingdotgg/t3code/blob/26c48bbc0a9ddc23acdd20a733fe209d423e848a/apps/web/src/browser/browserRecording.ts#L271-L277)). Nothing on the server reads it.
- Both lines came with #15328. Before it, the `recordingStart` automation command was handled in `PreviewAutomationHosts.tsx` by `startBrowserRecording`, so the setting applied to agent recordings too.

The setting is client-local by design ([comment in `settings.ts`](https://github.com/pingdotgg/t3code/blob/26c48bbc0a9ddc23acdd20a733fe209d423e848a/packages/contracts/src/settings.ts#L269-L275)), so the server cannot read it as it is. One way to fix it: have the client that starts or owns the tab pass its frame rate with `recordingStart`, or move the setting into server settings, and use that value in `captureStream()` and the bitrate.

### Impact

Minor bug or occasional failure

### Version or commit

0.0.46-nightly.20261014.3093 (107f602); `main` at 26c48bb has the same code

### Environment

Desktop app on Linux (NixOS, Wayland, niri), 2× display scale

### Logs or stack traces

_No response_

### Screenshots, recordings, or supporting files

_No response_

### Workaround

_No response_

