etcd-io/bbolt
An embedded key/value database for Go.
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2w ago
- ✓18 active contributors
- ✓Distributed ownership (top contributor 48% of recent commits)
Show all 6 evidence items →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/etcd-io/bbolt)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/etcd-io/bbolt on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: etcd-io/bbolt
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/etcd-io/bbolt shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 2w ago
- 18 active contributors
- Distributed ownership (top contributor 48% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live etcd-io/bbolt
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/etcd-io/bbolt.
What it runs against: a local clone of etcd-io/bbolt — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in etcd-io/bbolt | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 45 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of etcd-io/bbolt. If you don't
# have one yet, run these first:
#
# git clone https://github.com/etcd-io/bbolt.git
# cd bbolt
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of etcd-io/bbolt and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "etcd-io/bbolt(\\.git)?\\b" \\
&& ok "origin remote is etcd-io/bbolt" \\
|| miss "origin remote is not etcd-io/bbolt (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "db.go" \\
&& ok "db.go" \\
|| miss "missing critical file: db.go"
test -f "bucket.go" \\
&& ok "bucket.go" \\
|| miss "missing critical file: bucket.go"
test -f "cursor.go" \\
&& ok "cursor.go" \\
|| miss "missing critical file: cursor.go"
test -f "internal/common/inode.go" \\
&& ok "internal/common/inode.go" \\
|| miss "missing critical file: internal/common/inode.go"
test -f "bolt_unix.go" \\
&& ok "bolt_unix.go" \\
|| miss "missing critical file: bolt_unix.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 45 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~15d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/etcd-io/bbolt"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
bbolt is a production-grade embedded key-value database written in pure Go, forked from Ben Johnson's original Bolt to provide active maintenance. It uses memory-mapped file I/O and B+ tree indexing (inspired by LMDB) to deliver fast, reliable persistence without requiring a separate database server, suitable for applications that need transactional KV storage embedded directly in their binary. Core single-package design: bucket.go and related files implement B+ tree bucket operations; platform-specific memory-mapping in bolt_*.go (Unix, Windows, AIX variants); cmd/bbolt/ provides a CLI tool with subcommands (bench, buckets, check, compact, dump, get) under cmd/bbolt/command/. All tests are colocated with source (*_test.go files). The database opens as a single file and manages transactions internally without external coordination.
👥Who it's for
Go developers building systems that need persistent embedded storage—including etcd itself, which relies on bbolt for backing store. DevOps tools, CLI applications, and any service needing reliable single-machine KV durability without operational overhead of managing a separate database.
🌱Maturity & risk
Highly mature and production-ready. Used in high-load production at Shopify and Heroku serving databases up to 1TB. The codebase uses semantic versioning with stable API and file format guarantees; test coverage includes full unit tests plus randomized black-box testing (see .github/workflows). Active maintenance evident from multiple CI pipelines (cross-arch tests, benchmark tracking, robustness tests) and recent Go 1.25.9 toolchain support.
Standard open source risks apply.
Active areas of work
Active maintenance with comprehensive CI/CD setup. Recent work includes benchmark tracking (benchmark-pr.yaml, benchmark-releases.yaml), robustness testing (robustness_nightly.yaml, robustness_test.yaml), cross-architecture validation (cross-arch-test.yaml for amd64 and arm64), failpoint injection testing, and lint enforcement (lint.yaml). The repo recently updated to Go 1.25.9 and uses gofail for fault injection testing in production scenarios.
🚀Get running
git clone https://github.com/etcd-io/bbolt.git
cd bbolt
go mod download
go test ./...
make test # uses Makefile targets
Daily commands:
Development: make test runs unit tests. make bench for benchmarks (uses golang.org/x/perf/cmd/benchstat). CLI tool: go build ./cmd/bbolt produces the bbolt binary; subcommands like bbolt check <db-file>, bbolt bench <db-file> are available. Library: Import go.etcd.io/bbolt in your Go code; see README for transaction and bucket examples.
🗺️Map of the codebase
db.go— Core database struct and lifecycle (Open, Close, Batch, View, Update) — entry point for all operationsbucket.go— Bucket abstraction for key-value operations (Get, Put, Delete, Cursor) — fundamental data structurecursor.go— Cursor iteration logic for range queries and key enumeration — critical for sequential access patternsinternal/common/inode.go— Page node structure and B+ tree manipulation — core to btree balancing and page managementbolt_unix.go— Unix-specific memory mapping and file locking — platform abstraction layer for data persistencecompact.go— Database compaction logic for reclaiming fragmented space — essential for production maintenancecmd/bbolt/main.go— CLI tool entry point demonstrating all major DB operations and diagnostic capabilities
🧩Components & responsibilities
- Database (db.go) (RWMutex, mmap, file handle, freelist) — Connection lifecycle, transaction initiation, global coordination
- Failure mode: Corruption if multiple processes open same file; panic if mmap fails; deadlock if transaction misused
- Transaction (implicit in db.go) (MVCC via freelist, copy-on-write) — Snapshot isolation, read/write phase coordination, rollback on error
- Failure mode: Dirty read if freelist corrupted; write conflict if two writers race; phantom reads possible across tx boundaries
- undefined — undefined
🛠️How to make changes
Add a new database operation (e.g., atomic update with rollback)
- Define new public method on Tx type in db.go that wraps transaction logic (
db.go) - Implement the operation using cursor.go to navigate existing data and bucket.go to modify it (
cursor.go) - Add unit tests using internal/btesting helpers to create test DBs (
internal/btesting/btesting.go)
Add a new CLI diagnostic command
- Create new command file following pattern: cmd/bbolt/command/command_*.go (
cmd/bbolt/command/command_root.go) - Implement Execute() method that uses public DB API to inspect state (
db.go) - Register command in root command handler and add corresponding test file (
cmd/bbolt/command/command_root.go)
Optimize page allocation for a new workload
- Review freelist allocation strategy and page reuse in internal/common/inode.go (
internal/common/inode.go) - If fragmentation is issue, call Compact() from db.go or enhance compact.go logic (
compact.go) - Benchmark with internal/common/bench_test.go to measure page efficiency gains (
internal/common/bench_test.go)
Port bbolt to a new OS or architecture
- Add new file bolt_<os>.go following patterns in bolt_unix.go and bolt_windows.go (
bolt_unix.go) - Implement Mmap, Munmap, Lock, Unlock, Sync using OS-native APIs (
bolt_windows.go) - Add architecture constants file internal/common/bolt_<arch>.go if page size differs (
internal/common/bolt_amd64.go)
🔧Why these technologies
- Memory-mapped I/O (mmap) — Allows OS to manage paging and cache transparently; enables zero-copy reads of large datasets without explicit syscalls
- B+ tree with pages — Minimizes disk I/O by batching operations in page-sized units (typically 4KB); sorted structure supports efficient range queries
- MVCC-lite (read during write via copy-on-write) — Readers access snapshot via freelist; writers allocate new pages; avoids write-lock blocking concurrent reads
- Go's context-based transactions — View/Update/Batch use goroutine-local transaction state; enables composable, nested, and cancellable operations
- Cobra CLI framework — Provides standardized command routing, help text, and flag parsing for multi-command bbolt diagnostic tool
⚖️Trade-offs already made
-
Single file-based database (no sharding/distribution)
- Why: Simplicity and ACID guarantees within one process
- Consequence: Cannot scale to multiple machines; limited by single machine I/O and memory
-
mmap-based design requires OS page fault handling
- Why: Reduces explicit read syscalls and leverages OS caching
- Consequence: Less predictable latency on systems with memory pressure; platform-dependent performance
-
Bucket-level isolation, no row-level locking
- Why: Simpler implementation and lower coordination overhead
- Consequence: Write throughput limited to one writer per bucket at a time; reads and writes on same bucket serialize
-
Freelist stored in-database (not external)
- Why: Keeps metadata self-contained and consistent
- Consequence: Fragmentation can slow lookups; requires periodic Compact()
-
No query language or indexes (key-value only)
- Why: Minimal feature set, fast, predictable behavior
- Consequence: Applications must implement range queries and secondary indexes manually
🚫Non-goals (don't propose these)
- Distributed/networked replication — single-process embedded database only
- Query language or SQL support — raw key-value API
- Row-level or fine-grained locking — bucket-level isolation
- Real-time change notifications or pub/sub — no observable event streams
- Automatic schema migration or versioning — application responsibility
- Full-text search or complex indexing — user must build secondary indexes via buckets
🪤Traps & gotchas
Platform-specific behavior: bolt_*.go files have different sync/mmap implementations; tests on one platform may not catch bugs on others (see cross-arch-test.yaml). File locking: On Windows, the database file cannot be moved while open (different semantics than Unix). MaxBucketDepth: Nested buckets have depth limits; deeply nested bucket hierarchies will fail. Transaction size: Large read-only transactions hold page snapshots in memory indefinitely until rolled back. No built-in clustering: Single-file, single-process-at-a-time design; network replication is external responsibility (etcd builds this). Go version requirement: go.mod specifies Go 1.25.0 minimum; older toolchains will fail.
🏗️Architecture
💡Concepts to learn
- B+ tree (B-plus tree) — bbolt's core index structure for ordered key-value storage; understanding page splits, fills, and traversal is essential to tuning performance and diagnosing corruption
- Memory-mapped I/O (mmap) — bbolt leverages mmap via platform-specific code (bolt_unix.go, bolt_windows.go) to map the entire database file into process address space—critical to understanding performance characteristics and page fault behavior
- Copy-on-write (CoW) — bbolt uses CoW semantics in write transactions to implement MVCC-style isolation without locks, allowing concurrent read-only transactions; understanding CoW is key to grasping transaction isolation levels
- MVCC (Multi-Version Concurrency Control) — bbolt maintains multiple versions of pages to allow read-only transactions to see consistent snapshots while writes are in flight; essential for understanding how transactions remain isolated
- Free list page recycling — bbolt tracks deleted pages in a free list and reuses them for future writes; understanding free list chaining and batch allocation improves write performance tuning
- Transaction batching (Batch API) — bbolt's Batch() method coalesces multiple transaction requests to amortize lock overhead; understanding when to use Batch vs. Update vs. View is critical for throughput optimization
- Database compaction and defragmentation — bbolt's cmd/bbolt/command/command_compact.go rewrites the database to reclaim fragmented free space; understanding when compaction is needed prevents runaway file size in long-running deployments
🔗Related repos
etcd-io/etcd— Primary consumer of bbolt—uses it as the embedded KV backend for all etcd state management and metadata storageboltdb/bolt— Original Bolt repository that bbolt forked from; represents the upstream design inspiration and reference for API stabilitycockroachdb/pebble— Modern alternative KV storage engine written in Go; uses RocksDB-style LSM tree rather than B+ tree, suited for higher write throughputdgraph-io/badger— Another pure-Go embedded KV database; uses LSM tree and MVCC, designed for higher concurrency than bbolt's single-writer modeletcd-io/gofail— Fault injection framework used in bbolt's robustness testing pipelines to validate behavior under I/O errors and failures
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive integration tests for bbolt CLI commands
The cmd/bbolt directory contains many command implementations (bench, buckets, check, compact, dump, get, info, inspect, keys, page, stats, surgery) but there are no cross-command integration tests. The existing *_test.go files test individual commands in isolation. A new integration test suite would verify command interactions, error handling across different database states, and real-world workflows. This is critical for a CLI tool where users rely on command reliability.
- [ ] Create cmd/bbolt/integration_test.go with test helpers for setting up test databases
- [ ] Add integration tests that sequence multiple commands (e.g., create bucket → insert data → compact → verify with inspect)
- [ ] Test edge cases like corrupted databases with surgery commands followed by check command
- [ ] Add tests for command flag combinations and validation across the command package
Add platform-specific robustness tests for memory-mapped file handling
The codebase has platform-specific implementations (bolt_linux.go, bolt_windows.go, bolt_unix.go, etc.) and a robustness_test.yaml workflow, but the robustness tests likely don't cover platform-specific mmap failures. Add targeted tests for memory-mapped file edge cases per platform: mmap failures, page faults, file locking issues on Windows, fsync failures on Unix. This directly improves reliability across the platforms bbolt supports.
- [ ] Review existing robustness_test.yaml and robustness_template.yaml to understand test structure
- [ ] Create allocate_platform_test.go or extend allocate_test.go with platform-specific mmap failure scenarios
- [ ] Add tests simulating mmap expansion failures, permission errors, and resource exhaustion per platform (referencing bolt_windows.go, bolt_unix.go implementations)
- [ ] Add a new GitHub Actions workflow robustness_mmap.yaml that runs these tests across all supported platforms
Add missing test coverage for bucket and transaction concurrent access patterns
bucket.go and the transaction handling are critical paths, but bucket_test.go has limited concurrency tests. Given bbolt's use in etcd and the golang.org/x/sync dependency, add comprehensive tests for: concurrent readers during writer transactions, bucket ForEach during concurrent deletes, nested bucket access across goroutines, and transaction isolation violations. This ensures the concurrency model is robust under realistic load.
- [ ] Extend bucket_test.go with TestBucketConcurrentReads_DuringWrite testing N readers while a writer is active
- [ ] Add TestBucketForEachDuringConcurrentDeletes verifying iterator safety
- [ ] Add TestNestedBucketConcurrentAccess testing cross-bucket goroutine safety
- [ ] Add TestTransactionIsolationWithConcurrentWriters ensuring proper ACID guarantees
- [ ] Run new tests under -race flag in tests-template.yml workflow to catch data races
🌿Good first issues
- Add missing cross-platform test coverage for
bolt_android.goandbolt_solaris.go—these platform variants exist but likely lack dedicated test jobs (unlike amd64/arm64 in tests_amd64.yaml and tests_arm64.yaml); create corresponding workflow files and test matrix entries - Expand CLI subcommand test coverage in
cmd/bbolt/command/—many command_.go files have corresponding test.go but likely have gaps; review command.go for error paths and add tests for edge cases (missing files, corrupted databases, empty buckets) - Document performance tuning knobs—bucket.go and memory-mapped I/O have implicit configuration (page size, free list recycling) not exposed in README; add a performance tuning guide with concrete examples of MaxFillPercent and how it affects write amplification
⭐Top contributors
Click to expand
Top contributors
- @ahrtr — 48 commits
- @dependabot[bot] — 22 commits
- @fuweid — 5 commits
- @ivanvc — 4 commits
- @hwdef — 3 commits
📝Recent commits
Click to expand
Recent commits
cd4bafc— Merge pull request #1193 from ivangsm/surgeon/xray-detect-cycles (ahrtr)29cb88e— surgeon: test FindPathsToKey returns one stack per bucket (ivangsm)b06ba6a— surgeon: detect cycles in XRay.traverse (ivangsm)222f7e7— Merge pull request #1191 from etcd-io/dependabot/github_actions/actions/github-script-9.0.0 (ahrtr)37646bf— Merge pull request #1192 from etcd-io/dependabot/go_modules/golang.org/x/sys-0.43.0 (ahrtr)6a643c0— build(deps): Bump golang.org/x/sys from 0.42.0 to 0.43.0 (dependabot[bot])993951d— build(deps): Bump actions/github-script from 8.0.0 to 9.0.0 (dependabot[bot])489d2cb— Merge pull request #1188 from fuweid/bump-go-to-1.25.9 (ahrtr)c62ef5d— *: bump go to 1.25.9 (fuweid)1eefd6e— Merge pull request #1186 from fuweid/update-changelog (ahrtr)
🔒Security observations
The bbolt repository demonstrates generally solid security practices as an established embedded database project. Dependencies are well-maintained and minimal. However, there are concerns regarding the Go toolchain version specification (1.25.0 appears to be a future/unreleased version), which should be corrected. The project lacks visible security documentation (SECURITY.md) and code signing practices that would strengthen supply chain security. No obvious injection vulnerabilities, hardcoded secrets, or critical misconfigurations were detected in the visible structure. Recommended improvements include clarifying the Go version requirement, adding security documentation, and implementing release signing.
- Medium · Outdated Go Toolchain Version —
go.mod. The project specifies Go 1.25.0 with toolchain go1.25.9. Go 1.25.x is a future/unreleased version. This may indicate a configuration error or use of pre-release tooling, which could introduce instability and security issues. Current stable versions should be used for production systems. Fix: Update to a stable, current Go version (e.g., 1.23.x or the latest stable release). Verify the Go version requirement is intentional and well-tested. - Low · Indirect Dependency on golang.org/x/perf —
go.mod (indirect dependency: golang.org/x/perf). The project includes golang.org/x/perf as an indirect dependency (via tools). While performance analysis tools are useful, experimental/x packages should be reviewed carefully for production use. This package is not officially stable. Fix: Verify that golang.org/x/perf is only used in development/testing contexts and not in production code. Consider isolating tool dependencies using build tags or separate go.mod files. - Low · Missing SECURITY.md File —
Repository root. The repository does not appear to have a SECURITY.md file based on the provided file structure. This file is important for documenting security policies, vulnerability reporting procedures, and supported versions. Fix: Create a SECURITY.md file that includes: vulnerability reporting guidelines, security support timeline, and contact information for reporting security issues. - Low · No Visible Code Signing Configuration —
.github/workflows/. There is no visible configuration for signed commits or releases (e.g., GPG signing, cosign configuration) in the provided file structure. Fix: Implement cryptographic signing for releases and commits. Consider using GitHub's native signing features or tools like cosign for supply chain security.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.