You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[FEATURE]: limit the FPS (frames per second) target rate, useful for remote work #13817
I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Gist
When working on powerful remote machine over RDP (XRDP) I could see that it become laggy and xrdp consumes CPU. After some back and forth, I've assumed it may be to high refresh rate and it seems to be so - once I've set rps to 5, xrdp CPU consumption became much lower.
As well, when working over ssh - which is a quite standard thing too, having high FPS doesn't make much sense, i.e. over 250-300 ms link, what kind of FPS/RPS you may expect :)
I've build local package, enabled debug information ( Ctrl+P -> Toggle Debug ) , watched FPS is limited while producing some output. In the other terminal, I was watching top for xrdp.
"classical" situation:
Reacted by Santiago M. Mola, Jeffrey Magder, Kirill Chuprov, Dan Kamins and Pepi Zawodsky
This problem still exists, and the feature suggestion is good.
(The suggested PR seems orthogonal and related to the web interface. I believe the original feature request is about the TUI, as is my interest.)
On systems where an animation or spinner keeps the renderer live, lowering both values substantially reduces CPU usage (the app is internally walking a huge scene graph 60 times per second) as well as remote-terminal traffic.
Something as simple as an environment variable would suffice, e.g.:
Unsupported workaround: Binary patch OpenCode TUI to throttle FPS
(targets binary in official Docker image ghcr.io/anomalyco/opencode)
While native FPS configuration is being considered...
I developed a binary-patch workaround that makes a copy of the opencode binary with both targetFps and maxFps set as specified. You can easily make separate binaries for different uses, e.g. opencode-fps-30, opencode-fps-10, opencode-fps-1, etc.
At some point in the future when OpenCode changes the relevant code, this patch will no longer work (but it should fail gracefully as opposed to created a corrupt binary).
This patch is provided for experimentation, with no warranties. Review the script before running it.
#!/usr/bin/env node
/** * opencode-fps-patch.js - * This script creates a modified copy of the `opencode` binary, * but with a different target and max FPS "patched" (a.k.a. hacked) in. * * * ## Background * * - OpenCode is a great open-source TUI coding agent. * - OpenCode TUI, by default, runs and renders at 60 FPS, hard-coded. * - Even a basic animation or spinner that keeps the renderer live wastes * _immense_ amounts of CPU cycles, energy, and network bandwidth. * - There is no option to change FPS in the application itself. * - There are multiple open and closed issues about this, but no resolutions. * * * Main related issues: * - https://github.com/anomalyco/opencode/issues/13817 * - https://github.com/anomalyco/opencode/issues/19466 * * Possibly related issues: * - https://github.com/anomalyco/opencode/issues/811 * - https://github.com/anomalyco/opencode/issues/6172 * - https://github.com/anomalyco/opencode/issues/11119 * - https://github.com/anomalyco/opencode/issues/13673 * - https://github.com/anomalyco/opencode/issues/22017 * * * ## Should You Use This Patch? * * Decision tree: * - Could you fork OpenCode, patch the source, and recompile it? Yes. * - Should you do that? Yes. * - Are you lazy and want a quick hack? Also yes. * - Does this come with any warranties? Absolutely not. * - Is it safe? Sure. :homer-bush: * - Should you use this? No. Compile from source. * - Can you use it? Yes. Read what it does, and decide for yourself. * * * ## How This Works * * First, see: * https://github.com/anomalyco/opencode/blob/dev/packages/tui/src/app.tsx * * That file does a few things, including (abbreviated) setting up OpenTUI: * - `import { createCliRenderer, MouseButton } from "@opentui/core"` * - `createCliRenderer({ ... targetFps: 60, gatherStats: false, ... })` * * In the compiled `opencode` binary, that ends up minified to a single string: * - `targetFps:60,gatherStats:!1` (27 characters / bytes) * * While `targetFps` limits continuous/live rendering, * `maxFps` (notably missing) limits immediate `requestRender()` frames. * Setting both is required and applies the same cap to both rendering paths. * * But `gatherStats` defaults to `false` in OpenTUI. So we don't need that. * We overwrite this 27 byte string with a new string of the **same length**, * but with our desired FPS and `maxFps` set to the same value. * * That is all this patch does. It makes a copy of the `opencode` binary, * and overwrites that string with a new one, containing the desired FPS. * * * ## How to Use This * * 1. Make sure you have Node.js installed. * 2. Save this script to a file, e.g. `opencode-fps-patch.js`. * 3. Run `node opencode-fps-patch.js <1-99>`, * e.g. `node opencode-fps-patch.js 10`. * 4. The new binary is written to, * e.g. `/usr/local/bin/opencode-fps-10`. * * * ## Which OpenCode Versions is this Compatible With? * * - This is a binary patch. * - This is Linux/Docker oriented; it will not work with signed executables. * - It was tested against the compiled `opencode` in official Docker image: * `ghcr.io/anomalyco/opencode` (originally developed on v1.17.15) * - It may work with other versions, but it is not guaranteed. * * * ## Disclaimer / License * * - Read the code below. It is a simple binary patch, but it is still a hack. * - Use at your own risk. * - Absolutely no warranties, express or implied. * - This code is CC0-1.0 public domain. No rights reserved. * * @typedef {string} _ABOUT_THIS_PATCH */constfs=require("fs");// Source and destination executable paths (adjust as needed):constCONFIG={SRC: ()=>`/usr/local/bin/opencode`,// (existing binary)DST: (fps)=>`/usr/local/bin/opencode-fps-${fps}`,// (created binary)}// Parse FPS arg:const{fps}=(()=>{constargs=process.argv.slice(2);constrawFps=args[0];if(args.length!==1||!/^(?:0?[1-9]|[1-9]\d)$/.test(rawFps??"")){console.error("Usage: opencode-fps-patch <1-99>");process.exit(1);}return{fps: Number(rawFps)};})();// Prepare and double-check patch plan:const{oldBytes, newBytes}=(()=>{constoldBytes=Buffer.from("targetFps:60,gatherStats:!1",'ascii');constnewBytes=Buffer.from(`targetFps:${fps},maxFps:${fps}`.padEnd(oldBytes.length," "),'ascii');if(oldBytes.length!==newBytes.length){thrownewError("Replacement must be same length as original");}return{oldBytes, newBytes};})();// Read source binary and patch bytes in buffer:const{src, patchedSrc, mode}=(()=>{constsrc=CONFIG.SRC();constmode=fs.statSync(src).mode&0o777;constdata=fs.readFileSync(src);constoffset=data.indexOf(oldBytes);if(offset<0||data.indexOf(oldBytes,offset+1)>=0){thrownewError("Expected exactly one matching byte sequence");}newBytes.copy(data,offset);return{src,patchedSrc: data, mode};})();// Write new binary with replacement:const{dst}=(()=>{constdst=CONFIG.DST(fps);consttmp=`${dst}.tmp-${process.pid}`;try{fs.writeFileSync(tmp,patchedSrc,{flag: 'wx', mode });fs.renameSync(tmp,dst);}finally{if(fs.existsSync(tmp)){fs.unlinkSync(tmp);}}return{dst};})();// Happy:console.log(`Patched: ${src} -> ${dst}`);
Activity
jmagder commentedon Feb 16, 2026
Its your lucky day! I just opened a PR to do just this because I was annoyed my CPU fan was too loud. :D You can check it out here:
#13901
Please let me know if it helps you! Hopefully it'll be merged before you see this. :D
github-actions commentedon Apr 22, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.
jmagder commentedon Apr 22, 2026
I guess this never got looked at? I can't reopen the issue, and I have a PR solution!
dkamins commentedon Jul 22, 2026
This problem still exists, and the feature suggestion is good.
(The suggested PR seems orthogonal and related to the web interface. I believe the original feature request is about the TUI, as is my interest.)
More Detailed Proposal
OpenCode currently initializes its TUI renderer with hard-coded
targetFps: 60, while leaving OpenTUI's separatemaxFpscap at its default.See: https://github.com/anomalyco/opencode/blob/dev/packages/tui/src/app.tsx
On systems where an animation or spinner keeps the renderer live, lowering both values substantially reduces CPU usage (the app is internally walking a huge scene graph 60 times per second) as well as remote-terminal traffic.
Something as simple as an environment variable would suffice, e.g.:
OPENCODE_TUI_FPS=10 opencodedkamins commentedon Jul 22, 2026
Unsupported workaround: Binary patch OpenCode TUI to throttle FPS
(targets binary in official Docker image
ghcr.io/anomalyco/opencode)While native FPS configuration is being considered...
I developed a binary-patch workaround that makes a copy of the
opencodebinary with bothtargetFpsandmaxFpsset as specified. You can easily make separate binaries for different uses, e.g.opencode-fps-30,opencode-fps-10,opencode-fps-1, etc.At some point in the future when OpenCode changes the relevant code, this patch will no longer work (but it should fail gracefully as opposed to created a corrupt binary).
This patch is provided for experimentation, with no warranties. Review the script before running it.