← Back to parser

The ESE database format that powers SRUDB.dat

The Extensible Storage Engine is Microsoft's embedded ISAM database engine — Jet Blue if you ever read internal docs. It is the storage layer for SRUM, Active Directory's NTDS.dit, Exchange mailbox stores, the old IE/Edge WebCacheV01.dat, Windows Search's Windows.edb, and DHCP. Once you can read one ESE file you can read all of them, so it is worth knowing how it ticks before you try to parse SRUDB.dat.

ESE in one paragraph

A series of fixed-size pages (4 KB or 8 KB) organised into B-trees, one per table. Writes go through a write-ahead log first, so recovery is possible after a crash. The engine is single-process — only the owning service has the file handle. Tables are described by a catalog B-tree (table id 0).

On-disk anatomy

  • Pages. 4 or 8 KB. The first page contains the database header (signature EFCDAB89, page size, log signature, state). The esentutl /mh output reads this header.
  • B-trees. One per table. Internal pages hold key ranges and child pointers; leaf pages hold rows.
  • Catalog. A special B-tree (table id 0) describing every other table: name, root page number, column definitions.
  • Long values. Variable-length data too big to fit inline lives in a separate long-value tree; the row holds a reference key.
  • Transaction logs. .log files holding committed but un-flushed writes. .chk is the checkpoint — how far the engine has flushed.

Column types you will meet in SRUDB.dat

ESE has 19 column types. The ones SRUM uses:

Type IDNameEncoding
1Bit1 byte (0/1)
4Long32-bit signed int
7IEEEDouble8-byte float (used for OLE date times)
8DateTime8-byte OLE variant date
11LongBinaryvariable bytes (often XPRESS-compressed)
12LongTextvariable UTF-16 / cp1252 text
14UnsignedLong32-bit unsigned int
15LongLong64-bit signed int (often FILETIME)
16GUID16 raw bytes (mixed-endian)

Two gotchas you will hit on SRUM:

  • The TimeStamp column on Application Resource Use is type 8 (OLE date, 8-byte float). A bucket boundary at midnight UTC is 44986.0, not a FILETIME. Tools that assume FILETIME for every timestamp column produce dates in the year 4,000,000.
  • Event-style columns like ConnectStartTime on Network Connectivity and EventTimestamp on Energy Usage are type 15 FILETIMEs. A parser must handle both.

The same divergence catches people on NTDS.dit and Exchange. Type matters.

Recovering from a dirty database

ESE marks the database "dirty shutdown" whenever the engine did not write its clean-shutdown record. Copying SRUDB.dat from a live host almost guarantees this state — DPS held the handle and was actively writing.

A read-only parser will either refuse the dirty header or quietly skip pages that need log replay. The fix is soft recovery: replay the .log files against the database with esentutl /r. The dirty-database recovery post walks the command line.

Always work on a copy. esentutl /p (hard repair) is destructive — it can discard rows. Reserve it for cases where logs are gone entirely.

XPRESS compression on variable columns

SRUM uses XPRESS compression on variable-length payloads. The SruDbIdMapTable.IdBlob column is the obvious example — the UTF-16 application paths often compress 3:1. A parser that does not decompress returns garbage strings. The compressed payload is prefixed by a magic byte (0x10 for XPRESS, 0x18 for XPRESS Huffman).

Reading ESE in 2026

Real-world choices for parsing ESE:

  • libesedb (Joachim Metz, C). The reference open-source library. Powers everything that does not write its own parser.
  • ese_parser (Stroz Friedberg, Rust). Compiles cleanly to wasm32-unknown-unknown, which is how the in-browser SRUM parser works.
  • go-ese (Velocidex, Go). Used by Velociraptor.
  • esentutl.exe. Ships with Windows. Useful for recovery, not for programmatic reads.

Further reading

Frequently asked questions

What does ESE stand for?

Extensible Storage Engine. Microsoft also calls it Jet Blue internally. It is an embedded, transactional, ISAM database with B-tree pages.

Where else is ESE used besides SRUM?

Active Directory (NTDS.dit), Microsoft Exchange (mailbox stores), the Edge / Internet Explorer cache (WebCacheV01.dat), Windows Search (Windows.edb), and DHCP.

Can I open SRUDB.dat in Microsoft Access?

No. Access uses Jet Red, a different engine. ESE/Jet Blue has its own on-disk format and requires a dedicated reader like libesedb, ese_parser, or this browser-based tool.

Is the ESE format documented?

Partially. Microsoft open-sourced the ESE engine in 2021. Joachim Metz' libyal project maintains the most complete community reverse-engineered specification.

Why are SRUM rows compressed?

ESE supports per-column XPRESS compression. SRUM uses it on its variable-length payloads (the IdBlob in SruDbIdMapTable, for example) to keep the database small.