Barrel Docs
The document layer. Version-vector MVCC, BQL queries, attachments, a changes feed, and replication. Use it inside the full Barrel, or standalone as an embeddable library.
Core Capabilities
Everything you need for document storage, querying, and distributed sync.
MVCC
Multi-version concurrency with HLC version vectors.
- + Causal, coordinator-free
- + Retained history
- + Conflicts kept, with a merge hook
BQL Queries
A PartiQL dialect with automatic path indexing.
- + Auto path indexing
- + No manual indexes
- + Live subscriptions
Replication
Multi-master sync with replication policies.
- + Chain, Group, Fanout
- + Filtered replication
- + One-shot or continuous
Subscriptions
Real-time notifications via MQTT-style patterns.
- + Path patterns
- + Query subscriptions
- + Changes feed
Timeline
Branch, point-in-time restore, and merge branches back
TTL and retention
Expire documents and bound the retained history
Attachments
Content-addressed blobs, streamed and replicated
HLC Ordering
Hybrid Logical Clocks for distributed coordination
Provenance and audit
Every write records actor, session, and source
Embeddable
Use as a library in Erlang/Elixir apps
Replication Policies
Chain
A → B → C
Sequential replication with sync writes
Group
A ↔ B ↔ C
Multi-master with conflict resolution
Fanout
A → B, C, D
Event distribution to multiple targets
Use Cases
Edge Computing
Deploy nodes that sync to cloud when connected
Multi-Region
Replicate data across regions with conflict resolution
Offline-first apps
Local writes that converge when back online
Event Distribution
Fan-out patterns for event streaming architectures
Quick Start
%% Start the application
application:ensure_all_started(barrel_docdb).
%% Create a database
{ok, _} = barrel_docdb:create_db(<<"mydb">>).
%% Put a document
{ok, #{<<"id">> := Id}} = barrel_docdb:put_doc(<<"mydb">>, #{
<<"type">> => <<"user">>, <<"name">> => <<"Alice">>
}).
%% Query with BQL
{ok, Rows, _} = barrel_docdb:query(<<"mydb">>,
<<"SELECT * FROM db WHERE type = 'user'">>).
%% Subscribe to changes (MQTT-style patterns)
{ok, _Ref} = barrel_docdb:subscribe(<<"mydb">>, <<"type/user/#">>). # barrel_docdb is embedded-only. Run barrel_server for an HTTP surface.
$ curl -X PUT localhost:8080/db/mydb
{"ok":true,"db":"mydb"}
$ curl -X PUT localhost:8080/db/mydb/doc/alice \
-H 'content-type: application/json' -d '{"type":"user","name":"Alice"}'
{"id":"alice","ok":true,"rev":"0000019f46b4c08900000000@8c0010c983917d4b"}
# BQL over HTTP.
$ curl -X POST localhost:8080/db/mydb/query \
-H 'content-type: application/json' \
-d '{"query":"SELECT * FROM db WHERE type = '"'"'user'"'"'"}'
# The changes feed, as JSON or Server-Sent Events.
$ curl localhost:8080/db/mydb/changes
$ curl -H 'accept: text/event-stream' localhost:8080/db/mydb/changes For a REST/JSON or MCP surface, run barrel_server over the same database.
When to Use
Use Barrel Docs when:
- + You need document versioning and history
- + Offline-first or sync is required
- + Multi-device or multi-region sync is needed
- + You want to embed it in an Erlang/Elixir app
Consider alternatives when:
- + Simple key-value is enough
- + You need full relational SQL
- + Graph traversal is the core workload
- + You also need vectors (then use the full Barrel)
One record with vectors
In the full Barrel, a document and its embedding share one id, so there is no integration code between a document store and a separate vector index. Store text, get search.
Explore Barrel →