Terminal · Technology

How the Terminal
Actually Works

From keypress to pixel: the PTY layer, escape codes, GPU rendering, and the engineering stack that makes a 60-year-old interface screamingly fast in 2025.

01 / Architecture

The PTY — Pseudo-Terminal Layer

When you type in a terminal emulator, you're not talking directly to bash. A kernel abstraction called a Pseudo-Terminal (PTY) sits between them, emulating a physical serial line. Understanding PTY is understanding the entire terminal stack.

Full Terminal Stack — Keypress to Process
You
keyboard
Terminal Emulator
Alacritty / iTerm2 / etc
PTY Master
/dev/ptmx
PTY Slave
/dev/pts/N
Shell
bash / zsh / fish
Child Process
vim / git / etc
← Output travels back: Process → Shell → PTY Slave → Kernel TTY Line Discipline → PTY Master → Terminal Emulator → GPU Render → Screen
The TTY line discipline in the kernel handles canonical mode processing — buffering lines, processing backspace, Ctrl+C signals, and flow control (XON/XOFF). This is why pressing Backspace deletes a character before your shell sees the input: the kernel handles it transparently.
# Inspect open PTY devices on your system $ ls /dev/pts/ 0 1 2 3 ptmx # See which process owns each PTY $ ps aux | grep pts user 1234 bash pts/0 user 5678 vim pts/0 user 9012 bash pts/1 # The PTY slave is just a file — write to it directly $ echo "hello other terminal" > /dev/pts/1 hello other terminal ← appears in the other window # Check terminal settings (line discipline config) $ stty -a speed 38400 baud; rows 40; columns 200 intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = undef; eol2 = undef; swtch = undef; ...
Terminal Emulator Renders pixels, handles input, speaks VT100
↕ reads/writes PTY master fd
Kernel: PTY + TTY Line Discipline Buffers, signals, echo, flow control
↕ file descriptor /dev/pts/N
Shell (bash / zsh / fish) Job control, readline, completion
↕ fork/exec, pipe, dup2
Child Process (vim, git, curl…) stdin/stdout/stderr → PTY slave

02 / Protocol

ANSI Escape Codes — The Terminal's Language

Everything you see in a terminal — colors, bold text, cursor movement, clearing the screen — is controlled by ANSI escape sequences: printable bytes starting with ESC (\x1b, byte 27). Standardized by ANSI X3.64 in 1979 based on the DEC VT100, these sequences are understood by every terminal emulator ever made.

# ESC = \x1b = \e = byte 0x1B = octal \033 # SGR: Select Graphic Rendition — colors and styles $ printf '\e[1mBOLD\e[0m \e[3mITALIC\e[0m \e[4mUNDERLINE\e[0m\n' BOLD ITALIC UNDERLINE # 3-bit colors (original 8) $ printf '\e[31mRED\e[0m \e[32mGREEN\e[0m \e[34mBLUE\e[0m\n' RED GREEN BLUE # 256-color mode (since xterm 88, 1999) $ printf '\e[38;5;196mBRIGHT RED\e[0m \e[38;5;46mBRIGHT GREEN\e[0m\n' # 24-bit truecolor (since ~2012, ~16 million colors) $ printf '\e[38;2;255;100;0mORANGE\e[0m \e[38;2;130;80;255mPURPLE\e[0m\n' # Cursor movement $ printf '\e[2J' # clear entire screen $ printf '\e[H' # move cursor to top-left (row 1, col 1) $ printf '\e[10;20H' # move cursor to row 10, column 20 $ printf '\e[5A' # move cursor 5 rows up $ printf '\e[?25l' # hide cursor $ printf '\e[?25h' # show cursor # Window title (xterm extension, widely supported) $ printf '\e]0;My Terminal Title\a'

The 16 standard ANSI colors (8 normal + 8 bright). Every terminal emulator supports these — they've been standard since 1979:

000
Black
001
Red
002
Green
003
Yellow
004
Blue
005
Magenta
006
Cyan
007
White
008
Br.Black
009
Br.Red
010
Br.Green
011
Br.Yellow
012
Br.Blue
013
Br.Magenta
014
Br.Cyan
015
Br.White

03 / Shell

The Shell — The Terminal's Brain

The terminal emulator is just a window. The shell is where the intelligence lives: command parsing, job control, tab completion, history, variables, scripting, and the most powerful text-processing pipeline ever designed.

bash (1989)

GNU Bourne-Again Shell. The universal default. ~/.bashrc runs on a billion machines. POSIX-compliant, array support, arithmetic expansion, and 35 years of tribal knowledge baked in.

zsh (1990)

The power user's shell. Better tab completion, theme support (oh-my-zsh), spelling correction, right-side prompts, and the default on macOS since 10.15 Catalina. ~/.zshrc

fish (2005)

Friendly Interactive Shell. Autosuggestions out of the box, web-based config, no POSIX compatibility (intentionally). Makes the terminal approachable for newcomers without sacrificing power.

Pipelines

The terminal's superpower. ps aux | grep nginx | awk '{print $2}' | xargs kill. Chain any command to any other. One-liners that would take 100 lines of Python. Unix philosophy: do one thing well.

Readline / Editing

Ctrl+R reverse history search. Ctrl+A/E line start/end. Alt+. last argument. !! last command. The keyboard shortcuts that make terminal experts 10× faster than anyone else.

Job Control

Ctrl+Z suspends. bg backgrounds. fg foregrounds. & runs in background. nohup survives logout. disown detaches from shell. Run 20 things at once.

# The pipeline: the terminal's killer feature # "Who are my top 10 most-requested URLs today?" $ cat /var/log/nginx/access.log \ | grep "$(date +%d/%b/%Y)" \ | awk '{print $7}' \ | sort | uniq -c | sort -rn \ | head -10 4821 /api/v2/users 2134 / 987 /static/app.js ...one line of shell. zero lines of Python.

04 / Rendering

GPU Rendering — The Terminal Meets Modern Hardware

Traditional terminal emulators render on the CPU: measure each glyph, paint pixels in a software framebuffer, copy to the screen. At 4K resolution with a 144Hz display, this is a bottleneck. GPU-accelerated terminals changed everything.

CPU Rendering (xterm, GNOME Terminal) vs GPU Rendering (Alacritty, Kitty)
CPU PATH (SLOW)
Character data Font rasterizer (FreeType) Cairo / Pango software draw X11 / Wayland compositor Screen (10–20ms lag)
GPU PATH (FAST)
Character data Glyph atlas (GPU texture) GLSL instanced rendering GPU → display direct Screen (<1ms lag)

Glyph Atlas

GPU terminals pre-rasterize every character into a texture atlas on the GPU. Rendering a character means sampling a texture — a single GPU instruction, not a full font render. Entire screens render in microseconds.

Instanced Rendering

One draw call renders thousands of glyphs by sending instance data (position, color, glyph index) to a GLSL shader. Modern GPUs do this in parallel across thousands of shader cores simultaneously.

Subpixel Rendering

LCD panels have R, G, B subpixels. Subpixel antialiasing addresses each independently, tripling effective horizontal resolution. At 4K on a Retina display, text is indistinguishable from print.

Ligature Fonts

Fonts like Fira Code, JetBrains Mono, and Cascadia Code combine character sequences (-> → →, != → ≠) into single glyphs. GPU rendering makes this free. Code becomes readable at a glance.

05 / Encoding

Unicode — The Terminal Goes Global

The original terminal was ASCII: 128 characters, English only. Unicode (1991) assigned a code point to every character in every writing system — over 150,000 characters across 161 scripts. UTF-8 (Ken Thompson & Rob Pike, 1992) made it backward-compatible with ASCII while encoding the full Unicode range.

Unicode in the terminal — 2025
$ echo "Unicode works everywhere now" Japanese: 日本語でターミナル
Arabic: الطرفية الحديثة
Emoji: 🖥️ 💻 ⌨️ 🐧 🦀 🐍 ☁️ 🚀
Math: ∀x ∈ ℝ: x² ≥ 0 · ∫₀^∞ e⁻ˣ dx = 1
Braille: ⠓⠑⠇⠇⠕ ⠺⠕⠗⠇⠙
Box art: ╔══╤══╗ ║ A│ B║ ╠══╪══╣
$ file encoding_test.txt encoding_test.txt: UTF-8 Unicode text

UTF-8 Encoding

Variable-width: ASCII characters use 1 byte (backward compatible), most European characters use 2 bytes, CJK use 3 bytes, emoji use 4 bytes. Designed by Ken Thompson on a napkin at a diner in 1992.

Wide Characters

CJK characters (Chinese, Japanese, Korean) are "double-width" — they occupy 2 terminal columns. The terminal emulator must account for this when calculating cursor positions and line wrapping.

Combining Characters

Some characters modify the character before them (accents, diacritics). e + ◌́ = é. Modern terminals handle combining characters correctly; older ones garble them.

Nerd Fonts

Programmer fonts patched with thousands of icons: git branch (), language icons, Powerline separators (), folder symbols. A Nerd Font turns your shell prompt from text into an information dashboard.

06 / Multiplexing

tmux — Terminal Superpowers

A terminal multiplexer manages multiple terminal sessions inside a single window. Sessions, windows, and panes. Detach and reattach. Survive SSH disconnects. The operational model of every serious backend engineer.

# tmux survival cheatsheet # Prefix key is Ctrl+B by default tmux new-session -s work # new named session tmux attach -t work # reattach from anywhere tmux ls # list all sessions # Inside tmux: Ctrl+B c # new window Ctrl+B % # vertical split Ctrl+B " # horizontal split Ctrl+B ←→↑↓ # navigate panes Ctrl+B z # zoom current pane Ctrl+B d # detach (session stays running) Ctrl+B [ # scroll mode (vi keys) Ctrl+B :resize-pane -R 10 # resize right by 10 cols # Sessions survive SSH disconnect. Come back tomorrow: $ ssh server.example.com $ tmux attach -t work → All your panes exactly as you left them.