Configure subscription concurrency and partitioning
masterTo implement the competing consumers pattern and increase throughput, you can configure a subscription to support multiple concurrent subscribers.
Concurrency Options
concurrency_limit: The maximum number of concurrent subscribers allowed. Defaults to 1. If exceeded, returns{:error, :too_many_subscribers}.buffer_size: Limits the number of in-flight events sent to the subscriber before an acknowledgement is required. Defaults to 1.partition_by: A function used to distribute events to subscribers. It receives anEventStore.RecordedEventand returns a partition key.
Ordering Guarantee with Partitioning
When using multiple subscribers, global ordering is lost. To maintain ordering for specific groups (e.g., ensuring all events for a single stream are processed in order), use partition_by to return a key like stream_uuid. This ensures all events for a specific stream go to the same subscriber, while different streams are processed concurrently by different subscribers.
alias EventStore.RecordedEvent
alias MyApp.EventStore
# Partition by stream_uuid to guarantee per-stream ordering with 10 concurrent subscribers
by_stream = fn %RecordedEvent{stream_uuid: stream_uuid} -> stream_uuid end
{:ok, _subscription} =
EventStore.subscribe_to_stream(stream_uuid, "example", self(),
concurrency_limit: 10,
partition_by: by_stream
)