Skip to content
Nuvyntra Labs

Documentation

File format

Format v2 layout: superblock, pages, BSON documents, index keys, and WAL.

Overview

A .nvx file is one portable embedded database. Creates and writes always use format 2. Format 1 is deprecated: the engine still reads it (and leftover n: index keys / WAL v1 headers). Do not write format 1. Language bindings must not reimplement this format. They call the Native AOT C ABI, which uses the same managed engine as Nuventra.NuvexaDB.

Layout

ItemValue
Magic (bytes 0–3)NVX1
Format version2 on every create / write; 1 deprecated, accepted on open (uint16 LE at offset 4)
Physical page size8192 bytes
Logical payload (after AES-GCM overhead)8164 bytes (8192 - 12 nonce - 16 tag)
Page header40 bytes
Slot directory entry4 bytes (offset + length, uint16 LE each)
Catalog page id1
First allocatable page id2
Companion WAL<path>.nvx-wal (magic NVXW)
Exclusive lockFileShare.None — one process, one open path

Page 0 is the superblock. It is never AES-GCM page-encrypted. Encrypted files HMAC-SHA256 the first 400 bytes of page 0 with the DEK (32-byte MAC at offset 400). Superblock CRC32 covers those 400 bytes (CRC stored at offset 198; the CRC field is zeroed while computing).

Superblock (page 0, little-endian)

OffsetSizeField
04Magic NVX1
42Version
62Flags (Encrypted = 1, CompactNeeded = 2, IntegrityProtected = 4)
84Page size (must be 8192)
128Page count
2016File id (AAD / wrap nonce context)
368Catalog page id
448Next page id
528Committed LSN
684Argon2id memory KiB
724Argon2id iterations
762Argon2id parallelism
7816KDF salt
9412Verifier nonce
10616Verifier tag
12216Verifier ciphertext (NVEXA-OK-VERIFY!)
13812DEK wrap nonce
15016DEK wrap tag
16632Wrapped DEK (AES-256-GCM)
1984CRC32 of bytes 0–399 (field zeroed during compute)
40032HMAC-SHA256(DEK, bytes 0–399); all-zero means legacy, still accepted

See encryption.md for KDF and page cipher.

Pages

Each allocated page (except the superblock) is a slotted logical buffer of 8164 bytes:

OffsetSizeField
01Page type
22Item count
44CRC32 of the logical page (checksum field zeroed during compute)
88Page id
168LSN
248Next page id (overflow / chain)
328Right sibling (B+tree)

Types: Free=0, Super=1, Catalog=2, Data=3, IndexLeaf=4, IndexInternal=5, SecondaryIndexCatalog=6.

Slots grow from the header; the slot directory grows backward from the end of the logical page. Documents larger than a page are chained (MaxDocumentBytes = 16 MiB). Collection names are at most 120 bytes.

Documents

New data-page payloads are BSON. Public APIs stay JSON (NuvexaDocument.Parse / ToJson, NQL, Explorer, C ABI). A payload that looks like {…} is treated as legacy UTF-8 JSON. Mixed BSON/JSON files are valid.

Index keys

Keys are type prefix plus NUL plus document id:

PrefixMeaning
s:string
n:v1 number (G17 invariant culture; not numeric-order-preserving)
d:v2 number (8 IEEE754 sortable bytes; lex order = numeric order)
b:0 / b:1boolean
z:null
j:other JSON

Compound indexes join field paths and value prefixes with U+001F. Equality, string ranges, and format-2 numeric ranges can IXSCAN with lo/hi bounds. Deprecated format-1 n: keys are still read (walk that prefix and apply the real compare). New numeric index entries are always d:.

WAL (`*.nvx-wal`)

v1 header (22 bytes): NVXW + uint16 version + 16 reserved bytes. v2 header (32 bytes): NVXW + uint16 version + int32 page size + 22 reserved bytes. Records:

  • Page: type 1, page id, LSN, length (8192), physical page, CRC32 of the page
  • Commit: type 2, LSN, CRC32 of type+LSN

Replay applies page records up to the last valid commit. Encrypted checkpoints write the same DEK HMAC on WAL copies of page 0. Legacy all-zero MAC records still replay. Truncate after a successful checkpoint.

Integrity

Open checks superblock CRC (and HMAC when encrypted and non-zero). NuvexaOpenOptions.VerifyIntegrity (default true) scans allocated pages when the file is ≤ IntegrityScanMaxBytes (default 64 MiB). A mismatch throws NuvexaIntegrityException. The engine does not repair a failed file.

Bindings

Language SDKs (Java, Kotlin, Swift, Flutter, React Native, Python, Node, Go, C++) must treat .nvx as an opaque file and call bindings. Do not parse pages from those SDKs. Sharing model: architecture.md.

Discussion

Comment on NuvexaDB. The thread lives on this component's GitHub repository (nuvyntralabs/NuvexaDB). Sign in with GitHub — Giscus uses Discussions, Utterances uses Issues.