Vim Persistent Undo: Architecture Note on Undofile Design and Safety
An architecture note on Vim’s persistent undo (undofile) feature: requirements, minimal design, trust boundaries, operational checks, failure modes, and when the design would need to change.
01 Sept 2026, 17:20 UTC

Requirements
Vim must keep undo history after a editing session ends so that a user can revert changes made in a previous session without losing work. The solution must work across different files, survive Vim restarts, and not introduce security risks from loading untrusted data.
Smallest Suitable Design
For each buffer Vim creates an undo file named <originalfile>.un~ (or just .un~ when the original name cannot be used). The file is stored in a directory chosen by the undodir option. The undo file contains:
- a fixed magic header that identifies the format,
- a sequence of undo blocks describing the edit tree, and
- a checksum to detect truncation or corruption.
When Vim starts editing a file it looks for a matching undo file; if present and valid it loads the blob and reconstructs the in‑memory undo tree, otherwise it starts with an empty tree.
Trust and Data Boundaries
The undo file is treated as pure data: Vim never executes its contents. Safety checks include:
- verifying the magic number matches the expected value,
- ensuring the file size is within a reasonable limit (currently 10 MiB) to avoid allocating excessive memory, and
- refusing to read a file that is world‑writable, because such a file could have been altered by another user.
If any of these checks fail Vim silently discards the undo file and falls back to normal, in‑memory undo for that session.
Operational Checks
During normal operation Vim performs the following steps for each buffer:
- Check
undofileoption; if off, skip undo file handling. - Construct the undo file path from
undodirand the buffer name. - Stat the file: reject if mode shows world‑writable (
002bits). - Open and read the file, verifying the magic header and size.
- If validation passes, parse the undo blocks and populate the undo tree; otherwise ignore the file.
These checks happen before any modification to the buffer, so a malformed undo file cannot corrupt Vim’s internal state.
Failure Modes
- Corruption: Disk errors or concurrent writes can truncate or alter the undo blob. Vim will detect a bad magic or checksum and start a fresh undo tree, causing the user to lose the ability to undo past edits. No crash occurs.
- Privacy leak: Storing undo files in a world‑accessible directory (e.g.,
/tmp) without proper permissions lets other users read the editing history. - Size exhaustion: A deliberately large undo file could cause Vim to refuse loading it (size limit) and fall back to in‑memory undo, which may be unexpected if the user expects persistent undo.
Conditions That Would Change the Design
The current design assumes undo files are static data blobs. If Vim were to:
- support encrypted undo files, the trust boundary would shift to include key management.
- allow sharing undo history across multiple machines, the design would need network transmission and authentication.
- integrate with a version‑control system that stores undo metadata, the file format might become extensible to include VCS identifiers.
In each case the core checks (magic, size, permissions) would remain, but additional validation steps would be added.
Practical Verification
To confirm that persistent undo is working as intended:
- Add the following to your
~/.vimrc(or init.vim for Neovim):set undofile set undodir=~/.vim/undo - Create the undo directory if it does not exist:
mkdir -p ~/.vim/undo. - Open a test file, make several edits, save and exit Vim.
- Restart Vim and open the same file.
- Press
urepeatedly; you should be able to undo the changes made in the previous session. - To verify that Vim ignores unsafe undo files, run:
Observe that Vim behaves as iftouch ~/.vim/undo/test.txt.un~ chmod 666 ~/.vim/undo/test.txt.un~ vim test.txtundofileis disabled (no earlier edits can be undone). - To test corruption handling, truncate an existing undo file with
truncate -s 100 ~/.vim/undo/test.txt.un~and reopen the file; Vim will start with a clean undo tree.
These steps let you confirm the design’s guarantees without relying on unverified claims.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.