Skip to main content
ansicode

DECSET ?2026 — Synchronized update mode

Buffer screen updates until you signal end-of-frame — eliminates flicker on full repaints.

Byte forms

Every common string-literal form so you can paste-and-search either direction.

\\x1b[\x1b[?2026h (begin frame) \x1b[?2026l (end frame)
\\033[\033[?2026h / \033[?2026l
\\e[\e[?2026h / \e[?2026l
ESC [ESC [ ? 2 0 2 6 h / l
hex1b 5b 3f 32 30 32 36 68 / 6c

Description

Originally an iTerm2 + contour proposal, now adopted by kitty, wezterm, foot, ghostty, Windows Terminal, mintty, alacritty (1.7+), and tmux as a pass-through. Wrap a full-screen redraw between \x1b[?2026h (begin synchronized update) and \x1b[?2026l (end) and the terminal will hold rendering until the l arrives, then paint the final state once — eliminating the half-painted frames that plague neovim, helix, tui-rs, ratatui, and similar apps over slow PTYs (especially over SSH). Terminals that don't recognize ?2026 simply paint as bytes arrive, so emitting the pair is safe. Apps that want to detect support should query with the DECRQM request \x1b[?2026$p and parse the reply. Recommended max in-frame time is ~100 ms — terminals abort the synchronized state on timeout to avoid a stuck screen.

Spec citation: Synchronized Output Mode (contour spec) / Mode 2026

Examples

bash
printf '\033[?2026h'   # begin frame\n# … emit the full repaint here …\nprintf '\033[?2026l'   # end frame -> painted atomically
python
import sys\nsys.stdout.write('\x1b[?2026h'); redraw(); sys.stdout.write('\x1b[?2026l')
go
fmt.Print("\x1b[?2026h"); redraw(); fmt.Print("\x1b[?2026l")
javascript
process.stdout.write('\x1b[?2026h'); redraw(); process.stdout.write('\x1b[?2026l')
c
printf("\x1b[?2026h"); redraw(); printf("\x1b[?2026l");

Used in

Real-world tools that emit this sequence — anchors the bytes to commands you've already used.

  • Helix editorHelix wraps every full redraw in `\x1b[?2026h` … `\x1b[?2026l` so the terminal buffers the frame and flips atomically — eliminates the tearing band when scrolling a large file in a wide-pane layout
  • neovim (≥ 0.10) atomic redrawsnvim probes via DECRQM `\x1b[?2026$p`; if mode-2 / mode-3 is reported, every `redraw` cycle gets wrapped in BSU / ESU — visible win on resize, statusline updates, and `:diffupdate` on side-by-side diffs
  • Ghostty, kitty, alacritty (0.13+), WezTermall four advertise DECSET 2026 support — terminal queues every byte until ESU lands, then commits the whole frame in one paint; without the support advert, Helix / nvim degrade to per-cell repaint
  • btop, btm, gtop dashboard TUIshigh-FPS resource monitors (btop / btm) wrap their inner-loop redraws in BSU / ESU so the CPU / RAM bars never tear mid-update — without sync, terminals with slow scrollback redraw show a visible split between old and new sparkline columns
  • tmux refresh, zellij pane resizemultiplexers wrap pane-redraw bursts in BSU / ESU on resize and on `refresh-client` so each pane lands atomically — without sync, splitting a window briefly shows half-drawn panes side-by-side

Frequently asked

Short answers to the questions developers actually search for this sequence.

What problem does DECSET ?2026 (synchronized output) actually solve?
Tear during full-screen redraws. When a TUI rewrites every cell in a frame, the terminal can paint mid-update — the user sees the top half new and the bottom half old for a frame or two. Wrapping the redraw in \x1b[?2026h\x1b[?2026l tells the terminal to buffer cell updates and flip the whole frame atomically, the same idea as a double-buffered SDL/OpenGL swap. Helix, Neovim, Ghostty's own TUIs, and modern TUI frameworks all enable it when the terminal advertises support.
How do I detect whether the terminal supports ?2026 before enabling it?
Query with DECRQM: \x1b[?2026$p. Supporting terminals reply \x1b[?2026;1$y (mode set) or \x1b[?2026;2$y (reset, but recognised). Unrecognised modes reply \x1b[?2026;0$y or don't reply at all — both mean *don't use*. Read non-blocking with a 50ms timeout; if no reply, assume unsupported. Kitty, ghostty, WezTerm, Mintty, foot, and iTerm2 (≥3.5) all support it; xterm, gnome-terminal, konsole, and the Linux console currently do not.

Terminal support

xterm
no
Linux console (fbcon)
no
macOS Terminal.app
no
iTerm2
yes
Windows Terminal
yes
cmd.exe / ConPTY
no
kitty
yes
alacritty
yes
WezTerm
yes
Ghostty
yes
GNOME Terminal
partial
Konsole
yes
tmux
yes
GNU screen
no

Related sequences

In the family cookbook

DEC cookbook · 6. Focus events & sync update — `?1004`, `?2026`