What FSEvents records
macOS keeps a persistent log of file system changes, written by the fseventsd daemon so that Time Machine, Spotlight and sync clients can ask what changed since a given point. Each volume gets a hidden .fseventsd folder of gzip-compressed log files. Every record is a path, a 64-bit event ID and a set of flags (created, removed, renamed, modified, extended attribute changed, mount, …); newer formats add the file's node ID.
For an investigation this is a path-level history of the volume, often including files that no longer exist: an archive that briefly sat in Downloads, a LaunchAgent that was written and removed, documents staged in a hidden folder, or the contents of a USB stick.
What the parser decodes
- gzip log files, including truncated or damaged ones (everything recoverable is kept and the damage is reported), several gzip members per file, and already-decompressed pages.
- Pages in the three on-disk formats: 1SLD (path, event ID, flags), 2SLD (+ node ID, macOS 10.13 and later) and 3SLD (+ a 4-byte extra field, macOS 14 and later), several pages per file.
- Every flag bit decoded to a plain name, with the raw value and the names FSEventsParser and mac_apt use.
- fseventsd-uuid (stream identity and start of history) and no_log markers, one volume per .fseventsd folder (Data volume, volume root or external drive).
- Time windows for each log file from modification times, rename pairs by node ID, a path tree, and CSV, Timesketch and JSON exports.
What it helps answer
- Did this file or folder ever exist on the Mac, and was it created, modified, renamed or removed?
- Was a LaunchAgent or LaunchDaemon written, and when (approximately)?
- Were documents gathered in a hidden folder, copied to an external volume, then deleted?
- Was the quarantine attribute likely stripped from a download, or a privacy permission (TCC) changed?
- What was written to a USB drive, using the drive's own .fseventsd?
Limits to keep in mind
- No timestamps: records only have an event ID. Times are windows between log file modification times, and are only as good as the collection kept them.
- No user or process: FSEvents does not say who made a change. The 3SLD extra field is decoded as a user ID by FSEventsParser; its meaning is not documented by Apple.
- Coalescing: several changes to a path can be merged into one record (e.g. Created + Modified + Removed); their order inside the record is unknown.
- Retention: fseventsd purges old logs on its own schedule; weeks to months of history is typical, not guaranteed.
- Not logged: read-only volumes, network shares, and the most recent events still held in memory when the logs were copied.
Collect it in one command
- Live Mac, Terminal with Full Disk Access: sudo tar -czf ~/Desktop/fseventsd.tar.gz -C /System/Volumes/Data .fseventsd, then drop the archive here.
- UAC: the ir_triage profile (or the files/logs/macos.yaml artifact alone) collects every .fseventsd folder into a tar.gz this page reads as-is.
- Disk image: attach it read-only, then archive the Data volume's .fseventsd the same way.
FAQ
Are my files uploaded anywhere?
No. The parser is Rust compiled to WebAssembly and runs in a Web Worker in your browser. The files never leave your machine; the page works offline once loaded.
Why are there no exact timestamps?
FSEvents records do not contain one. A log file is written when fseventsd flushes it, so its modification time is an upper bound for its records and the previous log file's time a rough lower bound. The parser shows that window for every record and says how it was derived.
Which macOS versions are supported?
All three on-disk formats: 1SLD (older macOS), 2SLD (macOS 10.13 High Sierra and later, adds node IDs) and 3SLD (macOS 14 Sonoma and later, adds a 4-byte field). Mixed folders are handled.
Can it read a UAC collection directly?
Yes. Drop the UAC tar.gz: the page streams through it, keeps only the .fseventsd files and uses the modification times stored in the archive. Aftermath and Velociraptor ZIPs and plain folders work too.
What happens with a truncated or corrupt log file?
Everything that can be decompressed is parsed, complete records are kept, and the file is marked Partial with the reason (cut-short gzip, CRC mismatch, page running past the data, damaged record).
How does it compare with FSEventsParser and mac_apt?
It decodes the same on-disk structures and flag bits (names from both are shown), adds time windows, rename pairing, a path tree and findings, and needs no Python or installation. For court work, validate important records with a second tool.