Edge-cut, vertex-cut, predicate sharding

On power-law graphs edge-cut (one vertex per machine) dumps a hub's edges onto one machine as a hotspot, so vertex-cut splits the high-degree vertex across machines to balance edges; predicate-sharding (Dgraph) sidesteps the choice by keeping every edge of one TYPE together so 'all of X's friends' stays local — but no cut has zero crossing edges.

Previously

Cutting is unavoidable; the question was which cut crosses fewest edges. Edge-cut hotspots on hubs; vertex-cut splits the hub to balance edges; predicate-sharding keeps each edge type together so common expands stay local. The supernode broke naive partitioning, just as it broke reads and writes. But all of this is about TRAVERSAL by edges — what about finding a start node by its VALUE across a distributed store?

Scene 11a

Edge-cut, vertex-cut, predicate sharding

  1. Watch
  2. Try it
  3. Predict
  4. Capture
PARTITIONmachine 0machine 1AliceBobCarolDaveErinFrankGraceHeidiIvanJudyThe Rock×10MThe MatrixInceptionGothamFRIENDRATEDLIVES_INFOLLOWSSame social graph, now split across two machines — give every person to one machine and cut the…PARTITIONEdge-cut2 machinescross-hop: +4ms RPCSPINElocal 2 · global 14hub expand: crosses the cut
What to watch for

Same social graph, but it no longer fits on one machine — we have to cut it across two. Watch the simplest cut first: give every PERSON to one machine and cut whatever edges span the two. Step 1, the cut line drops. Step 2, look what happens to The Rock — it's a hub, so when its vertex lands on machine 1, ALL of its edges land there too. One machine ends up carrying half the graph's edges: a hotspot.

Continue unlocks when the animation finishes.
Implementation

Highlighted lines are the ones running in the diagram right now.

Partitioner.place
where does each vertex / edge live? (the slider picks the branch)
def place(graph, mode, M): # M machines
if mode == 'edge-cut':
for v in graph.vertices: # vertex → one machine
home[v] = hash(v) % M # a hub's edges all follow v
elif mode == 'vertex-cut':
for e in graph.edges: # edge → one machine
home[e] = hash(e) % M # split hubs: mirror across M
elif mode == 'predicate':
for e in graph.edges: # edge TYPE → one shard
home[e] = shard_of[e.type] # all of one type together
return home
Query.expand_friends
'all of X's friends' — how many machines does it touch?
def expand_friends(X, mode):
if mode == 'predicate':
return read(shard_of['FRIEND']) # ONE machine, local
# otherwise X's :FRIEND edges may live on several machines
machines = {home[e] for e in edges(X, 'FRIEND')}
return rpc_fanout(machines) # cross-cut network hops
StreamingPartitioner.assign
no cut crosses zero edges — min-cut is NP-hard, so we greedily place and accept some crossings
def assign(graph, M): # one pass, heuristic
for v in stream(graph.vertices):
# score each machine: keep neighbors together, stay balanced
best = argmax(m in machines,
neighbors_on(v, m) - lambda * load[m])
home[v] = best # greedy, not optimal
load[best] += 1
# whatever's left spanning machines is the unavoidable cut:
crossings = count(e for e in edges
if home[e.from] != home[e.to])
return home, crossings # crossings > 0 always

Where this sits in Build a graph database (Neo4j / Dgraph-style)

Scene 11a of 16, in the Scale & ACID act — ACID on one box; the partition cut turns hops to RPCs.. Edge-cut assigns each vertex to a machine and chokes on power-law hubs; vertex-cut splits the hub across machines to balance edges; predicate-sharding keeps all edges of one TYPE together so a common expand stays on one machine.

Up next. Sharding decided where edges live, but every query still has to find its ANCHOR — by name, by text, by range. That SEEK was never part of adjacency (scene 5), and it isn't part of sharding either. In distributed graph stores, finding start nodes by value is served by classic indexes — full-text, B-tree, vector — bolted on the side, not woven into the native pointer-chase.

All 16 scenes in Build a graph database (Neo4j / Dgraph-style) · Every curriculum

Built with Arqly
Every scene in Build a graph database (Neo4j / Dgraph-style) builds on the one before it.All 16 Build a graph database (Neo4j / Dgraph-style) scenes