Built-in Undo vs. undo-tree in Emacs: A Decision Guide
A decision guide comparing Emacs' native undo with the undo-tree package, covering memory, persistence, keybindings, and large-file performance.
08 May 2026, 01:09 UTC

The decision: native undo or undo-tree
When you customize Emacs, one of the first infrastructure choices is how undo behaves. The built-in system is always present and stores changes in a buffer-local undo list. The external undo-tree package replaces that list with a branching tree, adds a visualizer, and can persist history to disk. The right choice depends on your buffer sizes, whether you need cross-session undo, and how much memory and disk space you can spare.
Side-by-side comparison
| Consideration | Built-in undo | undo-tree |
|---|---|---|
| Availability | Always active; no packages required | Requires installation from a package archive |
| Data structure | Buffer-local undo list | In-memory tree with branches |
| Cross-session persistence | None; history is lost when the buffer is killed | Optional; writes a per-buffer history file (e.g., .undo-tree) |
| Navigation | Linear undo/redo | Visual tree, branching, diff view, and replay |
| Large-buffer performance | Generally more responsive above ~10 MB | May lag because the tree grows in memory |
| Keybindings | Standard C-/ (undo); no dedicated redo key, so redoing requires interrupting the undo chain | Provides dedicated C-/ and C-\ bindings for undo and redo |
| External files | None | History directory can accumulate files |
Trade-offs that matter in practice
Memory and latency
The native undo list is compact and synchronous. Every edit appends to the list, and undo replays it immediately. undo-tree maintains a separate tree structure. For small and medium buffers the overhead is usually acceptable, but for very large files the tree representation can consume more memory and introduce noticeable input latency.
Persistence versus clutter
If you close Emacs and reopen a file, the built-in undo history is gone. undo-tree can save history to disk and restore it, which helps when you accidentally kill a buffer or restart your editor. The cost is a directory of history files that can grow large for heavily edited buffers; you must clean it up periodically.
Keybinding conflicts
Because undo-tree overrides C-/ and C-\, any existing custom bindings for those keys will stop working unless you remap them. If your workflow depends on those keys for other commands, weigh that cost carefully.
Concrete configuration
The following init.el snippet enables undo-tree globally, saves history, and stores it under a dedicated directory inside your Emacs configuration folder. Run it by evaluating the buffer or restarting Emacs.
;; init.el
(require 'package)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
(unless (package-installed-p 'undo-tree)
(package-refresh-contents)
(package-install 'undo-tree))
(global-undo-tree-mode 1)
(setq undo-tree-auto-save-history t)
(setq undo-tree-history-directory-alist
`(("." . ,(expand-file-name "undo-tree-history"
user-emacs-directory))))
Location and permissions: Edit init.el in your user Emacs directory (commonly ~/.emacs.d/). No elevated privileges are needed. The snippet assumes MELPA is already in your package-archives; if you use a different archive, adjust the URL. Note that package-refresh-contents contacts remote servers and may take a few seconds.
Expected checks: After restarting, open any file, type some text, and press C-/. You should see the undo-tree visualizer respond to branching edits. Press C-x u to open the tree view.
Validation and diagnostics
- Basic operation. Open a text file, insert a line, undo with
C-/, then redo withC-\. Confirm the buffer returns to the edited state. - Visualizer. Press
C-x u. Verify that the tree shows separate branches when you undo an edit and then type new text. - Persistence. Save the file, close Emacs completely, reopen Emacs, and revisit the file. If
undo-tree-auto-save-historyis active, the tree should still contain your earlier edits. - Large-file comparison. Open a file larger than 10 MB, make several edits, and note responsiveness. Then disable the package temporarily with
M-x global-undo-tree-modeand repeat. Compare latency and memory use with your system monitor. - Disk usage. Inspect the directory named in
undo-tree-history-directory-alist. Look for.undo-treefiles and note their sizes.
Limitations and cleanup
- History files are not compressed by default and can become large. Delete stale files from the history directory when they are no longer needed.
- If you use
C-/orC-\for other commands, remap them after loadingundo-treeor accept the override. - For temporary or scratch buffers where undo history is unnecessary, avoid enabling
global-undo-tree-modeindiscriminately; enable the mode selectively or toggle it off in those buffers.
Rollback
If you decide to revert to the built-in system, disable the global mode, uninstall the package, and remove the history directory:
;; In init.el, comment out or remove:
;; (global-undo-tree-mode 1)
;; In Emacs:
M-x global-undo-tree-mode
M-x package-delete [RET] undo-tree
;; In a shell, inside ~/.emacs.d/:
rm -rf undo-tree-history
After rollback, C-/ returns to the standard Emacs undo command.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.