What is Dolt and How Does It Work? A Deep Dive into the Git-Style SQL Database
Dolt is a Git-style version-controlled SQL database that stores tables as immutable, content-addressed objects and exposes branch, merge, and diff operations through both a command-line interface and SQL system tables.
Dolt combines the version control semantics of Git with the query capabilities of MySQL, allowing developers to branch, merge, and time-travel through relational data. According to the dolthub/dolt source code, Dolt achieves this by layering a SQL engine and Git-like CLI on top of an immutable storage engine called the Noms Block Store.
Core Architecture of Dolt
Dolt's architecture consists of four distinct layers that bridge Git-style version control with SQL query processing.
Storage Layer: Noms Block Store (NBS)
At the foundation lies the Noms Block Store (NBS), a horizontally-scalable, content-addressed storage system implemented in go/store/nbs/. Every byte sequence is stored as an immutable chunk keyed by its 20-byte SHA-1 hash. Because chunks are immutable, Dolt implements garbage collection through the gc command, which discards unreferenced chunks while preserving the Merkle-tree structure of active data.
The NBS supports two deployment modes: local disk storage via file URLs, and cloud-native storage using AWS S3 and DynamoDB, as documented in go/store/nbs/README.md.
Versioned Database Layer: DoltDB
Built atop NBS, DoltDB (defined in go/libraries/doltcore/doltdb/doltdb.go) provides the version-controlled view of the database. It wraps a Noms value store and maintains an LRU cache of materialized commits (commitCache) to accelerate repeated lookups.
Key responsibilities of DoltDB include:
- Root value management: Each commit points to a root value containing the complete schema and table data for that state.
- Branch resolution: Branches are lightweight named references pointing to commit hashes, implemented through the
GetHeadRefmethod. - Commit caching: Configurable via the
commitCacheSizeenvironment variable to optimize read performance.
SQL Interface and System Tables
Dolt exposes version control operations through a MySQL-compatible server implemented in go/cmd/dolt/commands/sqlserver/. The SQL engine registers system tables (such as dolt_log, dolt_status, and dolt_diff_<table>) and stored procedures (including dolt_add, dolt_commit, and dolt_merge) that map directly to CLI commands.
This architecture allows developers to execute version control within SQL transactions:
-- Stage changes
CALL dolt_add('users');
-- Commit with message
CALL dolt_commit('-m', 'Add initial users table');
-- View history
SELECT * FROM dolt_log;
How Dolt Implements Git-Style Version Control
Dolt adapts Git's distributed version control model to structured data through immutable data structures and Merkle-tree addressing.
Immutable Data Structures and Content Addressing
Every table, schema, and commit in Dolt is stored as an immutable object in the NBS. When you modify a row, Dolt creates new chunks for the affected table pages and propagates new hashes up the Merkle tree, resulting in a new root hash. This structure makes time-travel queries efficient: the engine simply loads the historical root hash specified in AS OF clauses.
Branching and Merging Strategies
Branches in Dolt are inexpensive references, implemented in go/libraries/doltcore/doltdb/doltdb.go through the branch ref system. When you execute dolt merge, the system performs a three-way merge on the root values of the source and target branches, resolving schema and data conflicts according to configurable rules.
Working with Dolt: CLI and SQL Examples
Initializing and Committing via CLI
The CLI entry point in go/cmd/dolt/dolt.go dispatches to command implementations in go/cmd/dolt/commands/:
# Initialize a new Dolt repository
dolt init
# Create and populate a table
dolt sql -q "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(50));"
dolt sql -q "INSERT INTO users VALUES (1,'Alice'), (2,'Bob');"
# Stage and commit changes
dolt add .
dolt commit -m "Add initial users table"
Programmatic Access with Go
You can embed Dolt directly using the doltdb package:
package main
import (
"context"
"fmt"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/store/types"
"github.com/dolthub/dolt/go/store/filesys"
)
func main() {
// Load a Dolt database from the current directory
fs := filesys.LocalFS
db, err := doltdb.LoadDoltDB(context.Background(),
types.Format_Default, doltdb.LocalDirDoltDB, fs)
if err != nil {
panic(err)
}
// Print the current branch name
headRef, err := db.GetHeadRef()
fmt.Println("HEAD is at:", headRef)
}
Summary
- Dolt combines Git-style version control with MySQL-compatible SQL, storing data as immutable, content-addressed chunks.
- The Noms Block Store (NBS) provides the foundational storage layer in
go/store/nbs/, using SHA-1 hashing and supporting both local and AWS S3 backends. - DoltDB (
go/libraries/doltcore/doltdb/doltdb.go) manages versioned database state, branch resolution, and commit caching. - Version control operations are exposed through CLI commands (
go/cmd/dolt/commands/) and SQL stored procedures (go/cmd/dolt/commands/sqlserver/). - All operations are immutable and Merkle-tree based, enabling efficient time-travel queries and branching without data duplication.
Frequently Asked Questions
What is Dolt and how does it work?
Dolt is a version-controlled SQL database that works like Git for data. It stores every table, schema, and commit as immutable objects in a content-addressed storage layer called the Noms Block Store, allowing you to branch, merge, diff, and time-travel through your database history using either Git-style CLI commands or standard SQL queries.
How does Dolt store data differently from traditional SQL databases?
Unlike traditional databases that mutate rows in-place, Dolt uses immutable, content-addressed storage where every change creates new chunks. When you modify data, Dolt writes new table chunks with new SHA-1 hashes and updates the Merkle tree root, preserving the entire history. This design enables features like SELECT * FROM table AS OF 'commit_hash' without performance penalties or separate audit tables.
Can I use Dolt with existing MySQL tools and applications?
Yes, Dolt is MySQL-compatible and implements the same wire protocol. You can connect standard MySQL clients, ORMs like SQLAlchemy or GORM, and business intelligence tools directly to dolt sql-server. Additionally, Dolt exposes version control operations through SQL stored procedures like CALL dolt_commit('-m', 'message') and system tables like dolt_log, allowing you to version data without leaving your SQL workflow.
What are the performance implications of Dolt's immutable storage?
Dolt's immutable storage trades some write amplification for read performance and versioning capabilities. Writes create new chunks rather than updating in-place, which requires more storage I/O than traditional B-tree updates. However, reads benefit from aggressive caching in the DoltDB layer (commitCache in go/libraries/doltcore/doltdb/doltdb.go) and structural sharing between versions. For analytical workloads and moderate transactional loads, the performance is comparable to MySQL, though high-throughput OLTP scenarios may require careful tuning of the NBS garbage collection and chunking parameters.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →