Distributed KV paradigm

Events Converge.
Inevitably.

Aevrion is a paradigm for distributed data: every mutation is an immutable event on a temporal axis. No coordination. No leader. No consensus. Convergence is inevitable.

AEVRION EVENTimmutable · content-addressable
{ key: "user:123",
  value: { name: "Alice", role: "admin" },
  timestamp: 1_710_684_600_042, // monotonic (ms)

  id: blake3(key ‖ value ‖ timestamp) // derived
}
3
Fields define identity
1
Hash — the ID
5
Tree levels cover 60 years
160
Hashes to diff all history
// The problem

Why Aevrion Exists

Distributed data diverges. Two nodes write the same key. Network partitions. Clocks drift. The fundamental challenge: how do independent nodes arrive at the same state without coordination?

Traditional approaches demand a leader, a quorum, a consensus protocol. They trade availability for consistency, add latency, create single points of failure. What if convergence didn't require any of that?

The idea

Time is the only coordinate you need.

If every mutation is an immutable event with a monotonic timestamp, and events are organized in a tree indexed by time, then any two nodes can deterministically compute the same state from the same set of events. No negotiation. No voting. The math guarantees it.

Aevrion is built on one primitive: the Event. Three fields determine identity. One hash makes it content-addressable. Everything else — storage, indexing, sync, conflict resolution — is derived.

// The atom

Everything Is an Event

The smallest unit of truth. Immutable. Content-addressable. Verifiable.

Three fields define identity: key, value, timestamp. The ID is blake3(key ‖ value ‖ timestamp) — a hash of the content. Same content on different nodes = same ID. No coordination needed.

Content-addressable means deduplication is free. Event already exists? Skip it. Verification is instant — recompute the hash, compare with the ID. Tampered? Hash won't match.

Deletion is an event, not a special case. An event with value: None means "this key is deleted as of this timestamp". The event persists — the delete is a fact in history, not an erasure.

What it is not
Not a log entry. Events are not ordered by a central sequencer. Each node assigns its own monotonic timestamp. Order emerges from time, not from sequence numbers.
Not a CRDT operation. Events don't carry merge semantics. Conflict resolution (LWW) happens at the index layer, not in the event itself. Events are pure data.
Not tied to a node. No node_id in the event. Two nodes that independently write the same key, value, and timestamp produce the same event, the same ID. Origin is metadata, not identity.
// Lifecycle

One Write. Four Structures.

Every put() creates an event that ripples through the entire system.

Client calls put("user:123", { name: "Alice" })
Create Eventkey + value + ts
#Compute IDblake3(…)
Event Storeid → event
Tree Leafleaf[ts/G].add(id)
Merge Index(key, ts) → id
Push→ neighbors
The event's 32-byte ID flows through every step: id = 0xa3f7… written once, referenced everywhere
Event data is stored exactly once in Event Store. Tree leaf, Merge Index, and Sync Agent all reference it by ID. No duplication. Hashes are not recomputed on write — they're batched when the leaf closes (every G).
// Architecture

Four Components. One Truth.

Event is written once. Everything else is a reference by ID.

Foundation

Event Store

Flat content-addressable storage. id → Event. The only place where event data lives. Put, get, has. That's it.

Every other structure references events by their 32-byte ID. One event, one copy, many references.
Temporal axis

Merkle Tree

Organizes events by time. Leaves store lists of IDs, not events. Hash of a leaf = blake3(sorted(event_ids)). Enables O(log N) diff between any two nodes.

Two parameters: G (granularity) and B (branching factor). Everything else is derived. 5 levels cover 60 years.
Key → Value bridge

Merge Index

The only component clients see. Maps key → latest event. Full history per key. Point-in-time queries. Scan, prefix search.

Fully derived — rebuilt from Event Store + Tree at any time. Append-only on write path. LWW conflict resolution.
Connectivity

Sync Agent

Channel + handler + triggers per neighbor. One function: handle(msg). Seven message types. Repair emerges as a chain reaction.

Push for latency (optimistic). Verify/repair for consistency (pessimistic). Both use the same handler.
// Merge Index

The Bridge: Time ↔ Key

Tree is organized by time. Client asks by key. Merge Index connects both worlds.

Temporal axis (events by time)
ts: 100 user:123 = "Bob" id: 0xaa…
ts: 200 config:theme = "dark" id: 0xbb…
ts: 300 user:123 = "Alice" id: 0xcc…
ts: 400 user:456 = "Dave" id: 0xdd…
merge index
Key axis (client view)
user:123 "Alice" ← latest
user:123 "Bob" ts:100
config:theme "dark"
user:456 "Dave"
get(key)

Latest version of any key. O(log N).

get_history(key)

Full version history. Every mutation, in order.

point_in_time(key, T)

Value of key at any moment in the past.

// Temporal Merkle Tree

Two Numbers. The Whole Tree.

Granularity G sets the leaf size. Branching factor B sets how many children per node. Everything else is derived.

level 4~1.9 years
27
level 3~22 days
864
865
870
895
level 2~17 hours
27840
27862
27871
level 1~32 min
891584
891606
891615
leaves1 min
…408
…409
…410
G = 60s
Granularity — leaf covers 1 minute
leaf_id = timestamp / G
B = 32
Branching — each node has 32 children
level_N = leaf_id / Bᴺ
5 levels
G → G×B → G×B² → G×B³ → G×B⁴
1 min → 32 min → 17 hrs → 22 days → 1.9 yrs
// Progressive Digest

Closer = More Detail

One snapshot covers all history. Recent data with minute precision. Old data in month-wide blocks.

NOW
leaves1 min each
level 1~32 min each
level 2~17 hrs each
level 3~22 days each
level 4~1.9 yrs each
match
divergence
current (open)
future

Like a Map

Streets nearby, districts further away, cities on the horizon. One snapshot gives a complete divergence map — recent data with minute-level precision, historical data in broad strokes. O(B × levels) hashes.

Zero Wasted Work

Matching blocks are skipped entirely. A green level 3 block means 22 days verified with a single hash comparison. Only diverged branches are explored deeper. Convergence cost is proportional to actual drift, not total history.

// Convergence

How Nodes Converge

Snapshot → diff → repair. Chain reaction. No coordinator.

0

Push (optimistic)

Local write → event is immediately sent to every neighbor. Best-effort, instant delivery. If it arrives — great. If not — verify will catch it.

1

Snapshot (periodic)

Every G, each node sends a tree snapshot to neighbors — hashes at every level, from fresh leaves to root. The closer to now, the more detail. Like a map: streets nearby, districts further, cities on the horizon.

≤160 hashes · ~6.5 KB · one round-trip
2

Compare

Receiver compares each hash with their own. Match = entire subtree verified. Mismatch at leaf = divergence pinpointed to the minute. Mismatch at level 3 = divergence somewhere in 22 days — drill down.

3

Repair (chain reaction)

Mismatch on leaf → EventListNeedEvents → events flow. Not a mode — a chain reaction of handle() calls. Both sides repair simultaneously. Matching subtrees are never touched.

4

Converged

All hashes match. Same events, same tree, same merge index state. Every node arrived here independently, following the same deterministic rules. No vote. No leader. Just time and math.

LWW: higher timestamp wins · tie: higher event_id wins
// Entropy

The Real Problem Is Entropy

Distributed systems don't fail. They diverge. The question is how you detect and repair it.

Every distributed system faces the same fundamental challenge: nodes drift apart. Network partitions, delayed writes, clock skew, crashed replicas — entropy is not a bug, it's physics. The difference between systems is how they manage it.

Most systems treat anti-entropy as an operational burden — a maintenance task you schedule, monitor, and pray completes before the next one starts. Aevrion treats it as a built-in primitive — continuous, automatic, and proportional to actual drift.

R/P
Strong consistency

Consensus (Raft, Paxos, ZAB)

Prevent divergence entirely by coordinating every write through an elected leader. Used in etcd, CockroachDB, TiKV, ZooKeeper.

Entropy strategy
Prevent at all costs

Every write requires quorum acknowledgment before it's considered committed. Divergence is structurally impossible — but at the cost of availability and latency.

Write path
Leader → quorum → ack

All writes are serialized through a single leader. The leader replicates to a majority before confirming. Leader failure triggers election — writes stall for seconds.

Partition behavior
Minority cannot write

CAP theorem in action: the minority partition is read-only (or unavailable). Network split = degraded service. Cross-datacenter deployments pay the latency tax on every write.

Operational cost
Moderate

No anti-entropy repairs needed (consistency is built-in), but leader elections, log compaction, and snapshot management require monitoring and tuning.

Trade-off: zero entropy, but writes are slow, partitions are painful, and a single leader is a structural bottleneck.
C*
Eventual consistency + manual repair

Cassandra (Anti-Entropy Repair)

Allow divergence during normal operation, fix it later with scheduled Merkle tree comparisons. The most widely deployed anti-entropy mechanism.

Entropy detection
Scheduled, batch, full-scan

Merkle trees are built on-demand during repair. Not maintained continuously — rebuilt from scratch on each nodetool repair invocation. Expensive.

Repair cost
All-or-nothing, O(total data)

Full repair scans every token range regardless of actual drift. Subrange repair exists but requires manual partitioning. Incremental repair adds flags, state, and its own failure modes.

Operational burden
A specialty in itself

Miss a repair cycle → tombstones resurrect deleted data. gc_grace_seconds is a ticking clock. Repair timeouts, vnodes, compaction interaction — each a source of incidents.

Resource impact
Competes with production

Repair is I/O and network intensive. Running it during peak hours degrades read/write latency. Not running it risks silent inconsistency. Lose-lose scheduling problem.

Trade-off: available writes, but entropy management is a manual, expensive, error-prone operational discipline.
Conflict-free replicated data types

CRDTs (Riak, Automerge, Yjs)

Encode merge semantics into the data type. Concurrent writes are automatically resolved by mathematical properties of the type (commutativity, associativity, idempotence).

Entropy strategy
Make divergence safe

Instead of detecting and repairing divergence, CRDTs ensure that any merge order produces the same result. Elegant in theory — constrained in practice.

Data model constraints
Limited to specific types

G-Counters, PN-Counters, OR-Sets, LWW-Registers. Arbitrary KV with full history, point-in-time queries, and prefix scan doesn't map naturally to CRDT semantics.

Metadata growth
O(nodes × keys) overhead

Version vectors, causal dots, tombstone sets grow with cluster size. Each key carries per-node metadata. At scale, metadata can exceed payload size.

Correctness complexity
Hard to get right

Custom merge functions require formal proofs of convergence. Edge cases in concurrent delete+add, move operations, and nested types are a research-level problem.

Trade-off: automatic merge, but limited data models, growing metadata, and correctness that's hard to verify.
Continuous temporal anti-entropy

Aevrion

Entropy is not prevented or tolerated — it's continuously measured and repaired. The temporal Merkle tree is always maintained, the progressive digest is always exchanged, convergence is always in progress.

Entropy detection
Continuous, progressive, proportional

Every G, nodes exchange a progressive digest — ~160 hashes covering all history. Recent data at minute precision, old data in month-wide blocks. Divergence is detected within one cycle.

Repair cost
O(actual drift), not O(total data)

Matching subtrees are skipped entirely. One hash comparison verifies 22 days of data. Repair touches only diverged branches. Week-long partition? Only the week's events are synced.

Operational burden
Zero

No nodetool repair. No gc_grace_seconds. No scheduled maintenance windows. Anti-entropy is a heartbeat, not a job. If the node is running, it's converging.

Conflict model
LWW — deterministic, stateless

Last-Write-Wins by timestamp, tiebreaker by event ID. No version vectors, no merge functions, no causal context. Events are pure data. Any node resolves the same conflict the same way.

No trade-off. Available writes + continuous convergence + zero operational cost + simple conflict model. Entropy is managed by the architecture, not by the operator.

Cassandra asks: "did you remember to run repair?"
Raft asks: "who is the leader right now?"
Aevrion doesn't ask. Repair is always running.

// Invariants

Guarantees

Append-Only

Events are never modified or deleted. History is a fact. Every derived structure can be rebuilt from the event log.

Temporal Axis

Time is the single organizing dimension. One integer division gives the path from root to leaf. Zero coordination.

Content-Addressable

ID = hash of content. Same event on any node has the same ID. Deduplication, verification, and routing — all free.

Autonomous Nodes

Every node works independently. Reads and writes never block on the network. Sync is a background process.

Full History

Merge Index keeps every version of every key. Point-in-time queries, audit trail, and rollback — by design, not as an afterthought.

Eventual Convergence

Push is optimistic. Verify is pessimistic. Together they guarantee that all connected nodes reach the same state. Always.

// The name

What Is Aevrion

aevum + -ion — a particle of eternity.

Aevum (Latin) — eternity, the continuous flow of time. The root behind aeon, ever, age. An append-only log means data is written for eternity. A Temporal Merkle Tree means time is the organizing axis. Point-in-time queries mean access to any moment that ever was.

-ion (Greek suffix) — a particle, the smallest indivisible unit. Like photon, electron, graviton — fundamental quanta that carry a force. An event is the quantum of change: the smallest, indivisible unit of mutation that carries truth across the system.

Aevrion is a quantum of eternity — an immutable particle of data that travels through time and inevitably reaches every node.

Time is on your side.

Explore the concepts, read the architecture, or start building.