Synchronized Output (DEC mode 2026)
Pause rendering while a program writes a batch of updates, then commit them as a single frame.
- 0x1B
- ESC
- 0x5B
- [
- 0x3F
- ?
- 0x32 0x30 0x32 0x36
- 2026
- 0x68
- h
- 0x1B
- ESC
- 0x5B
- [
- 0x3F
- ?
- 0x32 0x30 0x32 0x36
- 2026
- 0x6C
- l
Synchronized output is a DEC private mode that lets a TUI tell the
terminal "I am about to write a batch of updates; please do not render
intermediate states". When the mode is set the renderer pauses; when it is
reset the renderer resumes and the next frame reflects all of the writes
in between as a single coherent update. This eliminates the screen tearing
that fullscreen TUIs (e.g. btm, claude, htop, fast progress UIs)
can otherwise exhibit on high-performance terminals like Wintty.
The protocol was originally proposed by the Contour project and is now widely supported.
| Sequence | Action |
|---|---|
CSI ? 2026 h | Begin a synchronized update; pause rendering. |
CSI ? 2026 l | End the synchronized update; resume rendering. |
Like every other DEC private mode, support can be queried with a DECRQM request and the mode can be saved or restored with the standard DEC mode-save / mode-restore sequences.
When synchronized_output is set, the renderer's frame loop short-circuits
and skips drawing while the mode remains active:
if (state.terminal.modes.get(.synchronized_output)) {
log.debug("synchronized output started, skipping render", .{});
return;
}
Writes from the application continue to update the in-memory grid state; only the GPU-side rendering is paused.
A misbehaving or crashed application could leave the terminal stuck in the synchronized state, never rendering again. To prevent that, Wintty starts a safety timer when synchronized output is enabled. If the application does not reset the mode within the timeout, the termio thread forces it off and the renderer resumes.
Wintty also forcibly clears the synchronized state on certain terminal-disrupting events so the user is never stuck staring at a stale frame:
- A resize clears synchronized output. The spec allows the terminal to break the sync on resize, and Wintty does so to keep size reports and the new viewport in sync immediately.
- A full terminal reset clears synchronized output as part of the general reset path.
When a program redraws the screen with many small writes, a sufficiently
fast renderer (Wintty) may sample the grid partway through and present a
half-updated frame. The user sees tearing. With synchronized output, the
program brackets the redraw with CSI ? 2026 h and CSI ? 2026 l and
the renderer simply waits.
For application authors there is a more in-depth troubleshooting and adoption guide at Synchronized Output that includes references to known offenders and a recommended emit pattern.
# Begin synchronized update
printf '\033[?2026h'
# ...write many updates...
printf '\033[H\033[2J' # clear screen
printf '\033[1;1Hheader\n'
printf '\033[2;1Hrow 1\n'
printf '\033[3;1Hrow 2\n'
# Commit
printf '\033[?2026l'
The user only ever sees the final state of the three writes, never an intermediate half-redrawn screen.
- Synchronized Output troubleshooting: user-facing guide and a list of known affected programs.
- The original Contour synchronized output proposal for the authoritative protocol definition.