Join 10350+ others. No spamming.
I promise!

Follow us at github.



slashdotdash / eventstore


CQRS event store using PostgreSQL for persistence



CQRS event store implemented in Elixir. Uses PostgreSQL as the underlying storage engine.

Requires Elixir v1.5 and PostgreSQL v9.5 or newer.

EventStore supports running on a cluster of nodes (since v0.11). Stream processes will be distributed amongst all available nodes, events are published to subscribers running on any node.


MIT License

Build Status


Example usage

Append events to a stream:

stream_uuid = UUID.uuid4()
expected_version = 0
events = [
    event_type: "Elixir.ExampleEvent",
    data: %ExampleEvent{key: "value"},
    metadata: %{user: ""},

:ok = EventStore.append_to_stream(stream_uuid, expected_version, events)

Read all events from a single stream, starting at the stream's first event:

{:ok, events} = EventStore.read_stream_forward(stream_uuid)

More: Using the EventStore

Subscribe to events appended to all streams:

{:ok, subscription} = EventStore.subscribe_to_all_streams("example_subscription", self())

receive do
  {:events, events} ->
    # ... process events & ack receipt    
    EventStore.ack(subscription, events)

More: Subscribe to streams

Used in production?

Yes, this event store is being used in production.

PostgreSQL is used for the underlying storage. Providing guarantees to store data securely. It is ACID-compliant and transactional. PostgreSQL has a proven architecture. A strong reputation for reliability, data integrity, and correctness.

Backup and administration

You can use any standard PostgreSQL tool to manage the event store data:

Benchmarking performance

Run the benchmark suite using mix with the bench environment, as configured in config/bench.exs. Logging is disabled for benchmarking.

$ MIX_ENV=bench mix do es.reset, app.start, bench

Example output:

## AppendEventsBench
append events, single writer                  100   10170.26 µs/op
append events, 10 concurrent writers           20   85438.80 µs/op
append events, 100 concurrent writers           2   1102006.00 µs/op
## ReadEventsBench
read events, single reader                   1000   1578.10 µs/op
read events, 10 concurrent readers            100   16799.80 µs/op
read events, 100 concurrent readers            10   167397.30 µs/op


Pull requests to contribute new or improved features, and extend documentation are most welcome.

Please follow the existing coding conventions, or refer to the Elixir style guide.

You should include unit tests to cover any changes.


Need help?

Please open an issue if you encounter a problem, or need assistance.

For commercial support, and consultancy, please contact Ben Smith.