Zurück zu Cases
2024 · 8 Wochen · Solution Architect

Klarna AB (Contract)

PostgresGraphPerformance

// problem

Problem

Klarnas Payment-Graph wuchs auf 2.3 Mrd Kanten. Neo4j-Abfragen für Fraud-Detection brauchten 8+ Sekunden bei p99. Cloud-Kosten für den Neo4j-Cluster lagen bei €180k/Monat.

// approach

Approach

Migration auf PostgreSQL mit ltree für hierarchische Pfade und GIN-Indexes für Graph-Traversals. Denormalisierung der häufigsten Query-Pattern. Hybrid-Ansatz: kritische Pfade in Postgres, seltene Traversals bleiben im Neo4j-Read-Replica.

// code

payment_graph.sql
-- Payment graph with ltree for path traversal
CREATE TABLE payment_nodes (
    id          BIGINT PRIMARY KEY,
    node_type   TEXT NOT NULL,
    path        LTREE NOT NULL,
    metadata    JSONB DEFAULT '{}'
);

CREATE TABLE payment_edges (
    from_id     BIGINT REFERENCES payment_nodes(id),
    to_id       BIGINT REFERENCES payment_nodes(id),
    edge_type   TEXT NOT NULL,
    weight      NUMERIC DEFAULT 1.0,
    created_at  TIMESTAMPTZ DEFAULT now()
);

-- GIN index for fast path queries
CREATE INDEX idx_node_path
    ON payment_nodes USING GIST (path);

-- Key query: find all nodes in subtree
-- (replaces expensive Neo4j traversal)
SELECT n.* FROM payment_nodes n
WHERE n.path <@ text2ltree($1)
  AND n.node_type = ANY($2::text[])
ORDER BY n.path;

// outcome

Ergebnis

4x throughput bei Fraud-Detection-Queries

60% niedrigere Cloud-Kosten (€180k → €72k/Monat)

p99 von 8s auf 1.2s reduziert

Neo4j-Cluster von 12 auf 3 Nodes reduziert