Office
Output buffering and replay for long-running terminal sessions
A replay buffer turns reconnect from “start over” into “continue”: keep a bounded ring of recent output, replay it on attach, then resume live streaming.
Published: 2026-01-02 · Last updated: 2026-01-04
Direct answer
Output replay works when you treat terminal output as a bounded stream: store the last K output chunks per session (ring buffer), replay those chunks in-order when a client attaches, and then switch to live streaming. The buffer is not a log system; it is an operator continuity feature that makes reconnect survivable on mobile networks.
Mechanism (the minimal contract)
1) Choose what you are buffering
Buffer the same bytes you would have streamed live:
- terminal output bytes
- in the exact order they were observed
Do not attempt to parse ANSI or “re-render” into structured events. The terminal emulator is the renderer.
2) Bound memory by design
The buffer must be bounded by a clear policy:
- max chunks:
K - max bytes per chunk:
B - optional max total bytes:
K * B
When the buffer is full, drop the oldest chunks (ring buffer).
This avoids the two common failures:
- “it works until it OOMs”
- “we added replay, and now the server is a logging service”
3) Replay happens before live streaming
Attach flow should be deterministic:
- client attaches to
session_id - server sends buffered chunks (oldest -> newest)
- server begins sending live output
If you interleave replay and live output, the operator can see time-travel (older output after newer output), which breaks trust.
4) Buffer even when no client is attached
The feature matters when the client is offline. If you stop buffering when the connection drops, reconnect still loses output.
Buffering should be coupled to the terminal session lifecycle, not the connection lifecycle.
5) Reset semantics are explicit
Decide what happens when the operator requests “clear”:
- clearing the screen is a terminal action (ANSI), not a buffer action
- clearing the buffer is a server action
If you implement both, expose both explicitly; otherwise operators will misinterpret what “clear” did.
Common failure modes
Failure mode: “Buffer grows unbounded”
Symptom: memory climbs over hours/days.
Root cause: buffer is a Vec with no cap, or chunk sizes are unbounded.
Fix: fixed chunk sizes; ring buffer with strict limits; enforce maximums on write.
Failure mode: “Replay duplicates output”
Symptom: operator sees the same output twice after reconnect.
Root cause: you replay the full buffer and also leave the terminal emulator’s local scrollback intact, or you attach twice and replay twice.
Fix: define UI behavior (clear local terminal on attach vs keep); keep attach idempotent; ensure replay happens only once per attach event.
Failure mode: “Replay misses the exact interval you care about”
Symptom: operator reconnects and the buffer is “too small” to capture the outage window.
Root cause: limits are too low, or output is chunked in a way that wastes buffer capacity.
Fix: tune chunk size and K for your workload; prefer smaller chunks with a reasonable cap so the buffer captures more timeline.
Failure mode: “Replay breaks ordering”
Symptom: output appears out of order, or prompts appear before the command echoed.
Root cause: concurrency bugs: multiple writers to the buffer without ordering, or live stream starts before replay completes.
Fix: single ordered write path per session; replay first; then open live stream.
How to verify
-
Offline interval capture
- Start a long command that prints periodically.
- Disconnect for 10–30 seconds.
- Expected: on reconnect, you see the interval’s output (within buffer capacity).
-
Ordering
- Run a command that emits predictable sequences.
- Expected: replay shows the same ordering as live.
-
Bounded memory
- Force high output volume.
- Expected: memory stays within the configured cap; oldest output drops.
Link up (pillar)
Read next (sibling)
Scope boundary
This note describes the buffer/replay contract and its verification. It does not attempt to cover full auditing, log retention, or multi-tenant security.