eatmydata: LD_PRELOAD Your Way to 10× Faster Builds, Tests, and Throwaway Databases

2026-06-14

Every fsync() your build runs is the kernel asking the disk firmware to commit a write to physical media before returning. That's a promise the disk keeps with a real, measurable cost — single-digit milliseconds on spinning rust, hundreds of microseconds even on NVMe. SQLite calls it. Package managers call it. git calls it (a lot). Postgres' test mode calls it. Most of the time, when you're running CI or rebuilding a container, you do not care: the entire filesystem is going to evaporate in five minutes anyway.

eatmydata is a tiny LD_PRELOAD shim that turns fsync(), fdatasync(), msync(), sync_file_range(), and O_SYNC/O_DSYNC opens into no-ops. The name is the warning label. Born from OpenStack CI, packaged in Debian and Fedora, weighs about 8 KB.

$ sudo apt install eatmydata     # Debian/Ubuntu
$ sudo dnf install libeatmydata   # Fedora

Wrap any command:

$ eatmydata make install
$ eatmydata pytest -x
$ eatmydata dpkg -i ./big-package.deb

Real numbers from a Debian package install on a laptop SSD:

$ hyperfine -p 'sudo dpkg -P texlive-latex-base 2>/dev/null' \
            'sudo dpkg -i texlive-latex-base_*.deb' \
            'sudo eatmydata dpkg -i texlive-latex-base_*.deb'
  Time (mean): 14.812 s   (vanilla)
  Time (mean):  2.301 s   (eatmydata)
  Summary: eatmydata ran 6.4× faster

The mechanism is simple enough to read in one sitting — it's libeatmydata.so, exporting interposers that just return 0. Inspect with:

$ ldd $(which eatmydata) | grep eat   # actually it's a wrapper script
$ cat $(which eatmydata)
#!/bin/sh
LD_PRELOAD="libeatmydata.so${LD_PRELOAD:+:$LD_PRELOAD}" exec "$@"

That's the whole tool. The wrapper exists so the preload is inherited by every child — important because the durability calls are usually buried three forks deep inside make or cargo.

Where it shines:

Where it will eat your data: anything you intend to keep. Power loss or kernel panic during an eatmydata session leaves writes potentially uncommitted. Don't wrap your editor. Don't wrap rsync to the NAS. The package even ships a nocache companion if you want the inverse — buying back page-cache thrashing rather than durability.

The deep cut: if you don't trust LD_PRELOAD scope, you can scope it more tightly with LD_PRELOAD=libeatmydata.so command in a single child, or — for true paranoia — run inside a mount namespace where / is a tmpfs overlay, which is what some CI runners do anyway. eatmydata is the cheaper, drop-in version of that idea.

Key Takeaway: When durability is a lie you're telling the disk anyway — CI, container builds, throwaway databases — eatmydata turns every fsync() into a no-op via an 8 KB LD_PRELOAD and routinely cuts wall-clock time by 5–10×.

All newsletters