OriginChainDB
Graph

Group records using their neighbors

← Graph examples

The language tabs use earlier client interfaces. Check SDK versions and connection setup before running them.

Label propagation repeatedly lets nearby nodes adopt a common label. It finds communities without a preset group count.

Before you run it: The iteration cap does not guarantee convergence. Use a seed when comparing repeat runs.

First load the five-person social graph. It creates the exact social.users table and follows relation used below.

A label is a temporary group identifier. Group records by equal labels; a larger label does not mean a better or larger community.

Form groups by sharing neighbor labelsThe seed and iteration limit affect this bounded grouping process.
  1. Give each node a labelStart from the loaded self-relation.
  2. Update from neighboring labelsNodes adopt the common label among their neighbors.
  3. Read the final groupsEqual labels identify a group; their values are not rankings.

Follow the example

  1. Prepare the self-referencing relationship.
  2. Set an iteration limit and explicit seed.
  3. Run the request.
  4. Group equal labels.

Set up the relationship

The relation must be declared in the schema's [[relations]] block and must target the table it is declared on. See schemas/reference#relations.

Run the request

rel is required and max_iter defaults to 20. Set seed explicitly for repeatable runs. If omitted, the engine uses the current Unix timestamp and does not return that chosen seed.

curl -G "https://$OC_HOST/v1/tenants/$OC_TENANT/graph/social.users/label_propagation" \
  --data-urlencode "rel=follows" \
  --data-urlencode "max_iter=20" \
  --data-urlencode "seed=42" \
  -H "Authorization: Bearer $OC_TOKEN"

Check the result

Labels identify groups and need not be contiguous numbers.

[
  { "pk": ["alice"],   "label": 0 },
  { "pk": ["bob"],     "label": 0 },
  { "pk": ["carol"],   "label": 0 },
  { "pk": ["dave"],    "label": 0 },
  { "pk": ["heidi"],   "label": 7 },
  { "pk": ["ivan"],    "label": 7 },
  { "pk": ["judy"],    "label": 7 },
  { "pk": ["mallory"], "label": 10 }
]

One row per node, ordered by primary key. pk is the primary-key array and label is an unsigned integer. Labels start as one-per-node identifiers and most of them die off during convergence, so the surviving values are not contiguous and carry no ordering - the only thing a label means is equality. Two nodes with the same label are in the same community.

Understand the behavior

  • Every node starts with its own label. Each round visits nodes in a shuffled order and moves each node to whichever label most of its neighbours hold.
  • The shuffle is the only thing the seed drives. Ties within a tally are broken deterministically by the smaller label, so the same seed on the same graph gives byte-identical output.
  • The pass repeats until no label changes or max_iter rounds have run. There is no convergence guarantee, which is exactly why the iteration cap exists.
  • Self-loops are ignored - a node never votes for itself by force.
  • max_iter=0 is refused with a 400 rather than returning an unconverged answer.

Important limits and checks

  • Omitting seed. The engine falls back to the current unix timestamp and does not tell you which one it used. Two calls a second apart can return different groupings with nothing in the response to explain the difference.
  • Reading labels as group numbers. They are not dense, not ordered and not stable across graphs. Compare them for equality and nothing else.
  • Expecting louvain's answer. Label propagation optimises nothing globally. On a graph without sharp community structure it can collapse most of the nodes into one label, which is a real result and not an error. Cross-check with louvain before trusting a partition.

Continue

Continue to find closely connected communities.

© 2026 Silicoyn Technologies Pvt Ltd

On this page