Skip to content

⚡ Bolt: Throttle TUI refresh to 20 FPS#96

Open
milhy545 wants to merge 1 commit intomainfrom
bolt/throttle-ui-refresh-7404175556088628426
Open

⚡ Bolt: Throttle TUI refresh to 20 FPS#96
milhy545 wants to merge 1 commit intomainfrom
bolt/throttle-ui-refresh-7404175556088628426

Conversation

@milhy545
Copy link
Owner

@milhy545 milhy545 commented Feb 5, 2026

💡 What: Implemented throttling in InteractiveCLI's _stream_handler to limit UI updates to every 0.05 seconds (20 FPS).
🎯 Why: High-speed LLM streaming (50+ tokens/sec) caused 1:1 UI refreshes, leading to excessive CPU usage and rendering overhead.
📊 Impact: Reduces UI refresh calls by >95% during fast streaming (e.g., 50 calls -> 2 calls in 100ms test), significantly lowering CPU load.
🔬 Measurement: Verified with tests/repro_throttling.py (mocked stream test).


PR created automatically by Jules for task 7404175556088628426 started by @milhy545

- Limits `_refresh_live` calls to ~20 FPS (0.05s interval) in `cli_interactive.py`.
- Prevents CPU spikes when using fast providers (e.g. Grok, Gemini).
- Verified with reproduction script showing >95% reduction in draw calls.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

🤖 Hi @milhy545, I've received your request, and I'm working on it now! You can track my progress in the logs for more details.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @milhy545, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a performance optimization to the interactive command-line interface. By limiting the frequency of UI updates, it significantly reduces CPU load and rendering overhead, especially when processing rapid streams of data from large language models.

Highlights

  • TUI Refresh Throttling: Implemented a 20 FPS throttle for the TUI refresh in InteractiveCLI's _stream_handler to prevent excessive CPU usage during high-speed LLM streaming.
Changelog
  • src/mycoder/cli_interactive.py
    • Added a last_refresh_time variable initialized to 0.0 to track the timestamp of the last UI refresh.
    • Modified the _stream_handler function to include last_refresh_time in its nonlocal scope.
    • Introduced a conditional check within _stream_handler to only call self._refresh_live() if at least 0.05 seconds have elapsed since the previous refresh, effectively capping the refresh rate at 20 frames per second.
    • Included a comment explaining the "Bolt Optimization" for throttling UI updates.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a performance optimization by throttling TUI refreshes to 20 FPS during LLM streaming, which effectively reduces CPU usage. The implementation is sound. I've provided a couple of suggestions to improve the robustness and readability of the throttling logic, and also pointed out a minor UI issue where the last part of a stream might not be rendered, with a recommendation on how to fix it.

Comment on lines +1834 to +1839
# Bolt Optimization: Throttle UI updates to ~20 FPS to prevent
# high CPU usage when LLM streams very fast (e.g. 50+ tokens/sec).
now = time.time()
if now - last_refresh_time >= 0.05:
self._refresh_live()
last_refresh_time = now
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This throttling is a great optimization for performance. However, it introduces a small risk: if the stream ends shortly after a refresh, the final chunks of text might not be rendered in the "Thinking" panel before it's cleared. This can make it seem like the stream was cut off.

To ensure the final streamed state is always visible to the user, I recommend adding a final self._refresh_live() call after the streaming process is complete but before the UI is cleaned up. A good place for this would be in the finally block that wraps the await self.coder.process_request(...) call, just before self.activity_panel.clear_thinking().

Comment on lines +1836 to +1839
now = time.time()
if now - last_refresh_time >= 0.05:
self._refresh_live()
last_refresh_time = now
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This throttling logic is a great addition. Two small improvements could make it more robust and readable:

  1. Use time.monotonic(): For measuring time intervals, time.monotonic() is more reliable than time.time() because it's not affected by system clock changes.
  2. Define a constant for the interval: The value 0.05 is a magic number. Defining it as a named constant (e.g., UI_REFRESH_INTERVAL) makes the code's intent clearer (targeting ~20 FPS) and easier to modify. You could define this constant at the top of the process_chat method.
Suggested change
now = time.time()
if now - last_refresh_time >= 0.05:
self._refresh_live()
last_refresh_time = now
now = time.monotonic()
if now - last_refresh_time >= 0.05:
self._refresh_live()
last_refresh_time = now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant