Self-host an event log for AI agent reasoning steps with live SSE tails
Run a three-node Ursula cluster on EC2 and offload cold chunks to S3
Store every keystroke of a collaborative editor in a per-document stream
Replay long-running workflow state from any offset for debugging
Single binary boots in-memory on localhost, but a real deployment needs a 3 or 5 node cluster with S3 access and Raft quorum tuning.
Ursula is an open-source server, written in Rust, for storing append-only event streams and serving them over plain HTTP. An event stream here means a continuous log of small records, the kind of thing produced when a document editor wants to keep every keystroke, an AI agent wants to keep every step of its reasoning, or a long-running workflow wants to keep every state change. Apps can write new events to the end of a stream and others can read the stream back from any point, including tailing it live as new events arrive. The pitch in the README is that there are already protocols for this shape of data, specifically the Durable Streams Protocol developed by ElectricSQL, but most existing servers force a tradeoff. Either you cannot self-host them, write latency is slow because they batch, they need expensive S3 Express storage, or a single node failure loses data. Ursula tries to keep all four properties: self-hostable, sub-50 ms writes, plain S3 as the cold storage tier, and quorum replication so an acknowledged write survives losing one node. A typical deployment is three or five Ursula processes acting as one cluster. Each stream hashes to one Raft group, and one CPU core per node owns that group, so cores work on different streams without sharing mutable state on the hot path. Writes go into an in-memory ring and a Raft log, get acknowledged once a majority of the replicas persist them, and a background flusher later writes older chunks out to S3. The HTTP layer is built with axum and is stateless. To try it, you build from Rust source with cargo run and the binary listens on 127.0.0.1:4437 in an in-memory mode. The HTTP API is bucket-and-stream shaped: PUT /demo creates a bucket, PUT /demo/hello creates a stream, POST appends bytes, GET reads from an offset, and adding live=sse turns the request into a live tail. On three c7g.4xlarge EC2 machines the README reports about 35,200 appends per second across 500 streams and SSE fan-out to 1000 subscribers at 6.1 ms at the 99th percentile. The 0.1 series is a working prototype. Planned next are conditional appends with an if-match header for optimistic concurrency, a WASM compute extension that lets server-side modules summarise stream state, online membership changes, backup and restore tooling, and Rust and TypeScript client libraries. License is Apache 2.0, built by a team called Tonbo.
Generated 2026-05-22 · Model: sonnet-4-6 · Verify against the repo before relying on details.