Skip to content

FSEvents File Format: 1SLD, 2SLD and 3SLD Pages

The on-disk layout of macOS .fseventsd logs: gzip files, DLS page headers, record fields per version, and how to handle truncated or corrupt data.

Published on 4 min read

TL;DR. Each .fseventsd log is a gzip file. Decompressed, it is a sequence of pages; each page starts with a 12-byte header (1SLD, 2SLD or 3SLD, four unknown bytes, a little-endian page size) followed by records: a NUL-terminated path and 12, 20 or 24 bytes of fixed fields. This layout matches what FSEventsParser (Nicole Ibrahim, Apache-2.0) and mac_apt (ydkhatri, MIT) implement; Apple does not document it.

The folder

.fseventsd/
  0000000012a44181      gzip log file; name = an event ID in hex
  0000000012a4439d
  fseventsd-uuid        text: the stream UUID
  no_log                optional, empty: logging disabled

Log names are 16 hexadecimal digits. FSEventsParser treats a name as the file's last event ID; the FSEvents Parser on this site checks the name against the IDs inside and flags files whose name falls outside their own range (renamed or misplaced files).

gzip layer

Each log is an ordinary gzip stream (RFC 1952). Some files hold more than one gzip member, and copies of a log that was still being written end early. A robust reader:

  • inflates member after member;
  • keeps every byte it could inflate when the stream is cut short or damaged, instead of rejecting the file;
  • checks the CRC-32 and size trailer, and reports a mismatch without discarding data;
  • accepts data that was already decompressed by another tool (it starts directly with a page magic).
OffsetSizeField
04Magic, stored as the ASCII bytes 1SLD, 2SLD or 3SLD
44Unknown
84Page size, u32 little-endian, counted from the start of the header

Pages follow each other until the end of the decompressed data. Some write-ups call them "DLS1/DLS2" because the magic read as a little-endian integer spells that; the bytes on disk are 1SLD. See DLS page.

Records

After the header, records are packed back to back until the page size:

Field1SLD2SLD3SLD
Path, UTF-8, NUL-terminatedyesyesyes
Event ID, u64 LE+0+0+0
Flags, u32 LE+8+8+8
Node ID, u64 LE+12+12
Extra, 4 bytes+20
Fixed part after the path12 bytes20 bytes24 bytes
  • 2SLD appeared with macOS 10.13 High Sierra, 3SLD with macOS 14 Sonoma (per FSEventsParser's implementation notes). A volume used across upgrades can hold several versions.
  • The path is relative to the volume root, as it was when logged: Users/dana/Library/LaunchAgents/com.example.updater.plist, not /System/Volumes/Data/Users/…. Empty paths occur.
  • The 3SLD extra field is decoded by FSEventsParser as a signed 32-bit user ID (fs_uid) and left unnamed by mac_apt. Apple has not documented it; treat any interpretation as a hypothesis and test it on known data.
  • The flags are covered in the flags reference.

Parsing defensively

Real collections contain truncated, carved and damaged logs. Rules the parser on this site follows:

  1. A page whose declared size runs past the data is parsed up to the end of the data, and reported.
  2. A record whose path has no NUL, or whose fixed fields do not fit, is dropped and reported; the records before it are kept.
  3. Zero bytes after the last record or page are slack, not an error.
  4. Bytes that are not a page magic are skipped up to the next 1SLD/2SLD/3SLD and the number of skipped bytes is reported.
  5. Records with impossible flag combinations (both File and Folder, both Symlink and Hard link) are counted as a sign of damage, as FSEventsParser does for carved data.
  6. Paths that are not valid UTF-8 are shown with replacement characters and counted.

Timestamps

There are none in the format. How to date records from the log files' modification times is covered in dating FSEvents records.

FAQ

What is the difference between 1SLD, 2SLD and 3SLD?

The record size. 1SLD records hold a path, an 8-byte event ID and 4-byte flags; 2SLD adds an 8-byte node ID (macOS 10.13 and later); 3SLD adds 4 more bytes (macOS 14 and later).

Are FSEvents logs little-endian?

Yes. The page size, event ID, flags, node ID and extra field are all stored little-endian. Some tools read the flags big-endian and use byte-swapped constants, which gives the same names.

Related articles