Changelog
View SourceAll notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-10
First stable release. The barrel_docdb API is frozen: it will not break
without a major version.
Changed (breaking)
barrel_docdb:query/2,3rejects a table-function source with{error, {table_fn_requires_barrel, Fn}}. The atom wastable_fn_requires_facade; it was never in a published release.
Changed
- Documentation refresh: the doc set now describes the HLC version-vector model
(dropping the removed rev-tree functions
put_rev/revsdiff), and the HTTP API pages point tobarrel_serversince barrel_docdb is embedded-only. See the umbrella CHANGELOG.
[0.8.0] - 2026-06-14
Removed (breaking)
- The HTTP server and its REST/SSE/admin API are gone. barreldocdb is now
embedded-only: use it as an Erlang library via the
barrel_docdbmodule. This drops theliverydependency, the API-key store, the signed-peer registry, and the HTTP replication transport. Replicate in-process withbarrel_rep_transport_localor your ownbarrel_rep_transportbehaviour (URL replication targets now raise `{http_transport_removed, }`).
Fixed
find/2,3: an AND of two or more{compare, ...}conditions no longer returns the empty set.find/2,3:{prefix, Path, Prefix}works as a sole condition.- Documents re-created over a tombstone are re-indexed, so
findreturns them.
Added
find/2,3id scans:#{id_prefix => P}and#{id_range => {Start, End}}ordered primary-key range scans over the document id.find/2,3flat => truereturns flat documents (Doc#{<<"id">>}) instead of the#{<<"id">>, <<"doc">>}wrapper.
Changed
- OTP 29: dropped the deprecated prefix-
catchoperator reliance; addedbarrel_libwith reusablesafe_*helpers. - Bumped
rocksdbto 3.0.0 andinstrumentto 1.1.4.
Notes
- Top-level fields whose key begins with
_are reserved metadata: they are not stored or indexed, so they cannot be queried.
[0.7.7] - 2026-06-11
Changed (breaking)
/_replicatenow refuses to call out to anything not in the new peer registry. The request body must carry eitherpeer_id(a registered peer's id, URL pulled from the registry) or atargetURL that matches a registered peer's canonical URL. Anything else is rejected with 403unregistered_peer. Closes the SSRF surface (security-review #6): an authenticated key holder can no longer aim outbound replication at127.0.0.1,169.254.169.254, RFC1918, or any unregistered host.- The inbound replication-receiving endpoints (
_revsdiff,_put_rev,_sync_hlc) now require a valid Ed25519 signature from a registered peer (X-Peer-Id,X-Peer-Timestamp,X-Peer-Signatureheaders) in addition to the existing API key. Missing or invalid signatures return 401peer_signature_required/unregistered_peer/invalid_peer_signature. - Outbound replication calls now always include
peer_auth => true, i.e. every request between registered peers is signed.
Added
- New module
barrel_peer_registry(DETS-backed, file<data_dir>/peers.dets). Schema:peer_id,name, canonicalurl,public_key,databases,created_at,last_used. - Admin HTTP routes:
GET /peers— list registered peers.POST /peers— register a peer. Body:{"name": "...", "url": "...", "public_key": "<base64>", "peer_id": "..."}for an explicit registration, or{"name": "...", "url": "...", "discover": true}to TOFU-fetch the remote's/.well-known/barrelpubkey.GET /peers/:peer_id— fetch one entry.DELETE /peers/:peer_id— revoke. All four routes require an admin API key.
- Config knob
replication_require_registered_peer(defaulttrue),BARREL_REPLICATION_REQUIRE_REGISTERED_PEER. Setting it tofalsere-enables the legacy free-form target URL behaviour as a migration escape hatch — scheduled for removal in 0.8.0.
Migration
- Existing replication clients that call
/_replicatewith a rawtargetURL must register the target first (POST /peers {..., "discover": true}is the easy path on trusted networks), then either continue calling/_replicatewith the same URL or switch topeer_id. - Inbound endpoints will start returning 401 to any caller that isn't a registered peer. Make sure both ends of every replication link register each other before deploying this version.
[0.7.6] - 2026-06-05
Changed (breaking)
- Query timeout now hard-fails instead of silently truncating.
When the document-fetch pipeline (or the
barrel_parallelworker pool) does not finish withinquery_timeout_ms(default 30000ms, override viaBARREL_QUERY_TIMEOUT_MS), the call raiseserror({query_timeout, Info}). The HTTP/_findendpoint maps this to 504 Gateway Timeout with a JSON/CBOR body of{"error":"query_timeout","completed":N,"total":T, "missing_batches":M,"timeout_ms":Ms}. Callers that previously received a partial{ok, Results, Meta}with no signal must now handle the 504.
Added
barrel_query_timeoutscounter (Prometheus / OTel) records every pipeline or pool deadline expiry.- Configurable global deadline
query_timeout_msshared bybarrel_queryandbarrel_parallel. Replaces the previous hardcoded 30s and 60s splits.
Fixed
barrel_parallel:pmap/2,3spawn-fallback path used a barereceivewith no deadline, so a stuck worker would hang the caller forever. Now bounded by the samequery_timeout_ms.
[0.7.5] - 2026-06-04
Added
- HTTP request body size cap and in-flight request cap via livery's
middleware stack. Buffered bodies above
http_max_body_bytes(default 4 MiB) return 413; concurrent requests abovehttp_max_in_flight(default 1000) shed with 503. Both tunable viaBARREL_HTTP_MAX_BODY_BYTES/BARREL_HTTP_MAX_IN_FLIGHT. Streamed attachment uploads bypass the body cap by design.
Changed
barrel_http_api_keysnow reads the canonicaldata_dirconfig key, with a deprecation-warning fallback to legacydata_path. The fallback is scheduled for removal in 0.8.0.
Removed
- Dead cowboy-era config keys
http_acceptors,http_max_connections, andhttp_protocols. Livery's defaults (60s request timeout, 300s idle timeout) replace them; per-request caps are enforced by middleware.
[0.7.4] - 2026-06-04
Changed
- The OpenAPI 3.1 document is now generated at boot from the route
table in
barrel_http_serverand served live atGET /openapi.json. A Redoc UI is atGET /docs. Both are public (no API key required) so SDK generators and importers can pull the spec without credentials. - Per-route OpenAPI metadata (
operation_id,summary,tags, optionalparameters/request_body/responses) lives next to each route inbarrel_http_server:routes/0. To update the doc, edit the route metadata; the next service start picks it up.
Removed
docs/api/openapi.yaml(hand-maintained spec) and the staleopenapi.yamlat the repo root (0.5.0, referenced the JWT scheme we removed in 0.6.2). Replaced by the live endpoint.docs/api/openapi.mdrewritten to point at/openapi.jsonand/docsinstead of the deleted YAML file.
[0.7.3] - 2026-06-04
Changed
- Authentication and authorisation moved into a livery middleware. New module
barrel_docdb_authis a service-level middleware (one entry inbarrel_http_server's middleware stack) that classifies every request by(path, method)intopublic/admin/{data, DbName, ReadOrWrite}, runs the API-key check, and 401/403s before the handler ever runs. Handlers no longer callmaybe_authenticate/authorize/required_perm— those lived insidebarrel_http_handlerand have been removed. - Routes stay 3-tuples; there's no per-route auth decoration. The middleware parses the database name and required permission from the raw path (service-level middleware runs before livery's router sets path bindings, so we can't rely on
livery_req:binding/2there). barrel_http_api_keys(DETS-backed key store) andbarrel_peer_auth(replication Ed25519 signing) are unchanged. The validated key map is attached to the request vialivery_req:set_meta(auth_ctx, _, _)for handlers that want to inspect the caller.
[0.7.2] - 2026-06-04
Changed
- HTTP observability moves into livery middleware.
barrel_http_servernow wireslivery_request_id,livery_instrument_trace,livery_instrument_metrics, andlivery_access_loginto the service stack. Every request gets a W3Ctraceparentpropagation, an OpenTelemetry server span with semantic-convention attributes, the standardhttp.server.active_requests+http.server.request.durationmetrics, and an access log line. /metricsis now served bylivery_metrics:handler/0. The Prometheus exposition format is unchanged; both livery's HTTP middleware andbarrel_metrics's domain registrations feed the sameinstrumentregistry.barrel_http_handler:handle/2no longer wraps requests inbarrel_trace:with_extracted_context/2+with_http_span/3— the middleware does it.
Removed
- HTTP-shaped entries from
barrel_metrics:barrel_http_requests(counter),barrel_http_request_duration_seconds(histogram), and theinc_http_requests/3+observe_http_latency/3helpers. Replaced by livery's OTel-semantic-convention names (http.server.active_requests,http.server.request.duration). Dashboards or alerts referencing the old names need updating.
Kept
- Domain metrics (doc ops, query ops, replication, db gauges) and the
barrel_trace:*helpers — they're used by domain code, not HTTP plumbing.
[0.7.1] - 2026-06-04
Changed
- Switch
liveryfrom a git pin againstmainto the hex package0.2.0. - Replace
hackneywithlivery_clientfor outbound replication HTTP.barrel_rep_transport_httpnow useslivery_client:request/4for the_changes/_put_rev/_revsdiff/_sync_hlccalls, giving outbound replication the same composable middleware stack the server side has. The underlying transport remains hackney (via livery'slivery_client_hackneyadapter), but is no longer a direct barrel dep. - Drop
hackneyfromrebar.configdeps,barrel_docdb.app.srcapplications, and the relx release list. It still arrives as a transitive dependency of livery.
[0.7.0] - 2026-06-04
Changed
- HTTP layer migrated from cowboy to livery. All HTTP endpoints, headers, and response shapes are unchanged; the framework swap is internal. The dep graph drops
cowboy/cowlib/ranchand addslivery(and its transitiveh1/h2/quic/ws/webtransport/barrel_mcp). Consumers building a release from source needliveryin their build environment. - HTTP/2 is supported out of the box (livery serves H1 and H2 from one listener via h2c upgrade or prior knowledge). HTTP/3 is available via livery and can be enabled in a follow-up.
- HTTP modules are now grouped under
src/web/(rebar3src_dirsextended). instrumentis now consumed from hex (1.1.3) instead of the git pin, matching livery.
Internal
barrel_http_servercallslivery:start_service/1+livery_router:compile/1instead of cowboy's listener / dispatch APIs.barrel_http_handlerreturns value-based responses vialivery_resp:new/3,livery_resp:stream/3. Per-actionhandle_action/3clauses keep the same internal tuple shape; conversion is centralized inhandle/2.barrel_http_changes_streamuseslivery_resp:sse/3with a producer closure that owns the poll/heartbeat loop.
[0.6.4] - 2026-06-02
Security
- API key permissions are now enforced. Before 0.6.4 the
permissionsfield on an#api_keyrecord was stored and returned but discarded by the HTTP handler, so a key declared as[<<"read">>]could still write, delete, replicate, or bulk-update. A newauthorize/3step inbarrel_http_handlermaps each(action, method)pair to a required permission (read/write/admin) and returns 403 when missing.is_admin = trueand the "no keys configured yet" mode short-circuit. Admin-gated endpoints (/keys/*,/admin/*) are unchanged. - Chunked attachment metadata no longer goes through
binary_to_term. The writer now stores chunked metadata as<<"BARREL_CHUNK_V1:", json:encode(Meta)/binary>>; the reader pattern-matches on the tag and falls back to the legacyterm_to_binaryblob viabinary_to_term/2with[safe]for one release (with a warning log). Removes a path that decoded user-controlled bytes as Erlang terms. - Query-op whitelist.
convert_op/1in the HTTP handler used to callbinary_to_atom/1on any unrecognized binary, which could exhaust the atom table. The function now accepts only the documented set (eq/==,ne/!=/=/=,gt/>,gte/>=,lt/<,lte/<=/=<) and rejects everything else with HTTP 400.
Deprecated
- Legacy
term_to_binarychunked-attachment metadata. Attachments created on 0.6.3 or earlier are still readable in 0.6.4 with a warning; the fallback will be removed in 0.7.0.
[0.6.3] - 2026-06-02
Security
- MVCC: stale or missing
_revon update is now rejected with{error, conflict}(HTTP 409). Previously,barrel_docdb:put_doc/2,3and the bulk path silently overwrote the stored body and reported a different winning rev — a classic lost-update bug. The replication path (put_rev, bulk entries carrying explicithistory) is unchanged: the revtree merge handles conflict detection there. - Database names are validated.
barrel_docdb:create_db/1,2anddelete_db/1reject anything that does not match[a-z0-9_-]{1,63}(system databases keep their leading_). HTTP 400 is returned for invalid names atPUT /db/:dbandDELETE /db/:db. Prevents filesystem traversal via the data directory. delete_db/1no longer shells out. Replacesos:cmd("rm -rf " ++ DbPath)withfile:del_dir_r/1. Removes the shell-injection surface that depended on whatever ended up inDbPath.
[0.6.2] - 2026-06-02
Removed
- JWT authentication (
barrel_docdb_jwt,console_public_keyconfig,bdb_token branches in the HTTP handler) and thejosedependency. API key auth (ak_*) is the only bearer-token scheme. - Dead VDB benchmark code (
bench/src/workloads/barrel_bench_vdb.erl,barrel_bench:run_vdb*, VDB portions of the HTTP bench) referencing the long-removedbarrel_vdbmodule. - Stale
test/docker/CHECKPOINT.mdreferencing removedbarrel_rep_policywork.
Changed
- Bumped
instrumentto v1.1.3 for Erlang/OTP 29 compatibility (replaces deprecatedcatch Exprwithtry ... catch). - Replaced deprecated
catch Exprpatterns inbarrel_docdb,barrel_db_server,barrel_query,barrel_query_cursor, and the affected test suites; addedbarrel_store_rocksdb:safe_release_snapshot/1helper. - Updated docs to drop references to removed modules (
run_vdbbenchmark; "Sharding Strategy" renamed to "Bucketing Strategy" for the time-bucketed posting list).
[0.6.1] - 2026-06-01
Changed
- Moved to Erlang/OTP 28 (CI containers, Dockerfile builder, and docs).
Fixed
- Docker image now boots on OTP 28: the runtime stage uses
debian:trixie-slimto match theerlang:28builder's glibc (it was left onbookworm-slim, so ERTS failed withGLIBC_2.38 not found). - Release CI job builds in the
erlangcontainer instead of installing Erlang frompackages.erlang-solutions.com, which had failed the v0.6.0 release. - The relx release version was hardcoded
0.4.2; it now matches the application version.
[0.6.0] - 2026-05-26
Added
GET /.well-known/barrelnode identity endpoint returningnode_id,version, and (when peer auth is initialized)public_key, with no dependency on discovery or federation- Public
barrel_docdb:node_id/0seam (persistent_node_idsystem document) for an external discovery or cluster layer
Removed
- Virtual Database (VDB) and sharding: removed
barrel_vdb*,barrel_shard_map, andbarrel_shard_rebalancewith the/vdbHTTP endpoints - Federation and peer discovery: removed
barrel_federationandbarrel_discoverywith the/_federation,/_peers, and/.well-known/barrelendpoints - Replication policies: removed
barrel_rep_policy(chain/group/fanout/tiered patterns) and the/_policiesendpoints; the replication engine (barrel_rep,barrel_rep_tasks, transports) is unchanged - Tiered storage: removed
barrel_tierand the/db/:db/_tier/*endpoints; thecreated_at/expires_at/tierentity columns are kept as reserved fields so the on-disk format is unchanged - Materialized views: removed
barrel_view,barrel_view_index,barrel_view_sup, theregister_view/unregister_view/query_view/list_views/refresh_viewAPI, and the/db/:db/_views/*endpoints
Changed
- Reduced scope to a document-database core: CRUD with MVCC, declarative queries, changes feed, attachments, pub/sub, and the replication engine. Sharding, tiering, and clustering can be built on top via the public API (changes feed, revision primitives, HLC, system and local documents, store/index introspection, and metrics).
barrel_peer_authis retained (used by the HTTP replication transport); its node id now persists in a_node_idsystem document.- Upgraded the instrument dependency to v1.1.2.
Fixed
- Metrics exemplar reservoir table is no longer lost on an application stop/start. It is initialized in
barrel_metrics:setup/0, which previously causedbarrel_rep_tasksto crash on restart when the first histogram value was recorded.
[0.5.0] - 2026-04-04
Added
- Views with Map/Reduce: Secondary indexes with map/reduce support
- Module-based views with
map/1and optionalreduce/3callbacks - Query-based views with declarative key/value extraction
- Built-in reduce functions:
_count,_sum,_stats - Rereduce support for merging results from sharded queries via
merge_reduced_results/2 - Manual and automatic refresh modes
- Module-based views with
- OpenAPI 3.0 Specification: Full API documentation with Swagger UI at
/api-docs barrel_docdb:fold_docs/4with options support (limit, skip, start_key, end_key)barrel_query:matches/2for simple condition matching outside of queries
Changed
- Migrated from legacy
{Epoch, Counter}sequence format to HLC timestamps throughout - Removed
barrel_sequencemodule (functionality consolidated inbarrel_hlc) - Upgraded hlc to 3.0.3 and match_trie to 1.0.0
- Upgraded rocksdb to 2.6.2
- Removed unused bitmap dependency
Fixed
- Multiple dialyzer warnings across modules
- Dead code removal in fold_range functions
- Unmatched return values in shard rebalancing
[0.4.1] - 2026-03-08
Fixed
- Snapshot handle leak in chunked exists/prefix query paths where temporary snapshots were never released
- Streaming attachment uploads now clean up orphaned chunks on failure via
new
abort_stream/1function
Added
abort_attachment_writer/1API to clean up partial attachment uploads- Snapshot support for pure compare queries ensuring read consistency
fold_compare_docids_with_snapshot/8in barrel_ars_indexfold_range_posting_compare_with_snapshot/6in barrel_store_rocksdb
[0.4.0] - 2026-03-05
Added
- Authentication support for federation queries with
bearer_tokenandbasic_authformats - Federation-level auth stored with config, per-query auth override in find options
doc_idsfiltering for changes feed to subscribe to specific documents- Query-based filtering for changes feed with
whereconditions - GitHub Actions CI/CD workflows for automated testing and releases
Fixed
- VDB replication setup by adding
syncoption to peer registration - JSON encoding of peer public keys in HTTP API responses
Changed
- Upgraded hackney to 3.2.1
[0.3.2] - 2026-02-13
Fixed
- SSE changes stream now correctly includes document bodies when
include_docs=true - Fixed
get_changes_full_scanto route to filtered path wheninclude_docsis requested - Fixed
get_changes_filteredto setNeedsDocflag wheninclude_docs=true
Added
changes_stream_include_docstest to verify document bodies in SSE events
[0.3.1] - 2026-02-13
Verified
- SSE changes stream stability confirmed with all tests passing
since=nowparameter handling working correctly- Heartbeat mechanism keeping connections alive
[0.3.0] - 2026-02-12
Added
JWT Authentication
- ES256 (ECDSA P-256) JWT token validation for API authentication
- Token format:
bdb_<base64-encoded-JWT>prefix for barrel_docdb tokens - Required claims validation:
sub,typ,oid,prm,exp - Workspace isolation via optional
widclaim - Permission-based access control with
is_adminflag - File-based or inline PEM key configuration
Usage Reporting
- New
barrel_docdb_usagemodule for database statistics GET /admin/usage- Get usage stats for all databasesGET /admin/databases/:db/usage- Get stats for specific database- Stats include: document_count, storage_bytes, memtable_size, sst_files_size
Ed25519 Peer Authentication for P2P Replication
barrel_peer_authgen_server for Ed25519 key management- Automatic keypair generation on startup
- Request signing with canonical format:
timestamp|peer_id|method|path|body_hash - 5-minute timestamp window for replay protection
- HTTP headers:
X-Peer-Id,X-Peer-Timestamp,X-Peer-Signature - Public key exposed via
/.well-known/barreldiscovery endpoint - Optional
peer_authoption in HTTP transport (disabled by default)
Fixed
SSE Changes Stream Reliability
- Reduced heartbeat interval from 60s to 30s (below Cowboy's idle_timeout)
- Added
idle_timeout => 120000to Cowboy protocol options - Added
request_timeout => infinityfor long-running SSE streams - Fixed
since=nowparameter crash (was callingbarrel_hlc:encode(now)) - Simplified
parse_since/1to only accept valid base64-encoded HLC binaries
API Compatibility
- Fixed
barrel_docdb_usageto usedb_pid/1+get_store_ref/1API - Updated all HTTP tests for hackney 3.x API (body in 4th tuple element)
Changed
- Upgraded hackney to 3.0.2
- Default heartbeat for SSE streams changed from 60s to 30s
Tests Added
barrel_docdb_usage_SUITE- 6 tests for usage statistics modulebarrel_docdb_jwt_SUITE- 10 tests for JWT authenticationbarrel_peer_auth_tests- 11 EUnit tests for peer authentication- HTTP usage endpoint tests (4 tests in barrel_http_SUITE)
- SSE stream tests:
changes_stream_since_now,changes_stream_heartbeat
[0.2.0] - 2025-01-12
Added
Virtual Databases (VDB) - Automatic Sharding
- New VDB layer for horizontal scalability with automatic document sharding
- Consistent hashing of document IDs for even distribution across shards
- Scatter-gather queries across all shards with merged results
- HTTP API endpoints for VDB operations (
/vdb/:vdb/*) - Shard split and merge operations for rebalancing
- Multi-datacenter sharding with zone-aware placement
- Cross-node VDB configuration synchronization
- VDB shard replication with automatic failover
- Import from regular database to VDB (
POST /vdb/:vdb/_import) - VDB benchmarks and comprehensive documentation
HTTP/2 Support
- HTTP/2 cleartext (h2c) via HTTP Upgrade mechanism
- HTTP/2 over TLS (h2) with ALPN negotiation
- Graceful degradation to HTTP/1.1 for legacy clients
- Environment variable configuration for TLS/HTTP2 in releases
Docker & CI
- Multi-architecture Docker builds (amd64 + arm64)
- GitLab CI pipeline with buildx for container builds
- Docker multi-region VDB test suite
Documentation
- VDB overview and sharding guide
- Multi-datacenter deployment documentation
- Advanced features guide with curl examples
- HTTP API reference for VDB endpoints
Fixed
- HTTP test suite isolation by unlinking server process
- VDB cross-node sync authentication
- Replication policy auth and checkpoint error handling
- HTTP benchmarks and documentation links
Changed
- Upgraded hackney to 2.0.0-beta.1
- Added LZ4 and Snappy libraries for RocksDB native build
[0.1.0] - 2024-12-01
Added
- Initial release
- Document CRUD with MVCC revision trees
- Declarative queries with automatic path indexing
- Real-time subscriptions via MQTT-style path patterns
- HTTP API with REST endpoints
- Peer-to-peer replication with configurable patterns (chain, group, fanout)
- Federated queries across multiple databases
- Tiered storage with automatic TTL/capacity-based migration
- Prometheus metrics for monitoring
- HLC ordering for distributed event coordination