Slow perceived response time due to excessive storage writes during streaming #8063

Open
opened 2026-02-16 18:09:03 -05:00 by yindo · 3 comments
Owner

Originally created by @taetaetae on GitHub (Jan 30, 2026).

Originally assigned to: @rekram1-node on GitHub.

Description

During streaming responses, OpenCode writes to storage (JSON files) on every reasoning-delta event. With fast streaming APIs, this results in hundreds of file writes per second.

Impact

  • High I/O overhead from frequent file system operations
  • Increased latency between receiving content and displaying it
  • Slower perceived response time compared to native CLI tools (e.g., kiro-cli)

Root Cause

In processor.ts, every delta triggers a storage write:

case "reasoning-delta":
  if (part.text) await Session.updatePart({ part, delta: value.text })

Session.updatePart calls Storage.write which writes to the file system on every call.

Proposed Solution

Throttle storage writes during streaming:

  • Accumulate content in memory
  • Only flush to storage every 50ms
  • Always flush on reasoning-end

Environment

  • OpenCode version: latest
  • Tested with Kiro API streaming responses
Originally created by @taetaetae on GitHub (Jan 30, 2026). Originally assigned to: @rekram1-node on GitHub. ## Description During streaming responses, OpenCode writes to storage (JSON files) on every `reasoning-delta` event. With fast streaming APIs, this results in hundreds of file writes per second. ## Impact - High I/O overhead from frequent file system operations - Increased latency between receiving content and displaying it - Slower perceived response time compared to native CLI tools (e.g., kiro-cli) ## Root Cause In `processor.ts`, every delta triggers a storage write: ```typescript case "reasoning-delta": if (part.text) await Session.updatePart({ part, delta: value.text }) ``` `Session.updatePart` calls `Storage.write` which writes to the file system on every call. ## Proposed Solution Throttle storage writes during streaming: - Accumulate content in memory - Only flush to storage every 50ms - Always flush on `reasoning-end` ## Environment - OpenCode version: latest - Tested with Kiro API streaming responses
yindo added the perf label 2026-02-16 18:09:03 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 30, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #6172: High CPU usage (100%+) during LLM streaming in long sessions due to O(n) text buffer rendering

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Jan 30, 2026): This issue might be a duplicate of existing issues. Please check: - #6172: High CPU usage (100%+) during LLM streaming in long sessions due to O(n) text buffer rendering Feel free to ignore if none of these address your specific case.
Author
Owner

@taetaetae commented on GitHub (Jan 30, 2026):

Thanks for flagging #6172! After reviewing it, I believe these are different issues addressing different bottlenecks:

Aspect #6172 (OpenTUI) #11329 (This issue)
Root cause O(n) text buffer rendering in Zig renderer Excessive file I/O on every streaming delta
Hot path textBufferViewMeasureForDimensionsmmap Session.updatePartStorage.writeBun.write
Layer TUI rendering (OpenTUI native) Application logic (TypeScript)
Fix location OpenTUI Zig code processor.ts

#6172 addresses CPU usage from re-rendering the entire text buffer on every update.

This issue addresses I/O overhead from writing to disk on every streaming delta in processor.ts:

case "reasoning-delta":
  await Session.updatePart({ part, delta: value.text })  // File write every delta

Both optimizations are complementary - fixing one doesn't fix the other. The PR #11328 addresses this specific storage I/O bottleneck.

@taetaetae commented on GitHub (Jan 30, 2026): Thanks for flagging #6172! After reviewing it, I believe these are **different issues** addressing different bottlenecks: | Aspect | #6172 (OpenTUI) | #11329 (This issue) | |--------|-----------------|---------------------| | **Root cause** | O(n) text buffer rendering in Zig renderer | Excessive file I/O on every streaming delta | | **Hot path** | `textBufferViewMeasureForDimensions` → `mmap` | `Session.updatePart` → `Storage.write` → `Bun.write` | | **Layer** | TUI rendering (OpenTUI native) | Application logic (TypeScript) | | **Fix location** | OpenTUI Zig code | `processor.ts` | #6172 addresses CPU usage from **re-rendering** the entire text buffer on every update. This issue addresses I/O overhead from **writing to disk** on every streaming delta in `processor.ts`: ```typescript case "reasoning-delta": await Session.updatePart({ part, delta: value.text }) // File write every delta ``` Both optimizations are complementary - fixing one doesn't fix the other. The PR #11328 addresses this specific storage I/O bottleneck.
Author
Owner

@buildkloe commented on GitHub (Feb 1, 2026):

Confirming significant disk I/O impact

Image

Experiencing 11.2 MB/s sustained writes from OpenCode (desktop and CLI) during normal usage or idle state - more than any other process on the system. This is visible in macOS Activity Monitor as continuous disk activity even no operation at all.

I'm a bit worry about the impact:
SSD wear from constant writes during every session
Competes with other disk I/O (spotlight indexing)
Battery drain on laptops
Would love to see FIX/PR #11328 prioritized.

Thank you!

@buildkloe commented on GitHub (Feb 1, 2026): Confirming significant disk I/O impact <img width="376" height="261" alt="Image" src="https://github.com/user-attachments/assets/1ca7d1be-f5d1-475c-9bdc-c7191ed8ad7f" /> Experiencing 11.2 MB/s sustained writes from OpenCode (desktop and CLI) during normal usage or idle state - more than any other process on the system. This is visible in macOS Activity Monitor as continuous disk activity even no operation at all. I'm a bit worry about the impact: SSD wear from constant writes during every session Competes with other disk I/O (spotlight indexing) Battery drain on laptops Would love to see FIX/PR #11328 prioritized. Thank you!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#8063