Configuration Guide
View SourceThis guide covers all configuration options for erl-esdb, with examples for both Erlang (sys.config) and Elixir (config.exs).
Quick Start
Erlang (sys.config)
[
{erl_esdb, [
{stores, [
{my_store, [
{data_dir, "/var/lib/erl_esdb/my_store"},
{mode, single},
{timeout, 5000},
{writer_pool_size, 10},
{reader_pool_size, 10}
]}
]},
{telemetry_handlers, [logger]}
]}
].Elixir (config.exs)
config :erl_esdb,
stores: [
my_store: [
data_dir: "/var/lib/erl_esdb/my_store",
mode: :single,
timeout: 5_000,
writer_pool_size: 10,
reader_pool_size: 10
]
],
telemetry_handlers: [:logger]Configuration Reference
Store Configuration
Stores are the primary configuration. Each store is an independent event store instance backed by Khepri/Ra.
| Option | Type | Default | Description |
|---|---|---|---|
stores | proplist | [] | List of store configurations |
Each store in the list has:
| Option | Type | Default | Description |
|---|---|---|---|
data_dir | string | /var/lib/erl_esdb/{store_id} | Data directory for Khepri/Ra |
mode | atom | single | Operation mode: single or cluster |
timeout | integer | 5000 | Default timeout in milliseconds |
writer_pool_size | integer | 10 | Number of writer workers |
reader_pool_size | integer | 10 | Number of reader workers |
gateway_pool_size | integer | 1 | Number of gateway workers |
Erlang Example
{stores, [
{orders_store, [
{data_dir, "/bulk0/erl_esdb/orders"},
{mode, cluster},
{timeout, 10000},
{writer_pool_size, 20},
{reader_pool_size, 50}
]},
{users_store, [
{data_dir, "/bulk0/erl_esdb/users"},
{mode, single},
{writer_pool_size, 5},
{reader_pool_size, 10}
]}
]}Elixir Example
config :erl_esdb,
stores: [
orders_store: [
data_dir: "/bulk0/erl_esdb/orders",
mode: :cluster,
timeout: 10_000,
writer_pool_size: 20,
reader_pool_size: 50
],
users_store: [
data_dir: "/bulk0/erl_esdb/users",
mode: :single,
writer_pool_size: 5,
reader_pool_size: 10
]
]Pool Sizes (Global Defaults)
These set defaults for all stores that don't specify their own values.
| Option | Type | Default | Description |
|---|---|---|---|
writer_pool_size | integer | 10 | Default writer pool size |
reader_pool_size | integer | 10 | Default reader pool size |
gateway_pool_size | integer | 1 | Default gateway pool size |
Erlang Example
{writer_pool_size, 20},
{reader_pool_size, 50},
{gateway_pool_size, 2}Elixir Example
config :erl_esdb,
writer_pool_size: 20,
reader_pool_size: 50,
gateway_pool_size: 2Worker Timeouts
Idle timeout for reader and writer workers.
| Option | Type | Default | Description |
|---|---|---|---|
reader_idle_timeout_ms | integer | 60000 | Reader idle timeout (ms) |
writer_idle_timeout_ms | integer | 60000 | Writer idle timeout (ms) |
Erlang Example
{reader_idle_timeout_ms, 120000}, %% 2 minutes
{writer_idle_timeout_ms, 120000}Elixir Example
config :erl_esdb,
reader_idle_timeout_ms: 120_000,
writer_idle_timeout_ms: 120_000Health Probing
Health probing monitors store nodes and triggers failover in cluster mode.
| Option | Type | Default | Description |
|---|---|---|---|
health_probe_interval | integer | 5000 | Probe interval in milliseconds |
health_probe_timeout | integer | 2000 | Probe timeout in milliseconds |
health_failure_threshold | integer | 3 | Failures before marking unhealthy |
health_probe_type | atom | ping | Probe type: ping or deep |
Probe Types:
ping- Simple node reachability check (fast, low overhead)deep- Checks Khepri/Ra cluster health (thorough, higher overhead)
Erlang Example
{health_probe_interval, 10000},
{health_probe_timeout, 5000},
{health_failure_threshold, 5},
{health_probe_type, deep}Elixir Example
config :erl_esdb,
health_probe_interval: 10_000,
health_probe_timeout: 5_000,
health_failure_threshold: 5,
health_probe_type: :deepConsistency Checking
Periodic consistency verification for cluster mode.
| Option | Type | Default | Description |
|---|---|---|---|
consistency_check_interval | integer | 60000 | Check interval in milliseconds |
Erlang Example
{consistency_check_interval, 30000} %% 30 secondsElixir Example
config :erl_esdb,
consistency_check_interval: 30_000Persistence
Controls periodic snapshot persistence to disk.
| Option | Type | Default | Description |
|---|---|---|---|
persistence_interval | integer | 60000 | Persistence interval in milliseconds |
Erlang Example
{persistence_interval, 30000} %% 30 secondsElixir Example
config :erl_esdb,
persistence_interval: 30_000Telemetry
Configure telemetry handlers for metrics and logging.
| Option | Type | Default | Description |
|---|---|---|---|
telemetry_handlers | list | [logger] | List of telemetry handlers |
Available Handlers:
logger- Logs events via OTP logger
Erlang Example
{telemetry_handlers, [logger]}Elixir Example
config :erl_esdb,
telemetry_handlers: [:logger]Complete Configuration Examples
Single Node Development
%% Erlang sys.config
[
{erl_esdb, [
{stores, [
{dev_store, [
{data_dir, "/tmp/erl_esdb/dev"},
{mode, single}
]}
]},
%% Small pools for development
{writer_pool_size, 2},
{reader_pool_size, 5},
%% Fast feedback on issues
{health_probe_interval, 2000},
{health_failure_threshold, 1},
%% Frequent persistence for testing
{persistence_interval, 5000}
]}
].# Elixir config/dev.exs
config :erl_esdb,
stores: [
dev_store: [
data_dir: "/tmp/erl_esdb/dev",
mode: :single
]
],
writer_pool_size: 2,
reader_pool_size: 5,
health_probe_interval: 2_000,
health_failure_threshold: 1,
persistence_interval: 5_000Production Cluster
%% Erlang sys.config
[
{erl_esdb, [
{stores, [
{main_store, [
{data_dir, "/bulk0/erl_esdb/main"},
{mode, cluster},
{timeout, 10000},
{writer_pool_size, 50},
{reader_pool_size, 100},
{gateway_pool_size, 5}
]}
]},
%% Production health monitoring
{health_probe_interval, 5000},
{health_probe_timeout, 3000},
{health_failure_threshold, 3},
{health_probe_type, deep},
%% Consistency and persistence
{consistency_check_interval, 60000},
{persistence_interval, 30000},
%% Longer idle timeouts
{reader_idle_timeout_ms, 300000},
{writer_idle_timeout_ms, 300000}
]}
].# Elixir config/runtime.exs
config :erl_esdb,
stores: [
main_store: [
data_dir: "/bulk0/erl_esdb/main",
mode: :cluster,
timeout: 10_000,
writer_pool_size: 50,
reader_pool_size: 100,
gateway_pool_size: 5
]
],
# Production health monitoring
health_probe_interval: 5_000,
health_probe_timeout: 3_000,
health_failure_threshold: 3,
health_probe_type: :deep,
# Consistency and persistence
consistency_check_interval: 60_000,
persistence_interval: 30_000,
# Longer idle timeouts
reader_idle_timeout_ms: 300_000,
writer_idle_timeout_ms: 300_000Multi-Store Setup
# Elixir config.exs - Multiple stores for different domains
config :erl_esdb,
stores: [
# High-write orders store
orders_store: [
data_dir: "/bulk0/erl_esdb/orders",
mode: :cluster,
writer_pool_size: 100,
reader_pool_size: 50
],
# Read-heavy analytics store
analytics_store: [
data_dir: "/bulk1/erl_esdb/analytics",
mode: :single,
writer_pool_size: 5,
reader_pool_size: 200
],
# Low-volume user store
users_store: [
data_dir: "/bulk0/erl_esdb/users",
mode: :single,
writer_pool_size: 10,
reader_pool_size: 20
]
]Cluster Mode Configuration
When running in cluster mode, additional Erlang VM configuration is needed.
vm.args
## Node name (required for clustering)
-name store1@192.168.1.10
## Cookie for cluster authentication
-setcookie my_cluster_cookie
## Enable distribution
-proto_dist inet_tcp
## Increase distribution buffer
+zdbbl 32768Connecting Nodes
Cluster formation happens via Khepri/Ra. Use the API to join nodes:
%% On the joining node
erl_esdb:join_cluster(my_store, 'store1@192.168.1.10').# Elixir
:erl_esdb.join_cluster(:my_store, :"store1@192.168.1.10")Data Directory Guidelines
Linux/Production
Store data on separate disk partitions for performance:
{data_dir, "/bulk0/erl_esdb/my_store"}Development
Use temp directory for ephemeral data:
{data_dir, "/tmp/erl_esdb/dev_store"}Docker/Container
Mount a volume for persistence:
volumes:
- esdb_data:/var/lib/erl_esdb{data_dir, "/var/lib/erl_esdb/my_store"}Performance Tuning
High-Write Workloads
config :erl_esdb,
stores: [
high_write: [
writer_pool_size: 100, # Many concurrent writers
reader_pool_size: 20, # Fewer readers needed
mode: :cluster # Distribute writes
]
],
persistence_interval: 60_000 # Less frequent persistenceHigh-Read Workloads
config :erl_esdb,
stores: [
high_read: [
writer_pool_size: 10, # Fewer writers needed
reader_pool_size: 200, # Many concurrent readers
mode: :cluster # Read from any replica
]
],
reader_idle_timeout_ms: 600_000 # Keep readers alive longerLow-Latency Requirements
config :erl_esdb,
stores: [
low_latency: [
timeout: 2_000, # Fast timeouts
gateway_pool_size: 10 # More gateway workers
]
],
health_probe_interval: 1_000, # Fast failure detection
health_failure_threshold: 1 # Immediate failoverTelemetry Events
erl-esdb emits telemetry events for monitoring:
| Event | Measurements | Metadata |
|---|---|---|
[erl_esdb, append, start] | - | store_id, stream |
[erl_esdb, append, stop] | duration | store_id, stream, count |
[erl_esdb, append, exception] | duration | store_id, stream, reason |
[erl_esdb, read, start] | - | store_id, stream |
[erl_esdb, read, stop] | duration | store_id, stream, count |
[erl_esdb, read, exception] | duration | store_id, stream, reason |
[erl_esdb, health, probe] | latency | store_id, node, status |
[erl_esdb, health, change] | - | store_id, node, old, new |
Attaching Handlers
# Elixir
:telemetry.attach_many(
"erl-esdb-metrics",
[
[:erl_esdb, :append, :stop],
[:erl_esdb, :read, :stop],
[:erl_esdb, :health, :change]
],
&MyApp.Metrics.handle_event/4,
nil
)%% Erlang
telemetry:attach_many(
<<"erl-esdb-metrics">>,
[
[erl_esdb, append, stop],
[erl_esdb, read, stop],
[erl_esdb, health, change]
],
fun my_metrics:handle_event/4,
undefined
).See Also
- Storage Internals - How data is stored
- Cluster Consistency - Consistency guarantees
- Memory Pressure - Memory management
- Snapshots - Snapshot configuration