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

FlagDefaultNotes
--config FILEsearches default config pathsTOML, JSON, or YAML config file
--preset PRESETdefault when no config file is founddefault, dev, tiny, small, standard, or large
--node-id IDconfig file or presetOverrides raft.node_id

Common config keys

  • runtime.live_read_max_waiters_per_core (default 65536) - SSE waiter cap per core
  • storage.cold.max_hot_size_per_group (default 64MiB) - when a group's hot bytes exceed this cap, new writes are rejected with HTTP 503
  • storage.cold.backend, storage.cold.root, [storage.cold.s3], and storage.cold.flush_* - cold-storage configuration. See configure S3
  • observability.tokio_console - enables the Tokio console subscriber when the binary is built with the feature

Next