Comparisons
How Ursula relates to other stream and storage systems for application-facing timelines.
Ursula occupies a specific niche: distributed Durable Streams over HTTP, with one timeline per application resource. This page is a longer narrative on how that niche differs from the systems Ursula gets compared to. For an at-a-glance positioning table, see the project README.
Object storage
S3 and its peers are excellent for durable immutable blobs and static reads. They are awkward as an append interface: every append is a new object, conditional writes are optimistic and degrade into retry storms under contention, and live readers must poll. Putting per-resource append-only logs directly on S3 surfaces these tradeoffs to every writer and reader.
Ursula uses S3, but for the cold tier and snapshots, not the write path. Appends commit at Raft quorum in the hot tier and the background flush carries data to S3 once it's no longer hot. The hot-to-cold boundary is invisible to clients; the same GET works for in-memory and S3-resident data.
Durable Streams reference server (Electric)
The upstream reference server implements the same protocol Ursula does. It is designed to be easy to embed and run as a single process, which makes it a good starting point for small deployments and local development. The tradeoff is that high availability requires building or sourcing another layer.
Ursula provides that layer natively (leader election, quorum replication, follower reads, snapshot-based recovery), at the cost of running a multi-node cluster. Both speak the same protocol, so client code is unchanged.
S2 / S2 Lite
S2 is an object-storage-backed stream API with strong acknowledged-write durability, achieved by writing through S3 Express One Zone on the hot path. Its self-hosted shape (S2 Lite) is a single serving process; the managed product uses its own API surface.
Ursula and S2 overlap on "durable append-only stream" but differ on:
- Protocol surface. Ursula speaks Durable Streams HTTP; S2 has its own API.
- Write path. Ursula commits at Raft quorum in a replicated hot tier with no S3 in the hot path; S2 commits via S3 Express.
- Cost model. Ursula uses S3 Standard for the cold tier; S2's hot path uses S3 Express, which is roughly 7× the per-GB cost of Standard.
- Operational shape. Ursula requires running a Raft cluster; S2 Lite is single-process self-hosted.
Kafka / Redpanda
Kafka, Redpanda, and similar systems target high-throughput event pipelines: topics with many partitions, consumer groups, and processing semantics. They are excellent for that workload.
Ursula deliberately does not try to be that. The primitive is one independently-addressable durable stream per application resource (documents, sessions, agent runs), not pipelines of records. The operational and API surfaces are correspondingly smaller, and the consumer model is "any HTTP client" rather than partition-aware consumer groups.
When to pick which
Reach for Ursula when:
- The natural data model is a large number of small, independent timelines, one per resource
- Clients are diverse and HTTP is the common denominator (browsers, agents, scripts)
- Replayable recovery, live tailing, and snapshots all need to work without bolting on separate infrastructure
Reach for something else when:
- The model is a small number of high-throughput topics with consumer groups → Kafka / Redpanda
- The deployment must stay single-process → the Durable Streams reference server
- You want managed and accept a different API → S2
- You need only durable immutable blobs with no append or tail semantics → object storage directly