Library / SDK
hashicorp/raft-boltdb avatar
hashicorp/raft-boltdb

raft-boltdb: a single file Raft log and stable store

Raft backend implementation using BoltDB

706 stars114 forksGoMPL-2.0

At a glance

What is it?
hashicorp/raft-boltdb is a Go package that provides the BoltStore, an implementation of both the LogStore and StableStore interfaces that hashicorp/raft expects. It keeps a Raft cluster's log, its current term and its vote in one BoltDB file, and it emits a detailed set of metrics about writes, batches and page allocation.
Who is it for?
Adopt raft-boltdb when you are running hashicorp/raft and want the log, the current term and the vote in one embedded file rather than in an external database, and when a single process on a local disk is an acceptable availability model. Do not adopt it if you need replication of the log store itself, since the file lives with the node and this package does not address storage durability beyond what BoltDB provides.
Can I use it commercially?
Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 37 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One file holding everything a Raft node must remember

The package description is a single line, a Raft backend implementation using BoltDB, and the README expands it just enough to be useful. This repository provides the raftboltdb package, and the package exports the BoltStore, which is an implementation of both a LogStore and a StableStore. It is meant to be used as a backend for the raft package. The two interfaces are the whole point of the design. A Raft node has to keep two different kinds of state: the replicated log of commands, which grows, and the small amount of durable state that the consensus algorithm needs, namely the current term and the vote. A single store that satisfies both means one file to back up, one file to reason about, and no second system to keep consistent. The underlying engine is BoltDB, described in the README as a simple key/value store implemented in pure Go and inspired by LMDB, which is the design that gives BoltDB its single file, page based, memory mapped behaviour.

The metrics are the interesting part of the README

Most of the README is a metrics table, and that is a statement about what this library is for. It is the storage layer of a consensus system, so the questions an operator asks are about the behaviour of the file rather than the behaviour of the API. The table lists gauges for freelistBytes, which is the number of bytes needed to encode the freelist metadata, freePageBytes for free space in the raft.db file, numFreePages and numPendingPages for page counts, openReadTxn and totalReadTxn for read transaction counters, and a writeCapacity sample, which is the theoretical write capacity in logs per second, with each sample projecting forward from a batch's size, byte size, disk performance and boltdb performance. There are timers for getLog, storeLogs and writeTime, and samples for logBatchSize, logsPerBatch and logSize. The txstats group tracks the B+tree mechanics: pageCount, pageAlloc, cursorCount, nodeCount, nodeDeref, rebalance, rebalanceTime, spill, spillTime, split, write and writeTime, and the README is careful to say the allocation gauges do not account for space freed and reused, so the value keeps rising.

Two metrics backends, selected by build tag

The library can emit metrics through either github.com/armon/go-metrics or github.com/hashicorp/go-metrics, and the choice is made at build time rather than at runtime. Two build tags control it: armonmetrics routes metrics to armon/go-metrics, and hashicorpmetrics routes all metrics to hashicorp/go-metrics. If you specify neither, the default behaviour is armon/go-metrics. That default is on its way out. The README states that emitting metrics to armon/go-metrics is officially deprecated, and that usage of armon/go-metrics will remain the default until mid-2025 with opt-in support continuing to the end of 2025. The migration path is spelled out in three steps: upgrade libraries using armon/go-metrics to consume hashicorp/go-metrics/compat instead, which the README says should involve only changing import statements, then update the application dependencies to versions that have the compatibility layer configured, then replace application imports of github.com/armon/go-metrics with github.com/hashicorp/go-metrics and instrument the build system to build with the hashicorpmetrics tag. Once the default changes you can drop that tag.

The dependency set tells you what it plugs into

The go.mod file is short enough to read in full, and it confirms the shape of the package. The module is github.com/hashicorp/raft-boltdb, the Go version directive is 1.26.0, and the direct requirements are boltdb/bolt at v1.3.1, hashicorp/go-metrics at v0.7.0, hashicorp/go-msgpack at v0.5.5 and hashicorp/raft at v1.8.0. The go-msgpack dependency is the one worth noticing, because it explains the encoding choice: Raft's log and stable state are serialised with msgpack rather than JSON or gob. The indirect list pulls in the usual raft dependencies, including go-immutable-radix and go-hclog, plus the test stack of testify and the colour libraries that the metrics packages use for terminal output. The repository root holds the implementation in bolt_store.go, with util.go and metrics.go beside it, the tests in bolt_store_test.go, a bench_test.go for benchmarks, and a Makefile for the test target. There is also a v2/ directory, so the module carries a second major version alongside the current one.

Running the tests and the benchmark

The Makefile is a two target file. The test target runs the whole suite with a timeout, and the deps target refreshes the module dependencies.

bash
	go test -timeout=30s ./...
bash
	go get -d -v ./...

The thirty second timeout in the test target is a deliberate choice rather than a default, and it says something about the expected behaviour of the store: a test that blocks on a lock or a transaction should fail rather than hang. The repository also carries a .go-version file, a .golangci.yml for linting, a .travis.yml for the older continuous integration setup, a CHANGELOG.md and a Makefile at the root, plus a .github/ directory. The v2/ subdirectory has its own arrangement of the same code, which is the usual way a Go module keeps a major version in-tree.

What a single file store costs you, and what the alternative looks like

The honest limitation is the one implied by the storage engine. The Raft log and the stable store live in a file on the disk of the node itself, so the availability of that state is bound to that node and that disk. A Raft cluster is designed to survive node failure through replication of the log, and the replicated log is what gets sent to other nodes, but the local file is the local copy. The choice is not free in either direction: BoltDB is a single mmap-ed file with a simple operational story and no separate compaction process to understand, and it is the engine the HashiCorp stack has used for years, while another Raft backend would give you a different file layout, different performance characteristics and a different set of operational surprises. The other limitation is the metrics default itself, which is a deprecation with a deadline rather than a solved problem, and a build that still uses the armon path after the end of 2025 is on borrowed time.

Maintenance, licensing and where the project sits

The repository is not archived, and the last push was on 2026-09-16, the same day as the v2.4.2 tag. The release history shows v2.3.1 from 2025-01-13 and v2.3.0 from 2023-11-15 behind it, so the 2.x line is the stable one and the v2/ directory in the tree is where its code lives. The licence is MPL-2.0, which is a per-file copyleft scheme: if you modify a file of this library and distribute it, you publish the modification under the same terms, while the rest of your program stays under your own licence. That is a more permissive outcome than a whole program copyleft, and it is the usual choice for a library that HashiCorp products link into larger programs. As an adopter you do not need to change anything about how you license your own code, but the boundary between the library and your code is the thing to be aware of if you fork the file rather than importing it.

Editorial conclusion

Adopt raft-boltdb when you are running hashicorp/raft and want the log, the current term and the vote in one embedded file rather than in an external database, and when a single process on a local disk is an acceptable availability model. Do not adopt it if you need replication of the log store itself, since the file lives with the node and this package does not address storage durability beyond what BoltDB provides. Before you wire it in, read the metrics table in the README, because the freelist and page gauges tell you what the file is doing, and check which go-metrics implementation your build uses, since the armon path is deprecated and the default changes.

Frequently asked questions

What does the raft-boltdb package provide?

It provides the raftboltdb package, which exports the BoltStore, an implementation of both a LogStore and a StableStore. It is meant to be used as a backend for the hashicorp/raft package, with BoltDB as the underlying key/value store.

How do I choose between armon/go-metrics and hashicorp/go-metrics?

The choice is controlled by build tags. The armonmetrics tag routes metrics to armon/go-metrics and hashicorpmetrics routes them to hashicorp/go-metrics, and with no tag the default is armon/go-metrics, which the README states is deprecated with the default expected to change around mid-2025.

Which dependencies does raft-boltdb need?

The go.mod file lists boltdb/bolt v1.3.1, hashicorp/go-metrics v0.7.0, hashicorp/go-msgpack v0.5.5 and hashicorp/raft v1.8.0 as direct requirements, and the module declares Go 1.26.0.

How do I run the tests for raft-boltdb?

The Makefile provides a test target that runs go test -timeout=30s ./... across the repository. A separate deps target refreshes dependencies with go get.

What is the writeCapacity metric in raft-boltdb?

It is a sample of the theoretical write capacity in logs per second. Each sample projects what the capacity would be if future batched log write operations resembled that one, taking into account batch size, byte size, disk performance and boltdb performance, and the README suggests aggregating it over a longer window for a useful picture.

Official sources

  1. hashicorp/raft-boltdb on GitHub
  2. Issues
  3. License: MPL-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hashicorp-raft-boltdb.svg)](https://hysenlabs.com/projects/hashicorp-raft-boltdb)

Was this useful?