Pre-1.0 hoardDB is pre-1.0. Expect breaking changes.
Limitations
hoardDB is pre-1.0. This page is the honest list of what it does not do or does not do the way you might expect. Read it before you design around it.
User management and authorization
- Role changes apply at the next AUTH. Authorization is decided per
connection from the identity established at AUTH. A
grant,revoke, oralter user ... rolesdoes not change what an already authenticated connection may do and does not terminate it; the change takes effect when that client authenticates again. If you need the change to bite immediately, change the password or disable the user (below). - Disable and drop close that user’s sessions. These two operations are the
deliberate exception:
alter user <name> disableanddrop user <name>close every session that user has open on the node serving the change.grantandrevokedo not. - User management is unavailable during a membership transition. While a node is being added to or removed from the cluster, a user mutation is refused with a retryable error. Queuing it would mean accepting a write the cluster cannot yet place. On a large cluster a rebalance is not a brief window.
- A follower that falls behind refuses logins and refreshes. In a cluster,
every node holds a full copy of the user store. A node that has not synced
with the master for longer than
auth_config_max_staleness_seconds(default300,HOARDB_AUTH_CONFIG_MAX_STALENESS) refuses new password AUTHs and token refreshes until it syncs. This is the deliberate trade-off: refusing logins is an outage, accepting a deleted or disabled credential is a security failure. Set the bound to what your recovery time allows. - A new cluster node with no user store blocks AUTH until it receives one.
A node that has a
users.jsonserves from it while it reconciles; a node with none will not accept logins from an empty user list. - Revocation is per user, not per token. Changing a password, disabling a
user, or a role change bumps that user’s
epochand refuses all their outstanding tokens at their next refresh. There is no way to revoke one individual token without affecting the rest. users.jsoncontains every password hash in the cluster. Decommissioning a node means deleting itsusers.json, exactly as it means wiping its cluster token. A member removed from the ring keeps its copy until you delete it.- The user store is sealed with the node master key, not your backup.
users.jsonis encrypted at rest under the node master key. A node that starts without that key material refuses to start rather than reconciling, and--reset-passwordcannot recover it — it reads the same file. Losing the key loses every user, role and epoch in the store, not just the ability to verify stored hashes. This is a wider failure than a lost password pepper used to be.
Queries
- A scan reads one node, not the whole cluster.
find()with no key, andfind({filter}), are served by the node that receives them. A bucket is held by its ring owner and replicas, so a request that reaches a node that is not a holder is refused rather than forwarded: the error names the ring owner and its cluster address, andnodeslists every member. Send the query to a node that holds the bucket. A scan is an ordinary read, so on a replica that is behind, the count reflects that replica;consistent getremains the verb for a read-your-writes guarantee. - Paging is
skip/limitover a live bucket, not a snapshot — andsortdoes not fix it. There is no server-side cursor: each page is a fresh scan, and asortorders the whole matched set again beforeskipandlimitare applied. A concurrent write between two pages can move a document across the page boundary, so a document can be seen twice (an insert ahead of the boundary) or missed entirely (a delete ahead of it). Sorting makes this worse rather than better, because a paged listing ordered by something likecreated_atlooks reliable and is not. Stop writes before exporting a bucket that must be consistent, or read it in a single page with alimitabove the match count. - Blob buckets do not scan. A blob’s value is binary content rather than a
document;
find()on a blob bucket refuses and points atinfo/getfor a single key. - Date-range queries on non-key fields are full bucket scans. A
btreebucket orders only its key, not its fields. A query like{ts: {$gt: ISODate("...")}}on a date field that is not the key walks every document in the bucket and filters by type and value, with no index help. Declare the date as the btree key if range queries on it are performance-critical.
Transport and sessions
- One request in flight per socket, no multiplexing. The protocol has no stream identifier; a client that wants concurrency opens another connection. Pipelining is bounded (4 frames by default) rather than unbounded.
- A frame is capped at 32 MiB (
transport.MaxFrameLength). A blob or document larger than that must be split or streamed, and chunked streaming is not implemented yet.
Cluster
- Cluster membership and replication are operational, but the observability is minimal. Lag and divergence are exposed through metrics, not through a richness of CLI status commands.
- hoardDB never removes a node automatically. A peer that stays unreachable is reported; an operator decides whether and when to remove it.
- User-management fencing is a reachability check, not consensus. The master confirms a strict majority of the current members are reachable before accepting a user mutation, and refuses with a retryable “no quorum” error otherwise. It is not a replicated consensus log; two nodes with divergent membership views can each believe they own the reserved key, and the term/version fence is what makes that safe.
Source and distribution
- The source is not published yet. hoardDB is source-available — the server under Business Source License 1.1, the client libraries under Apache-2.0 — but the public repository does not exist today. The history is being prepared for publication, and the source lands when hoardDB reaches v1.0.
Migration from another database
- Loading another database’s dump is not built. There is no
ingest,importor bulk-load command: whatdumpandrestoredo is back up and recover hoardDB buckets, and that is a different job from migrating off MongoDB. A plain-file import — BSON frommongodump, and JSON Lines — is committed before 1.0. Analysing a dump to recommend store types is later work and is not promised for 1.0.
Source: docs/user/limitations.md in the repository.