G-Set (Grow-Only Set)
This page is part of the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at gset.md, and llms.txt lists every page.tree.GSet(key) -> GSetAccessor, merge mode LatticeMergeMode.GSet.
Semantics
A G-Set is a set that only ever grows: elements can be added but never
removed. Elements are opaque byte[] compared by content. The merge is plain
set union, which is trivially commutative, associative, and idempotent, so
concurrent active-active adds from any number of clusters all survive
convergence and a re-delivered add is harmless.
Because it carries no dots and no tombstones, a G-Set is the minimal set primitive - the smallest, cheapest choice for append-only workloads such as tag sets, seen-ids, or an accumulating audience. When you need to remove elements, reach for the add-wins OR-Set or the remove-wins RW-Set instead.
Behaviour
Both clusters hold {alice, bob}. Union keeps every add, so no concurrent add is lost.
Merge is plain set union, which is commutative, associative, and idempotent.
sequenceDiagram
participant A as Cluster A
participant B as Cluster B
A->>A: Add("alice")
B->>B: Add("bob")
A-->>B: merge ships {alice}
B-->>A: merge ships {bob}
Note over A,B: merge is set union
Note over A,B: converged = {alice, bob}
Example
var seen = tree.GSet("campaign:autumn:reached");
// Two clusters add members concurrently; union keeps both.
await seen.AddAsync(Encoding.UTF8.GetBytes("alice"), cancellationToken);
await seen.AddAsync(Encoding.UTF8.GetBytes("bob"), cancellationToken);
bool reachedAlice = await seen.ContainsAsync(Encoding.UTF8.GetBytes("alice"), cancellationToken);
IReadOnlyList<byte[]> everyone = await seen.ToListAsync(cancellationToken);
See also: the add-wins OR-Set, the remove-wins RW-Set, and the CRDT overview.