Observed-remove sets: remove the additions you actually saw
Trace unique add tags, observed removal, and the add-wins outcome for a concurrent unseen addition.
On this page
The question for today
What you’ll understand
- Compute visible membership from add-tag and tombstone sets.
- Explain why an unseen concurrent addition survives an observed remove.
- Distinguish a simple tombstone construction from optimized causal-context representations.
A replicated set cannot treat every add and remove as if all replicas observed one shared timeline. If one person removes an item while another independently adds it, the product needs a rule. An observed-remove set gives every addition a distinct identity and removes only additions the remover observed. The resulting add-wins behavior is a consequence of that observation rule, not a magical preference for every add over every remove.
Identity belongs to an addition, not just its element
Represent an add as a pair of an element and a globally unique tag, such as a stable actor identity plus a never-reused counter. Adding the same element twice creates two tags even though the user-visible set shows it once. A remove records the tags for that element currently visible at its origin. It cannot name a concurrent addition it has not seen. Reusing tags after a crash breaks the interpretation by making a genuinely new addition look like an already removed historical one.
For a simple state-based teaching construction, keep a grow-only set A of all learned add pairs and a grow-only tombstone set T of removed tags. Merge both by union. An element is visible when at least one learned add tag for it is not tombstoned. This stores more metadata than optimized implementations, but makes the mechanism explicit. A missing visible element and a missing historical add are different facts; deleting the latter from storage without a justified compaction rule can change future merges.
Concurrent removal has a precise meaning
Suppose A adds a label with tag A1 and later removes it, while a disconnected B independently adds the same label with tag B1. A’s remove can tombstone A1 but not B1. After merging, B1 remains live and the label is visible. If A first observes both additions and then removes the label, both tags are tombstoned and it becomes absent. Thus add wins applies to the concurrent unseen add; a causally later observed remove can remove all currently known additions.
In an operation-based implementation, the remove effect must carry the observed tags or equivalent causal information. Replacing it with delete whatever the receiver currently sees can erase a concurrent addition and produce different outcomes under different delivery orders. Optimized observed-remove sets can encode removed history through causal contexts rather than retaining an explicit tombstone for every tag. Their merge rules are not obtained by simply throwing tombstones away from this teaching construction. Use the algorithm’s actual context and dot rules when implementing the optimization.
Choose set semantics that users can understand
A collaborative favorites list may reasonably retain an item someone added while another person removed an older instance. An access-control revocation may demand a different policy: allowing an unseen concurrent grant to survive could violate expectations. CRDT convergence does not choose that policy for you. Distinguish add-wins, remove-wins, and permanently removed two-phase sets before deciding which type a field needs. Test histories using operation identities and causal observations rather than only the final human-readable set.
The modular lab provides a concrete warning about reusing finite tag counters. Reset, set m=4 and a=1, predict 0→1→2→3→0, then Step four times. A repeated residue cannot uniquely identify a fresh addition after wraparound. This is an additive orbit, not an OR-Set: there are no elements, tag maps, or remove effects in the diagram. The actual membership trace remains the explicit A and T calculation. Real tags need a non-reuse discipline or a proven epoch protocol.
Work it through
One removal and an unseen concurrent add
Replica A knows add pair (red,A1) and removes red. Disconnected B knows (red,B1), created independently. Merge their full-history teaching states.
After A’s removal, its add set contains (red,A1) and its tombstones contain A1. B’s add set contains (red,B1), with no tombstone for that tag.
Union produces two add pairs and one tombstone. A1 is removed but B1 is live, so the visible set is {red}, with cardinality one. There is no contradiction between two historical additions and one visible element.
After a replica observes this merged state and removes red, it tombstones the remaining live B1 too. The add history still has two pairs, the tombstone set has two tags, and the visible set becomes empty, with cardinality zero.
The unseen concurrent addition survives the first remove. A later remove that observes it can make the element absent.
The living notebook
Explore the model
Interactive lab · modular
Tag reuse destroys a historical distinction
Reset, set m=4 and a=1, predict 0→1→2→3→0, then Step four times. The repeated residue illustrates a finite-label collision; this lab does not implement add tags, tombstones, or an observed-remove set.
- Residue r0
- 0
- Orbit period · m/gcd(m,a)
- 12
- Distinct residues visited
- 1 of 12
Addition modulo m starts at zero: rₙ = na mod m. Playback advances two additions per second. The orbit has period m/gcd(m,a), including period one for a = 0. This is not a cryptographic security test or a primality algorithm. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forAn add identity must distinguish a new operation from a removed old operation.
Pause & reason
Check your understanding
Your turn
Try it yourself
Let A={(x,A1),(x,B1),(y,B2)} and T={A1}. List visible elements. A remove then observes and removes x; concurrently C adds (x,C1). What is visible after merging?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Track tags before counting user-visible elements, and remove only the observed live tags for x.
Compare with the solution
Initially x survives through B1 and y through B2, so the visible set is {x,y}, cardinality two. The remove adds B1 to T, while C1 remains untombstoned. After merge the visible set is again {x,y}, with x now supported by C1 and y by B2.
Keep the idea
Take it with you
- Unique tags distinguish repeated additions of the same element.
- Observed removal yields add-wins behavior for an unseen concurrent addition.
- Optimized causal-context sets need their own proven payload and merge rules.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.