ZeeDB and ZeeDB Studio: Storage Guarantees Meet a Native Workspace
By Raymund Zyron Abella /
Explore framed WAL commits, checkpoint ordering, recovery contracts, and the native Windows client that turns byte records into an inspectable workspace.
In this article
A database needs a precise answer to a deceptively simple question: what does a successful write mean? A desktop client needs a different answer: how can a person inspect and change that data without misunderstanding it?
ZeeDB and ZeeDB Studio approach those problems as separate projects. ZeeDB is an experimental persistent key-value engine written in Go, available through an embedded API, CLI, and authenticated HTTP server. Studio is a native C#/.NET WPF client for that server.
The engine page and Studio page include their Windows downloads, screenshots, and implementation excerpts. Studio's portfolio capture shows the real app disconnected from any database; its record counts are not invented demonstration measurements.
Collections and Bytes Before Tables
The engine stores opaque byte values under collection-scoped byte keys. A collection groups keys into a namespace. It does not automatically create a SQL table, enforce a JSON schema, or establish an access-control boundary.
Applications can therefore store JSON, text, or binary values, but they own the interpretation of those bytes. Studio builds a convenient table view for JSON objects while retaining a raw inspector for other values.
This separation prevents the UI from quietly redefining the database. A column displayed in Studio is a way to inspect a value; it is not proof that the engine has a corresponding typed column or secondary index.
The Write-Ahead Log Defines the Commit Path
ZeeDB validates and copies a complete batch before writing it. The engine then appends a framed batch to the write-ahead log. In durable mode, it syncs that log before making the committed records visible under the database lock and acknowledging the operation.
The batch is the recovery unit. It includes a sequence number and operations, with length framing and CRC32 checks. Concurrent readers cannot observe only half of an applied batch because the commit holds an exclusive lock while changing state.
CRC32 serves a specific purpose: detecting accidental corruption. It does not authenticate data or provide encryption. The current format stores unencrypted keys and values, so those storage properties should not be confused with the HTTP token controlling server access.
There is another subtle contract. A complete frame from an operation whose acknowledgement was lost can still recover after a restart. An application must allow for a write having happened even when the caller did not receive success. This is why Fieldwork uses stable mutation identities and saved receipts above the engine.
Checkpoints Have an Order Too
The current single-shard implementation uses a bounded memtable and one fully compacted SSTable in a flat directory. It does not implement the proposed long-term multi-level storage layout merely because the project has a broader blueprint.
Checkpointing merges live state into a temporary sorted table, syncs and publishes it, verifies the new table, and publishes a checksummed manifest and CURRENT pointer. The old table and covered WAL data are reclaimed only after the new checkpoint is published.
That ordering matters during interruption. A system that removes the old data before publishing its replacement can turn a housekeeping operation into data loss. In this format, manifests and sequence bounds help distinguish the current checkpoint from incomplete or obsolete files.
The table index and Bloom filter are rebuilt from verified blocks on open. The index contains per-record keys and locations; this version does not claim a persisted sparse index or a general block cache. Those choices put clear limits around the current implementation.
Recovery Does Not Mean Guessing Through Corruption
On open, the engine acquires the database lock, verifies its published checkpoint, and replays complete valid WAL frames newer than that checkpoint. A final incomplete frame can be truncated to the last complete boundary.
A complete frame with a bad checksum, malformed records, or sequence gaps is treated differently. The engine reports an error rather than trying to invent a middle-of-file repair. A missing CURRENT alongside existing storage is also not permission to silently create a new empty database.
The repository records deterministic and process-kill tests for supported recovery cases. Those tests are useful evidence for that contract, but they do not establish arbitrary-media repair or the performance targets in the original blueprint. The engine and file format remain experimental.
Studio Projects JSON Without Changing It
Studio uses WPF and .NET to provide a native Windows workspace. Microsoft's WPF overview explains the UI framework; this project adds an authenticated ZeeDB client, saved profiles, forms, and record inspection on top.
The default table view projects JSON fields into columns, including nested paths. Missing fields and explicit JSON null have different displays. Literal dots and backslashes in property names are escaped so a path does not become ambiguous.
The raw record is unchanged by viewing it. Local table definitions guide row-entry forms, but they are not hidden schema records written into the database. An empty table definition remains a local Studio preference until an actual row is saved.
The storage version column is also separate from a JSON property named version. One describes engine metadata; the other is ordinary application content. Keeping those meanings visible avoids a small UI shortcut becoming an incorrect mental model.
Connections and Writes Are Deliberate
A connection profile supplies a server origin and bearer token. The client rejects origins with embedded URL credentials, unexpected paths, queries, or fragments. Remote and production connections require HTTPS, and database tokens are not forwarded across redirects.
Local loopback development profiles can open with writes enabled. Remote profiles begin read-only. Enabling writes requires typing the connection name, and destructive operations have their own confirmation wording. Saved tokens, when requested, use Windows-encrypted profile storage.
These choices help distinguish looking at data from changing it. The application should make the active profile and environment understandable before a row edit becomes an HTTP request.
A Small End-to-End Exercise
With an owned development database, create a temporary collection containing a nested JSON object. Open it in Studio, compare the table columns with the raw inspector, and inspect the difference between a missing field and an explicit null. Modify one value, reconnect, and verify that the stored representation matches your intent.
For evaluation, I would focus on incorrect edits, profile confusion, interpretation of null/missing fields, and whether a user understands which settings are only local. No throughput, security-certification, or user-efficiency result is claimed by this article.
The ZeeDB guide and executable cover the engine. The Studio download and requirements cover the native client. Together, they make a useful distinction concrete: storage guarantees belong to the engine, while the workspace must communicate those guarantees without adding imaginary ones.