Skip to content

File accessUser activity

QuickLook Thumbnail Cache: macOS File Preview Evidence

The QuickLook thumbnail cache (index.sqlite and thumbnails.data) records files previewed in Finder, with paths, hit counts and cached images.

Location
$(getconf DARWIN_USER_CACHE_DIR)/com.apple.quicklook.ThumbnailsAgent/com.apple.QuickLook.thumbnailcache/
Proves
That a file existed at a path and was displayed as a thumbnail or preview, with a cached image that can outlive the original
Timestamps
last_hit_date in Mac absolute time; file modification time stored in the version blob
Access
Owning user or root; the cache sits under /private/var/folders, collect as root
Retention
Cache is pruned by size and age and rebuilt with qlmanage -r cache; not a long-term record
Collection
mac_apt, ditto, Disk image

What it is

QuickLook generates the thumbnails Finder shows in icon, column and gallery views, and the previews shown when a user presses Space. To avoid rendering them twice, the ThumbnailsAgent keeps a per-user cache: a SQLite index of source files and a flat data file of raw thumbnail bitmaps. It is the closest macOS relative of the Windows thumbcache_*.db files.

The value is twofold. The index identifies the source files (as full paths in the older schema, as file system IDs in the newer one), including files on removable media, and the data file keeps a small image of the content, which can survive after the original file is deleted or the volume is disconnected.

Where it lives

The cache is in the per-user Darwin cache directory under /private/var/folders/<xx>/<random>/C/, which you can resolve on a live system with getconf DARWIN_USER_CACHE_DIR.

SourcePath (relative to the C/ folder)Versions
Index + datacom.apple.QuickLook.thumbnailcache/index.sqlite, thumbnails.data10.15 Catalina and earlier
Index + datacom.apple.quicklook.ThumbnailsAgent/com.apple.QuickLook.thumbnailcache/index.sqlite, thumbnails.data11 Big Sur and later (per mac_apt)
Preview imagesthumbnails.fraghandler and other side filesPresent on some releases

On a dead-box image, map each /private/var/folders/<xx>/<random> folder to a user by its owner UID. mac_apt does this automatically.

What it proves

  • A file existed at a given path and QuickLook produced a thumbnail for it, which normally means it was shown in a Finder window, an Open/Save dialog or a preview.
  • How often the thumbnail was requested (hit_count) and when it was last used (last_hit_date).
  • The appearance of the content through the cached bitmap, for images, PDFs, office documents and video frames.
  • Paths under /Volumes/<name>/ (older schema) tie files to external drives and disk images even after they are gone.

It does not prove the user opened the file in an application, and thumbnails can be generated by browsing a folder without looking at any particular file.

Key fields

Schema varies by release; mac_apt reads the version key in the preferences table to choose a query. Common tables:

Table / columnMeaning
files.folder, files.file_name, fs_idSource path, older schema
basic_files.fileIdSource file as a file system ID (inode / CNID), newer schema; no path stored
thumbnails.file_idLinks a thumbnail to its source row
thumbnails.hit_countTimes the thumbnail was served
thumbnails.last_hit_dateLast use, Mac absolute time
thumbnails.bitmapdata_location, bitmapdata_lengthOffset and size of the bitmap in thumbnails.data
thumbnails.width, heightBitmap dimensions
version (blob)Binary plist with the source file's size and modification date

Bitmaps in thumbnails.data are raw RGBA without a header, so carving needs the width, height and offset from the index.

Timestamps

last_hit_date is Mac absolute time (seconds since 2001-01-01 UTC). The modification date inside the version plist is a snapshot of the source file when the thumbnail was built: compare it with the current file to show the content changed later. Convert in SQLite with:

SELECT datetime(last_hit_date + 978307200, 'unixepoch') AS last_hit_utc, hit_count
FROM thumbnails ORDER BY last_hit_date DESC;

Retention

  • The agent trims the cache by size and age, so expect weeks to months of history rather than years; this varies with use and release.
  • qlmanage -r cache resets it, and so does deleting the folder. An almost empty cache on a busy Mac is worth noting.
  • The files live in the per-user temporary area; some clean-up tools and OS upgrades wipe it. Older copies can remain in APFS snapshots or Time Machine if /private/var/folders was not excluded (it usually is).

Collection

C=$(sudo -u <user> getconf DARWIN_USER_CACHE_DIR)
sudo ditto "$C/com.apple.quicklook.ThumbnailsAgent" ./case/quicklook_<user>

Collect the SQLite file together with any -wal and -shm companions, and thumbnails.data at the same moment, or offsets will not match. Triage collectors differ: check that yours includes /private/var/folders, which many skip for size.

Parsing

# mac_apt: index rows plus exported PNG thumbnails
python3 mac_apt.py -o out E01 image.E01 QUICKLOOK

# Quick look at the index
sqlite3 -readonly index.sqlite '.tables'

mac_apt's QUICKLOOK plugin builds on earlier research by Mari DeGrazia and handles both schemas. For the newer one it resolves each file ID against the file system of the image to rebuild a path, which fails for deleted files and for files on volumes that are not in the image: keep the unresolved IDs and the bitmaps anyway.

Investigator tips

  • On older-schema caches, filter paths on /Volumes/ to list media browsed from USB devices and mounted disk images. On newer ones, an ID that does not resolve on the system volume may belong to an external volume: test it against images of seized media.
  • A thumbnail for a file that is no longer on disk is strong evidence it existed; pair it with Trash and FSEvents to date the deletion.
  • Images viewed through Photos use the library's own derivatives; see Photos metadata.
  • Treat content from the cache as a thumbnail, not the file: low resolution, and possibly from an earlier version of the document.

See also