The NTFS Update Sequence Number Journal is the artefact I reach for first on any Windows host where I need to know what touched the disk and when. It is enabled by default on every NTFS volume Windows ships with since Vista, almost nobody disables it, and almost nobody reads it before something goes wrong. That asymmetry is what makes it useful.
Every file create, delete, rename, truncate, attribute toggle and close on the volume appends a record to $UsnJrnl:$J. The records are small — a few dozen bytes each — and the file is a fixed-size ring buffer, so a busy machine retains roughly the last several million operations. On a desktop with the default 32 MB allocation that is a few days. On a file server sized to 1 GB it is weeks.
Where the journal actually lives
The journal is not a regular file. It is an alternate data stream called $J, attached to the metadata file \$Extend\$UsnJrnl at the volume root. Two consequences that bite people who have not done this before:
- A drag-and-drop in Explorer, or an
xcopy, or arobocopy, will silently copy the empty default stream and you will end up with a zero-byte file. Use a tool that understands ADS: FTK Imager, X-Ways,icatfrom The Sleuth Kit, RawCopy.exe, PowerForensics. The companion post on extracting$Jfrom a disk image walks through each. - There is a sibling stream called
$Maxon the same metadata file. It only contains size/configuration metadata. If you carve$Maxby mistake, you get nothing useful. Always pick$J.
The file itself is sparse. NTFS reserves the configured maximum size on disk but leaves the leading unused region zeroed. When you carve $J from an image, the first few hundred megabytes are often all zeroes before you reach the first real record. Every reasonable parser (usnrs, PoorBillionaire's USN-Journal-Parser, MFTECmd, the WebAssembly parser on this page) skips past the leading zeroes automatically.
Record structure (USN_RECORD_V2)
Every record is a USN_RECORD_V2 struct. Microsoft documents the layout in winioctl.h; the field-by-field summary:
| Field | Bytes | Meaning |
|---|---|---|
| RecordLength | 4 | Total record size including filename |
| Major / Minor version | 2 + 2 | 2.0 for everything you will see in practice |
| FileReferenceNumber | 8 | MFT entry + sequence of the file |
| ParentFileReferenceNumber | 8 | MFT entry + sequence of the parent directory |
| USN | 8 | Position of this record in the journal |
| Timestamp | 8 | Windows FILETIME (100-ns ticks since 1601-01-01) |
| Reason | 4 | Bitmask describing what changed |
| SourceInfo | 4 | Hints (e.g. DATA_MANAGEMENT for OS-driven changes) |
| SecurityId | 4 | Index into $Secure:$SII |
| FileAttributes | 4 | Standard NTFS attributes |
| FilenameLength / Offset | 2 + 2 | Where the UTF-16 name lives in the record |
| Filename | n | UTF-16 LE, no null terminator |
The Reason bitmask is the field that earns its keep. It is additive, not exclusive: a single record can carry FileCreate | DataExtend | Close together. A typical file lifecycle looks like FileCreate | DataExtend → DataExtend | Close → BasicInfoChange | Close → FileDelete | Close. Reconstructing that sequence after the fact is how you tell what really happened to a file. The reason code post is the field reference for every bit.
Two fields the new reader often underestimates:
FileReferenceNumberis your join key. Group records by this and you have the file's whole story across renames, attribute changes and deletion. Note the upper 16 bits are a sequence number — a file deleted and a new file allocated to the same MFT entry will share entry but differ in sequence.ParentFileReferenceNumberis the only path information in the record. The filename is just the leaf. You need a parsed$MFTto walk the parent chain to a full path. Acquire both, always.
Why it earns its keep in DFIR
Two reasons that come up on almost every engagement.
First, the journal survives deletion. Once a file is gone from the namespace and its MFT entry has been reused for something else, the record of its creation, growth, rename and deletion is still in $J until the ring buffer wraps over it. Same for files emptied from the recycle bin — the bin's $I files get cleared, but the journal remembers. On a hunt for "did this file ever exist" the journal will outlast both the MFT entry and the recycle metadata most of the time.
Second, it is cheap and self-describing. A 100 MB $J typically contains five to ten million records spanning days to weeks. Every record carries its own timestamp, reason, file reference and parent. You can ship it through a parser in seconds and pivot on any field. There is no other Windows artefact at that price.
What it will not tell you is who. There is no user, no process, no command line in any record. To attach an actor you correlate by timestamp with Security.evtx event 4663 (object access, requires SACLs you almost certainly did not configure), Sysmon event 11 (file create), or process trees from Sysmon event 1. The journal answers what and when. Other logs answer who.
Where it sits in the artefact stack
The mental model I use, ordered from "current state" to "historical history":
$MFT— the current state index. Every file and directory on the volume, including some recently deleted entries. Four timestamps per attribute, no history.$UsnJrnl:$J— per-operation history, days to weeks of it. The thing you are reading about.$LogFile— NTFS's crash-recovery transaction log. Minutes to hours of raw before/after images. The post on USN journal vs MFT vs LogFile breaks down which to reach for when.
Bring the journal alongside Prefetch, AmCache, Shimcache, LNK files and jump lists and you can usually reconstruct what ran, what was opened, and what touched disk to the minute.
What's next
If you have never opened a journal before, the fastest way to build intuition is to grab one off a test box and load it into the parser at the top of this page along with the matching $MFT. Filter for FileCreate and read the file the way Windows wrote it. The posts that follow in this series dig into the reason flags, the extraction procedure, and the patterns the journal exposes for ransomware, exfil, timestomping and deleted-file recovery.
Further reading
- Microsoft Learn — Change Journals and the USN_RECORD_V2 reference.
- Airbus CERT's usnrs — the cleanest open-source
USN_RECORD_V2parser around, also what powers the WebAssembly module on this site. - Brian Carrier, File System Forensic Analysis — the book-length treatment of NTFS internals that still hasn't been replaced.