Pre-1.0 hoardDB is pre-1.0. Expect breaking changes.
Compatibility and versions
What you can rely on when you upgrade hoardDB: what talks to what, what is read back from disk, what happens when you run two builds at once, which platforms are built, and how a feature is retired.
hoardDB is pre-1.0 and no release has been tagged yet. Where this page says “today”, it describes the build in the repository. Where it states a rule, the rule is the project’s commitment from v1.0 on.
What carries a version
Three things are versioned, separately from the release number, because they have different consequences when they change.
| What | Where you see it | Today |
|---|---|---|
| Wire protocol | hoardDB-server -v and hoardDB-cli -v print protocol=N; the TLS handshake negotiates hoarddb/N | major 1 |
| Data directory | Checked by the server at start | storage layout version 2 (the shared store) |
| Dump format | format_version in a dump’s manifest.json and each bucket’s metadata.json | 2 |
The release (or devel for an untagged build) is printed by -v too:
hoardDB-server -v
hoardDB-server version=devel commit= build_date= protocol=1
The wire protocol
A client and a server speak the same protocol major or they do not talk.
- The major is negotiated before anything is sent. Both sides offer
hoarddb/1in the TLS handshake (the ALPN identifier), and every frame also carries the version in its header, so a connection can never mix versions. - A mismatch is named, not left to a decode failure later. A client that
offers no major the server serves is refused in the handshake, and one that
states a different major at login gets
server speaks protocol 1, client sent 2. - Inside a major, change is additive only. New operations, new optional
fields and new capability names can appear. A client ignores fields it does
not know, and a server ignores capability names it does not know. A server
that is asked for an operation it does not have answers
unsupported opcodeand the opcode’s number, never silence. - A breaking change gets a new major. It is never a silent reinterpretation
of
hoarddb/1. The server keeps serving the previous major for at least one release after a new one ships, and warns on every connection that uses the old one, with the date it will stop.
Today only major 1 exists, so no client has had to move yet. The one thing to
check when you mix versions is the line above: hoardDB-cli -v and
hoardDB-server -v should print the same protocol=.
The data directory
The server reads what is on disk at start and refuses what it does not understand, instead of guessing:
- The storage layout. This build keeps every bucket in one shared store per
node. A data directory written by the earlier layout (it has a
catalog.jsonof its own) is refused at start with a message that says so, and is not converted in place. Back it up with the earlier build’shoardDB-cli dump, then restore into a fresh data directory on this build. See Backup and restore. users.json. It carries its ownformat_version(today1), and a file with another version is refused. It is sealed under a key your backups must keep; see User management.- Encryption. A node’s encryption mode is fixed when its data directory is first started. A data directory started with encryption on is refused by a server configured without it, and the reverse; see Configuration.
- The memtable size a store chose at its first start is saved with the store
and kept on every restart (
store/memtable-choice.json). - Dumps.
restoreaccepts the dump format it writes (format_version2) and refuses any other with the version on both sides in the message. There is no format 1 to restore.
Going back is not supported
A node that has written to its log on a newer build cannot be started on an older one. The older build opens the data directory but reads the newer log entries as a damaged tail and discards them, and after a crash the copies of a bucket can silently disagree about writes that were acknowledged. The first time a node writes the newer format it logs one line saying so.
So the way back is a backup, not the old binary: copy the whole data directory before you upgrade, and go back by restoring that copy on every node. Limitations and Replication have the details.
Upgrading
No tagged release exists yet, so there is no earlier release to upgrade from. This is the procedure the current builds require, and it is the one to follow for every upgrade that touches a data directory.
- Stop writes and wait one minute. An earlier build has no gauge that tells you the log has caught up, so the wait is the margin.
- Stop every node.
- Copy each node’s whole data directory.
dumpis not a substitute: it leaves out blob payloads and user accounts. A copy of the directory keeps both. - Install the new build on every node.
- Start every node. Check
hoardDB-server -von each, thenstatusandnodesfrom the CLI.
Rolling upgrades
A cluster is not upgraded one node at a time. Do not run two builds side by
side in one cluster. Builds can disagree about where a bucket lives, and
nothing detects that disagreement; and a node that runs an earlier build cannot
pull data from an upgraded node until it is upgraded too. Data is pulled when a
node joins, when one is removed, when the cluster rebalances and when you run
migrate, so a cluster of mixed builds can stall in the middle of one of those.
The rule that follows: upgrade every node to the same build before you add a
node, remove one or run migrate, and if you find a cluster of mixed builds,
finish the upgrade first. Whether a later release can support a true rolling
upgrade is a decision that has not been made; this page will say so when it
has.
Supported platforms
The server and the CLI are built for four platforms:
| Operating system | Architecture |
|---|---|
| Linux | amd64, arm64 |
| macOS | amd64, arm64 |
Windows is supported through WSL2, using the Linux binaries. The Docker image
builds for linux/amd64 and linux/arm64.
What “supported” means, precisely: the platform build produces each file and
checks that it is the architecture its name says (scripts/build-matrix.sh,
described in Installation), and the captured session in
Getting started was run end to end on linux/amd64.
Another platform is supported in the sense that it is built on every platform
build; a report that it misbehaves is a defect, not an unsupported
configuration.
Building from source needs the Go version named in go.mod (Go 1.26.8
at the time of writing).
How a feature is retired
The rule (and the reason for it): hoardDB never breaks your data or your programs silently. Trust is the whole product.
- Deprecate loudly. A feature that is going away keeps working for a stated period and prints a warning on standard error each time it is used. The warning names what to use instead and the date the old way stops.
- Version explicitly. A change a program could notice — a wire change, a
changed meaning of a setting, a new on-disk layout — is named in the
project’s
CHANGELOG.md(at the root of the repository) under what changed and what to do about it, and a wire change raises the protocol major as described above. - Refuse, do not guess. When an old form is no longer accepted, it fails
with a message that says what replaced it. For example, the old
define bucketstatement is refused on purpose with the textdefine was renamed: use 'create bucket <name> { type: hash }', so an old script stops at once instead of doing something different. - Never lose data on the way. An upgrade that cannot read your data stops and says so. It does not discard what it does not understand.
Before v1.0 this was not always possible. Changes made before a release —
for instance, the environment variable prefix that became HOARDDB_ — were
made without a deprecation period, and CHANGELOG.md records them. From v1.0 the
rules above apply.
Source: docs/user/compatibility.md in the repository.