Skip to content

Architecture Overview

Calimero's architecture consists of four main layers that work together to enable distributed, peer-to-peer applications with automatic conflict-free synchronization.

Four-Layer Architecture

flowchart LR
    APP[Application<br/>WASM apps & SDK] --> NODE[Node<br/>Sync & execution]
    NODE --> STORAGE[Storage<br/>CRDT & DAG]
    STORAGE --> NETWORK[Network<br/>P2P & APIs]
    NETWORK -.-> NODE

    style APP fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NODE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style STORAGE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NETWORK fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff

Transaction Flow

Transaction Flow:

flowchart LR
    CLIENT[Client<br/>RPC call] --> NODE[Node<br/>Execute]
    NODE --> WASM[WASM<br/>Process]
    WASM --> STORAGE[Storage<br/>CRDT ops]
    STORAGE --> NODE
    NODE --> NETWORK[Network<br/>Broadcast]
    NETWORK --> PEER[Peer<br/>~100ms]
    NODE --> CLIENT

    style CLIENT fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NODE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style WASM fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style STORAGE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NETWORK fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style PEER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff

See core/crates/runtime/README.md for execution details.

Synchronization Flow

Calimero uses a dual-path synchronization strategy:

Path 1: Gossipsub Broadcast (Primary)

Fast real-time propagation (~100-200ms):

flowchart LR
    TXN[Execute] --> DELTA[Create Delta]
    DELTA --> GOSSIP[Gossipsub]
    GOSSIP --> RECEIVE[Peers receive]
    RECEIVE --> READY{Ready?}
    READY -->|Yes| APPLY[Apply]
    READY -->|No| BUFFER[Buffer]
    APPLY --> EVENTS[Events]

    style TXN fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style DELTA fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style GOSSIP fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style RECEIVE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style READY fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style APPLY fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff
    style EVENTS fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style BUFFER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff

Path 2: Periodic P2P Sync (Fallback)

Catch-up every 10-30 seconds:

flowchart LR
    TIMER[Timer] --> PEER[Select Peer]
    PEER --> STREAM[Open Stream]
    STREAM --> HEADS[Exchange Heads]
    HEADS --> DIFF{Differ?}
    DIFF -->|Yes| REQUEST[Request Deltas]
    DIFF -->|No| SYNC[Synced]
    REQUEST --> APPLY2[Apply]
    APPLY2 --> SYNC

    style TIMER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style PEER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style STREAM fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style HEADS fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style DIFF fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style REQUEST fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style APPLY2 fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style SYNC fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff

Why both paths? - Gossipsub: Fast (~100-200ms), reliable in good network conditions - Periodic sync: Ensures eventual consistency even with packet loss, partitions, or downtime

See core/crates/node/README.md for sync configuration details.

DAG-Based Causal Ordering

The DAG ensures deltas are applied in correct causal order:

flowchart LR
    ROOT[Root] --> A[Delta A]
    ROOT --> B[Delta B]
    A --> MERGE[Merge]
    B --> MERGE

    style ROOT fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff
    style A fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style B fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style MERGE fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff

Key properties: - Deltas can arrive in any order - System buffers deltas until their parent dependencies are ready - Once parents are available, deltas are applied automatically in causal order - Concurrent updates create forks that merge automatically

Key Components

flowchart LR
    SERVER[Server] --> NODE[Node]
    NODE --> RUNTIME[Runtime]
    NODE --> NETWORK[Network]
    SDK[SDK] --> RUNTIME
    RUNTIME --> STORAGE[Storage]
    STORAGE --> DAG[DAG]

    style SDK fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style RUNTIME fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style STORAGE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style DAG fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NODE fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff
    style NETWORK fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style SERVER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
Component Purpose Repository
SDK #[app::state], #[app::logic], CRDT collections, events core/crates/sdk
Runtime WASM execution (Wasmer), sandboxing core/crates/runtime
Storage CRDT collections, merge semantics core/crates/storage
DAG Causal delta tracking, dependency resolution core/crates/dag
Node NodeManager orchestrates sync, events, blobs core/crates/node
Network libp2p P2P (Gossipsub, streams, DHT) core/crates/network
Server JSON-RPC API, WebSocket/SSE core/crates/server
merod Node binary (coordinator/peer) core/crates/merod
meroctl CLI for node operations core/crates/meroctl

See core/README.md for complete architecture.

Component Details

For detailed information on each component, see their README files:

Deep Dives

For detailed architecture information:


Next: Learn about specific concepts: Contexts | Identity | Applications | Nodes