Think like a vertex: Pregel / BSP
When the answer depends on the entire graph (PageRank, connected components) there is no locality and index-free adjacency buys nothing, so computation flips to Pregel/BSP — each vertex computes, messages its neighbors, then everyone waits at a barrier before the next superstep — and one supernode with millions of messages makes every other vertex wait, so the whole pass runs as slow as the slowest partition.
Local queries light up a few nodes and everything we built makes them fly. PageRank lights up EVERY node, every round — no locality, so index-free adjacency buys nothing. The model flips to thinking like a vertex: compute, message neighbors, wait at a barrier, repeat. And the supernode is back one last time, stalling the barrier while everyone waits. You've now seen every force in graph databases — time to make the calls yourself.
Scene 13
Think like a vertex: Pregel / BSP
- Watch
- Try it
- Predict
- Capture
PageRank over a tiny 5-vertex graph. Watch one round: every vertex sends its current score, split across its out-edges, to its neighbors. Then everyone STOPS at the horizontal line — nobody reads the next round's numbers until all the messages from this round have landed. Only then do scores update and the next round begins. Notice the whole graph lights up — unlike the k-hop query from scene 1 that lit only a couple of nodes.
Highlighted lines are the ones running in the diagram right now.
def run(graph, compute):init_scores(graph, 1 / N)for step in range(MAX_SUPERSTEPS): # ~20-50 for PageRankfor vertex in graph: # every vertex, every roundinbox = messages_for(vertex)compute(vertex, inbox) # send new messagesbarrier() # ALL must arrive before the next superstep startsif converged(graph): break
def compute(vertex, inbox):incoming = sum(inbox) # supernode: millions of messagesvertex.score = 0.15 / N + 0.85 * incomingshare = vertex.score / out_degree(vertex)for neighbor in vertex.out_edges:send(neighbor, share) # push along every out-edge
def await(workers):for w in workers:w.signal_arrived() # 'I finished this round'while not all_arrived(workers):wait() # everyone idles for the laggardrelease() # next superstep may begin
Where this sits in Build a graph database (Neo4j / Dgraph-style)
Scene 13 of 16, in the The payoff act — No locality for whole-graph work — then design it.. Whole-graph algorithms have no locality to exploit, so the model flips to Pregel/BSP — every vertex runs a small function, sends messages to neighbors, then all vertices wait at a synchronization barrier before the next superstep — and a supernode at the barrier stalls everyone.
Up next. You've built the whole stack: first-class edges, index-free adjacency, the store records, SEEK vs EXPAND, the storage layout fork, Cypher and the planner, the supernode failures, ACID, distribution, bolted-on search, and the Pregel inversion. The last skill is choosing among all of it for a real system — storage layout, index strategy, supernode handling, single-node ACID vs distributed, and traversal-heavy vs aggregate-heavy workloads.
All 16 scenes in Build a graph database (Neo4j / Dgraph-style) · Every curriculum