A layer of Barrel

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.

CORE

MVCC

Multi-version concurrency with HLC version vectors.

  • + Causal, coordinator-free
  • + Retained history
  • + Conflicts kept, with a merge hook
QUERY

BQL Queries

A PartiQL dialect with automatic path indexing.

  • + Auto path indexing
  • + No manual indexes
  • + Live subscriptions
SYNC

Replication

Multi-master sync with replication policies.

  • + Chain, Group, Fanout
  • + Filtered replication
  • + One-shot or continuous
REALTIME

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 →