Packages
reckon_db
2.3.5
5.11.0
5.10.4
5.10.3
5.10.1
5.10.0
5.9.1
5.9.0
5.8.3
5.8.2
5.8.1
5.8.0
5.7.0
5.6.1
5.6.0
5.5.5
5.5.4
5.5.3
5.5.2
5.5.1
5.5.0
5.4.0
5.2.2
5.2.1
5.2.0
5.1.0
5.0.0
4.0.0
3.1.2
3.1.1
3.0.0
2.3.7
2.3.6
2.3.5
2.3.4
2.3.3
2.3.2
2.3.1
2.3.0
2.2.2
2.2.0
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.0
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.3
1.0.2
1.0.1
1.0.0
BEAM-native Event Store built on Khepri/Ra with Raft consensus. Event sourcing, persistent subscriptions, snapshots, and automatic cluster formation via UDP multicast discovery. Ships embedded Rust NIFs for 3-15x acceleration of crypto, hashing, compression, aggregation, filter matching, and grap...
Current section
Files
Jump to
Current section
Files
guides/configuration.md
# Configuration Guide
This guide covers all configuration options for reckon-db, with examples for both Erlang (sys.config) and Elixir (config.exs).
## Quick Start
### Erlang (sys.config)
```erlang
[
{reckon_db, [
{stores, [
{my_store, [
{data_dir, "/var/lib/reckon_db/my_store"},
{mode, single},
{timeout, 5000},
{writer_pool_size, 10},
{reader_pool_size, 10}
]}
]},
{telemetry_handlers, [logger]}
]}
].
```
### Elixir (config.exs)
```elixir
config :reckon_db,
stores: [
my_store: [
data_dir: "/var/lib/reckon_db/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/reckon_db/{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
```erlang
{stores, [
{orders_store, [
{data_dir, "/bulk0/reckon_db/orders"},
{mode, cluster},
{timeout, 10000},
{writer_pool_size, 20},
{reader_pool_size, 50}
]},
{users_store, [
{data_dir, "/bulk0/reckon_db/users"},
{mode, single},
{writer_pool_size, 5},
{reader_pool_size, 10}
]}
]}
```
#### Elixir Example
```elixir
config :reckon_db,
stores: [
orders_store: [
data_dir: "/bulk0/reckon_db/orders",
mode: :cluster,
timeout: 10_000,
writer_pool_size: 20,
reader_pool_size: 50
],
users_store: [
data_dir: "/bulk0/reckon_db/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
```erlang
{writer_pool_size, 20},
{reader_pool_size, 50},
{gateway_pool_size, 2}
```
#### Elixir Example
```elixir
config :reckon_db,
writer_pool_size: 20,
reader_pool_size: 50,
gateway_pool_size: 2
```
### Worker 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
```erlang
{reader_idle_timeout_ms, 120000}, %% 2 minutes
{writer_idle_timeout_ms, 120000}
```
#### Elixir Example
```elixir
config :reckon_db,
reader_idle_timeout_ms: 120_000,
writer_idle_timeout_ms: 120_000
```
### Health 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
```erlang
{health_probe_interval, 10000},
{health_probe_timeout, 5000},
{health_failure_threshold, 5},
{health_probe_type, deep}
```
#### Elixir Example
```elixir
config :reckon_db,
health_probe_interval: 10_000,
health_probe_timeout: 5_000,
health_failure_threshold: 5,
health_probe_type: :deep
```
### Consistency Checking
Periodic consistency verification for cluster mode.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `consistency_check_interval` | integer | 60000 | Check interval in milliseconds |
#### Erlang Example
```erlang
{consistency_check_interval, 30000} %% 30 seconds
```
#### Elixir Example
```elixir
config :reckon_db,
consistency_check_interval: 30_000
```
### Persistence
Controls periodic snapshot persistence to disk.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `persistence_interval` | integer | 60000 | Persistence interval in milliseconds |
#### Erlang Example
```erlang
{persistence_interval, 30000} %% 30 seconds
```
#### Elixir Example
```elixir
config :reckon_db,
persistence_interval: 30_000
```
### Telemetry
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
```erlang
{telemetry_handlers, [logger]}
```
#### Elixir Example
```elixir
config :reckon_db,
telemetry_handlers: [:logger]
```
## Complete Configuration Examples
### Single Node Development
```erlang
%% Erlang sys.config
[
{reckon_db, [
{stores, [
{dev_store, [
{data_dir, "/tmp/reckon_db/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
# Elixir config/dev.exs
config :reckon_db,
stores: [
dev_store: [
data_dir: "/tmp/reckon_db/dev",
mode: :single
]
],
writer_pool_size: 2,
reader_pool_size: 5,
health_probe_interval: 2_000,
health_failure_threshold: 1,
persistence_interval: 5_000
```
### Production Cluster
```erlang
%% Erlang sys.config
[
{reckon_db, [
{stores, [
{main_store, [
{data_dir, "/bulk0/reckon_db/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
# Elixir config/runtime.exs
config :reckon_db,
stores: [
main_store: [
data_dir: "/bulk0/reckon_db/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_000
```
### Multi-Store Setup
```elixir
# Elixir config.exs - Multiple stores for different domains
config :reckon_db,
stores: [
# High-write orders store
orders_store: [
data_dir: "/bulk0/reckon_db/orders",
mode: :cluster,
writer_pool_size: 100,
reader_pool_size: 50
],
# Read-heavy analytics store
analytics_store: [
data_dir: "/bulk1/reckon_db/analytics",
mode: :single,
writer_pool_size: 5,
reader_pool_size: 200
],
# Low-volume user store
users_store: [
data_dir: "/bulk0/reckon_db/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 32768
```
### Connecting Nodes
Cluster formation happens via Khepri/Ra. Use the API to join nodes:
```erlang
%% On the joining node
reckon_db:join_cluster(my_store, 'store1@192.168.1.10').
```
```elixir
# Elixir
:reckon_db.join_cluster(:my_store, :"store1@192.168.1.10")
```
## Data Directory Guidelines
### Linux/Production
Store data on separate disk partitions for performance:
```erlang
{data_dir, "/bulk0/reckon_db/my_store"}
```
### Development
Use temp directory for ephemeral data:
```erlang
{data_dir, "/tmp/reckon_db/dev_store"}
```
### Docker/Container
Mount a volume for persistence:
```yaml
volumes:
- esdb_data:/var/lib/reckon_db
```
```erlang
{data_dir, "/var/lib/reckon_db/my_store"}
```
## Performance Tuning
### High-Write Workloads
```elixir
config :reckon_db,
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 persistence
```
### High-Read Workloads
```elixir
config :reckon_db,
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 longer
```
### Low-Latency Requirements
```elixir
config :reckon_db,
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 failover
```
## Telemetry Events
reckon-db emits telemetry events for monitoring:
| Event | Measurements | Metadata |
|-------|--------------|----------|
| `[reckon_db, append, start]` | - | store_id, stream |
| `[reckon_db, append, stop]` | duration | store_id, stream, count |
| `[reckon_db, append, exception]` | duration | store_id, stream, reason |
| `[reckon_db, read, start]` | - | store_id, stream |
| `[reckon_db, read, stop]` | duration | store_id, stream, count |
| `[reckon_db, read, exception]` | duration | store_id, stream, reason |
| `[reckon_db, health, probe]` | latency | store_id, node, status |
| `[reckon_db, health, change]` | - | store_id, node, old, new |
### Attaching Handlers
```elixir
# Elixir
:telemetry.attach_many(
"reckon-db-metrics",
[
[:reckon_db, :append, :stop],
[:reckon_db, :read, :stop],
[:reckon_db, :health, :change]
],
&MyApp.Metrics.handle_event/4,
nil
)
```
```erlang
%% Erlang
telemetry:attach_many(
<<"reckon-db-metrics">>,
[
[reckon_db, append, stop],
[reckon_db, read, stop],
[reckon_db, health, change]
],
fun my_metrics:handle_event/4,
undefined
).
```
## See Also
- [Storage Internals](storage_internals.md) - How data is stored
- [Cluster Consistency](cluster_consistency.md) - Consistency guarantees
- [Memory Pressure](memory_pressure.md) - Memory management
- [Snapshots](snapshots.md) - Snapshot configuration