Run locally
Ursula's HTTP server is the ursula binary. It reads a config file, an optional preset, and a small set of CLI overrides.
Default (in-process, non-replicated)
With no config file, the default preset runs an in-process non-replicated runtime (no Raft at all). Nothing is persisted. Best for state-machine smoke tests and first-impression testing:
cargo run --bin ursula -- --preset default
It binds 127.0.0.1:4437, picks a core count from your CPU, and uses the in-memory engine. --preset default selects the default preset but does not disable config-file discovery: from the repository root, cargo run --bin ursula -- --preset default still loads ./ursula.toml when present. For a true no-file smoke test, run from a directory with no Ursula config file or temporarily move/rename ./ursula.toml first.
In-memory Raft
OpenRaft with an in-memory log. Fast iteration, no persistence, but the runtime exercises the real Raft path:
[server]
listen = "127.0.0.1:4437"
[raft]
node_id = 1
group_count = 16
[raft.wal]
backend = "memory"
ursula --config ./ursula.toml
Disk-backed single node
Persistent local storage. Streams survive a restart:
[server]
listen = "127.0.0.1:4437"
[raft]
node_id = 1
group_count = 16
[raft.wal]
backend = "disk"
path = "./data"
ursula --config ./ursula.toml
The raft.wal.path directory will contain a raft-log/ subdirectory with protobuf-framed Raft log records per group plus a shared journal.bin per core. Removing the directory wipes state cleanly.
Smoke test
curl -X PUT http://127.0.0.1:4437/demo
curl -X PUT http://127.0.0.1:4437/demo/hello
curl -X POST http://127.0.0.1:4437/demo/hello \
-H 'Content-Type: application/octet-stream' \
--data-binary 'hello'
curl 'http://127.0.0.1:4437/demo/hello?offset=-1'
Inspect runtime metrics (placement, mailbox depth, per-core counters):
curl http://127.0.0.1:4437/__ursula/metrics | jq .
CLI overrides
| Flag | Default | Notes |
|---|---|---|
--config FILE | searches default config paths | TOML, JSON, or YAML config file |
--preset PRESET | default when no config file is found | default, dev, tiny, small, standard, or large |
--node-id ID | config file or preset | Overrides raft.node_id |
Common config keys
runtime.live_read_max_waiters_per_core(default65536) - SSE waiter cap per corestorage.cold.max_hot_size_per_group(default64MiB) - when a group's hot bytes exceed this cap, new writes are rejected with HTTP503storage.cold.backend,storage.cold.root,[storage.cold.s3], andstorage.cold.flush_*- cold-storage configuration. See configure S3observability.tokio_console- enables the Tokio console subscriber when the binary is built with the feature
Next
- Deploy a cluster - three-node static gRPC Raft
- Configure S3 - shared cold storage
- Operations - the EC2 helper and runtime introspection