Skip to content

CONCEPT Cited by 1 source

Direction-agnostic edge ID

A direction-agnostic edge ID is an edge identifier constructed deterministically from the pair of endpoint node IDs in a way that produces the same identifier regardless of which direction the user requested the traversal. The canonical construction: lexicographically sort the source and destination node IDs, then concatenate them.

edge_property_id = sort([source_id, target_id]).concat()
                 = lower(source_id, target_id) || higher(source_id, target_id)

Why it matters

In a graph storage system that uses forward and reverse edge indexes on the link namespace, an edge between nodes A and B is physically written twice on the link side (once at forward partition A, once at reverse partition B).

Edge properties, by contrast, are direction-symmetric — a property of the edge is the same property whether the caller traversed A → B or B → A. Storing the property bag twice would mean every property update needs to write to two records atomically; storing it under one of the two endpoints would break the symmetry.

The direction-agnostic ID makes the property record single- copy: lex-sorting the endpoints before concatenation gives a unique-and-stable identifier per edge-pair. Properties are indexed once in the property namespace, and either direction reaches them via the same deterministic key.

The verbatim disclosure

"To ensure consistent record identifiers when updating edge properties in either direction, the Abstraction lexicographically sorts and concatenates the source and destination node IDs to create a direction-agnostic identifier for property storage. This ensures that properties can be accessed or mutated in a single database call regardless of the direction specified in the request." (Source: sources/2026-05-29-netflix-high-throughput-graph-abstraction-at-netflix-part-i)

Construction example

Caller-requested edge Lex-sorted endpoints Concatenated ID
profile-A → device-X [device-X, profile-A] device-X\|profile-A
device-X → profile-A [device-X, profile-A] device-X\|profile-A
account-Z → profile-A [account-Z, profile-A] account-Z\|profile-A

Both directions of the (profile-A, device-X) edge yield the same property ID. A point read on the property namespace returns the property bag in a single partition lookup regardless of how the traversal came in.

Composition with other patterns

The direction-agnostic ID composes with:

  • patterns/separate-edge-links-from-properties — the prerequisite that puts edge properties in their own namespace.
  • patterns/forward-and-reverse-adjacency-index — the forward and reverse link namespaces use the natural endpoint-keyed IDs, while the property namespace uses the direction-agnostic ID. Two different ID strategies for two different namespace classes.
  • Last-Write-Wins via timestamped idempotency tokens — property updates from either direction land at the same partition, so LWW resolution happens against a consistent identifier.

When the natural ID would have failed

If properties were stored with a natural directional ID like source||target, then a property update issued from the reverse-direction traversal (target||source) would land at a different partition. Two options to fix this without direction-agnostic IDs would each break:

  1. Store properties under both natural IDs — doubles property storage, requires atomic two-partition writes for every update (unsolved without distributed transactions or another entropy-repair pipeline).
  2. Force callers to always use the canonical direction — leaks a storage detail into the API surface; bidirectional edges have no natural canonical direction.

The lex-sort-then-concat construction sidesteps both issues by making the canonical direction a function of the ID values, unique per pair, and stable across calls.

Trade-off

The direction-agnostic ID is opaque to humans and not directly useful as a foreign key — applications that want to retrieve an edge by (source, target) must apply the same lex-sort-then- concat transformation client-side or via a server-provided helper. A small ergonomic cost; a major correctness payoff.

Seen in

Last updated · 542 distilled / 1,571 read