Architecting for Six 9s: How PayPal's JunoDB Achieves High Availability

Arpit Bhayani

Arpit Bhayani

May 25, 2023 • 7 min read

Play

In financial platforms like PayPal, downtime and data loss directly translate to revenue loss, regulatory breaches, and eroded customer trust. While high-traffic consumer applications might tolerate transient read errors or eventual consistency delays, mission-critical payment infrastructure demands near-absolute uptime—often targeted at six nines (99.9999%) of availability (less than 31.5 seconds of downtime per year).

To satisfy these strict SLAs, PayPal open-sourced JunoDB, their internal distributed key-value database designed specifically for zero data loss and extreme fault tolerance. Achieving six nines requires systematically eliminating single points of failure through multi-layered redundancy across compute, storage, availability zones, and geographical regions.


The Rule of Thumb: Redundancy Across the Stack

High availability in distributed systems fundamentally reduces to redundancy across compute and storage:

  1. Load Balancers: Stateless front doors running in redundant clusters with automatic failover.
  2. Juno Proxy (Compute Tier): A horizontally scalable, completely stateless proxy tier. Because all proxies are uniform and hold no state, the failure of any single proxy has zero impact on operational integrity; traffic is instantly routed to peer proxies.
  3. Storage Tier: The hardest component to make resilient. Compute can be killed and restarted instantly, but storage nodes maintain state that cannot be lost or corrupted.

JunoDB solves storage tier resilience through a structured 2D grid-based storage model paired with synchronous quorum-based replication.


The 2D Storage Grid Architecture

Instead of treating storage nodes as an unstructured pool or a standard hash ring, JunoDB logically arranges storage servers into a two-dimensional grid:

  • Rows = Storage Groups (SG): Logical groupings of storage servers that collectively own and replicate a dedicated subset of shards.
  • Columns = Failure Domains (Zones): Independent fault domains such as distinct physical server racks, power boundaries, or Cloud Availability Zones (AZs).
+----------------+------------+------------+------------+------------+------------+
|                |   Zone 1   |   Zone 2   |   Zone 3   |   Zone 4   |   Zone 5   |
+----------------+------------+------------+------------+------------+------------+
| Storage Group 1|  Server A1 |  Server A2 |  Server A3 |  Server A4 |  Server A5 |
| Storage Group 2|  Server B1 |  Server B2 |  Server B3 |  Server B4 |  Server B5 |
| Storage Group 3|  Server C1 |  Server C2 |  Server C3 |  Server C4 |  Server C5 |
+----------------+------------+------------+------------+------------+------------+

Shard Distribution Across the Grid

Data is partitioned into a fixed number of shards (e.g., 1024). Each shard is assigned to exactly one Storage Group.

Within that Storage Group, the shard’s data is replicated synchronously across all storage servers in that row. If Shard 10 is mapped to Storage Group 3, every server in that row (C1, C2, C3, C4, C5) maintains an exact, synchronized replica of Shard 10.

Because each column belongs to an isolated physical zone (power, networking, rack), a catastrophic rack failure in Zone 2 only knocks out one replica per Storage Group, leaving the remaining four replicas entirely functional.


Quorum-Based Reads and Writes

To route traffic to the grid, Juno Proxy utilizes deterministic hash-based partitioning followed by synchronous quorum operations.

sequenceDiagram
    autonumber
    participant Client
    participant JunoProxy as Juno Proxy
    participant S1 as Storage Node (Zone 1)
    participant S2 as Storage Node (Zone 2)
    participant S3 as Storage Node (Zone 3)
    participant S4 as Storage Node (Zone 4)
    participant S5 as Storage Node (Zone 5)

    Client->>JunoProxy: Write(Key, Value)
    Note over JunoProxy: Compute MurmurHash(Key) % NumShards<br/>Identify Target Storage Group
    
    par Parallel Synchronous Write
        JunoProxy->>S1: Write Request
        JunoProxy->>S2: Write Request
        JunoProxy->>S3: Write Request
        JunoProxy->>S4: Write Request
        JunoProxy->>S5: Write Request
    end

    S1-->>JunoProxy: ACK
    S2-->>JunoProxy: ACK
    S3-->>JunoProxy: ACK
    Note over JunoProxy: Write Quorum Reached (3 of 5 ACKs)
    JunoProxy-->>Client: Write Success
    
    S4-->>JunoProxy: ACK (Late)
    S5-->>JunoProxy: ACK (Late)

1. Partition Resolution

When a client submits an operation for key K1:

  1. Juno Proxy passes K1 through MurmurHash.
  2. It computes ShardID = MurmurHash(K1) % TotalShards.
  3. The proxy looks up the shard-to-group mapping to determine which Storage Group owns ShardID.

2. Synchronous Write Quorum (WW)

Once the target Storage Group is identified:

  • In a production cluster configured with N=5N = 5 zones, the proxy issues parallel write requests to all 5 storage nodes in that group.
  • The proxy waits for acknowledgments from a majority quorum (W=3W = 3 out of 5 nodes).
  • Once 3 nodes acknowledge the write, the proxy responds to the client with success.
  • Slow or temporarily unreachable nodes catch up out-of-band.

3. Synchronous Read Quorum (RR)

When reading key K1:

  • The proxy routes the request to all 5 nodes in the owning Storage Group.
  • It waits for responses from a majority quorum (R=3R = 3).
  • The proxy inspects the version metadata, resolves any potential divergence by picking the latest version, and returns it to the client.

Mathematical Consistency Guarantee

By enforcing the classical quorum intersection rule:

R+W>NR + W > N

(3+3>5)(3 + 3 > 5)

The Pigeonhole Principle guarantees that any read quorum of size 3 and any write quorum of size 3 must overlap by at least one node. That overlapping node is guaranteed to have the most up-to-date write, providing strict read-your-writes consistency even during node failures.


Zero-Downtime Maintenance and Zone Resiliency

A major operational advantage of this layout is routine maintenance without degradation:

  • Operating system upgrades, kernel patches, and hardware maintenance can be performed by completely taking down an entire Zone (e.g., Zone 1).
  • Since every Storage Group retains 4 running nodes, both read quorums (R=3R = 3) and write quorums (W=3W = 3) continue to be satisfied without interruption.
  • Production clusters can execute continuous rolling deployments across zones with zero impact on latency SLAs or availability.

Cross-Datacenter Asynchronous Replication

Intra-cluster quorum replication protects against server, rack, and zone outages. However, financial platforms must also survive regional disasters—such as a metropolitan-area power loss, major network fiber severing, or natural calamities.

Running synchronous replication across geographically distant regions would introduce unacceptable cross-region network latency (e.g., 50–100ms+ round trips). To balance latency and regional survival, JunoDB utilizes asynchronous cross-datacenter replication orchestrated by the proxy tier.

graph LR
    subgraph Region A [Datacenter 1: Primary Active]
        Client[Client Application]
        LB1[Load Balancer]
        JP1[Juno Proxy Cluster]
        SG1[Storage Grid Cluster 1]
        
        Client --> LB1
        LB1 --> JP1
        JP1 <-->|Sync Quorum W=3, R=3| SG1
    end

    subgraph Region B [Datacenter 2: Disaster Recovery / Active-Active]
        JP2[Juno Proxy Cluster]
        SG2[Storage Grid Cluster 2]
        
        JP2 <-->|Sync Quorum W=3, R=3| SG2
    end

    JP1 -.->|Async Cross-DC Replication| JP2

Replication Flow

  1. The client writes to DataCenter 1.
  2. The local Juno Proxy coordinates the intra-cluster synchronous write quorum (W=3W = 3) across the local 5-zone grid.
  3. As soon as the local write quorum is acknowledged, the proxy completes the client request.
  4. Concurrently and asynchronously, the local proxy forwards the operation payload to a remote Juno Proxy in DataCenter 2.
  5. The remote Juno Proxy writes the record to its own local storage grid using its own local quorum protocol.

If an entire data center suffers an catastrophic failure, traffic can be redirected to DataCenter 2 immediately, minimizing downtime and strictly bounding data loss exposure to in-flight asynchronous replication buffers.


Architectural Trade-Offs

Design ChoiceBenefitTrade-off
5-Node Storage GroupsTolerates up to 2 simultaneous node/zone failures without dropping availability.Requires 5×5\times storage capacity per gigabyte of primary data.
Synchronous Quorum WritesEliminates data loss on local failover; enforces strict version consistency.Tail latency is bounded by the speed of the 3rd fastest storage node in the group.
Proxy-Orchestrated Async Cross-DCKeeps write latency low for the client; isolates regional network partitions.In the rare event of sudden, catastrophic primary DC destruction, un-replicated in-flight writes risk loss (RPO > 0).

Summary

JunoDB’s path to six nines of availability relies on clean separation of concerns and layered redundancy:

  1. Stateless Compute: Juno Proxies and load balancers scale independently and fail over seamlessly.
  2. 2D Storage Grid: Divides data into discrete shards managed across distinct physical failure zones.
  3. Synchronous Quorums (R+W>NR + W > N): Delivers zero data loss and read-after-write consistency within the cluster while tolerating full zone outages.
  4. Inter-DC Asynchronous Mirroring: Protects against regional disasters without imposing cross-region latency overhead on user requests.
Arpit Bhayani

Principal Engineer II at Razorpay - building Agent Studio, Ex-staff engg at GCP Memorystore & Dataproc, Creator of DiceDB, ex-Amazon Fast Data, ex-Director of Engg. SRE and Data Engineering at Unacademy. I spark engineering curiosity through my no-fluff engineering videos on YouTube and my courses