Project 6: Distributed Presence Workspace
Build a collaborative incident room that represents users, devices, reconnect overlap, and uncertain failure honestly while Phoenix.Tracker converges across a cluster.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Level 3 — Advanced |
| Time Estimate | 16–22 hours |
| Language | Elixir (alternatives: TypeScript presence client, Erlang tracker) |
| Primary Tools | Phoenix.Presence, Phoenix.Tracker, Phoenix.PubSub, LiveView or Channels |
| Prerequisites | PubSub topics, process monitoring, distributed failure, client state/diff synchronization |
| Key Topics | One key/many metas, CRDT convergence, heartbeat failure detection, reconnect overlap, compact metadata |
| Observable Deliverable | Multi-device responder roster with uncertainty states and a repeatable two-node partition drill |
1. Learning Objectives
By completing this project, you will be able to:
- Distinguish PubSub subscription membership from replicated application presence.
- Model one logical responder with multiple concurrent connection metadata records.
- Explain Phoenix.Tracker’s heartbeat and CRDT-based eventual convergence without claiming instant global truth.
- Apply an initial presence state followed by join/leave diffs using stable metadata references.
- Represent hard failure and reconnect overlap honestly in the user interface.
- Keep presence metadata small, ephemeral, and safe while batch-fetching durable profile detail.
- Keep Presence
handle_metas/4bounded, and understand the stricter control-path constraints of raw Trackerhandle_diff/2. - Prove that authorization, billing, audit, and incident participation history do not depend on presence.
2. Theoretical Foundation
2.1 Presence Is a Replicated Liveness Projection
Phoenix.Presence builds on Phoenix.Tracker, which uses heartbeat exchange and a conflict-free replicated data structure to merge presence changes across nodes. Each node owns a local view. There is no single process that can answer “who is online everywhere right now?” with instantaneous certainty. Local joins appear immediately, remote joins appear after replication, and hard failure requires time to distinguish from temporary delay or network partition.
That model is appropriate for a responder roster because temporary disagreement is acceptable and convergence is useful. It is not appropriate for access control, billing, compliance evidence, or an audit trail. Those concerns require a durable, authoritative store and explicit transactions.
2.2 One Key, Many Metas
A stable presence key typically represents a logical resource such as a user ID. Each connection—browser tab, mobile socket, desktop application—adds a metadata entry. Phoenix assigns each entry a phx_ref; an update may also include phx_ref_prev. Therefore “Douglas is online” is a derived statement: at least one valid meta remains for Douglas’s key.
user key: 42
│
├── meta ref=A node_a laptop tab status=active
├── meta ref=B node_b phone status=away
└── meta ref=C node_a second tab status=active
close ref=C
│
└── key 42 remains online because A and B remain
Flattening this structure to a boolean too early produces false offline transitions and loses device-level diagnostics.
2.3 State Then Diff
A client begins with a complete presence state and then applies diffs. The state is grouped by logical key and contains a metas collection. A diff has joins and leaves, each carrying the same keyed/meta structure. Supported synchronization logic uses references to add or remove exact metas.
INITIAL STATE
42 -> [A, B]
77 -> [D]
DIFF
joins: 42 -> [E]
leaves: 42 -> [B]
RESULT
42 -> [A, E]
77 -> [D]
The join and leave may describe reconnect overlap, not a human deliberately leaving and re-entering. The UI should avoid turning every diff into a durable activity event.
2.4 Failure Detection and Uncertainty
Phoenix.Tracker periodically broadcasts deltas and heartbeats. In Phoenix.PubSub 2.2, documented defaults include a 1.5-second broadcast period, a heartbeat after ten silent periods, approximately 30-second down detection, and a 20-minute permanent-down period. These are operational defaults, not instant-failure guarantees.
On graceful shutdown, permdown_on_shutdown can tell replicas that a tracker is permanently gone. It is safe to set this option to true only when the Tracker is mounted at the root of the supervision tree under a :one_for_one strategy. With that prerequisite satisfied, true removes presence quickly but may generate mass leave/rejoin churn during a rolling deploy; false allows reconnect overlap but leaves temporary ghosts. The correct policy depends on product behavior and deployment topology.
2.5 Convergence Mental Model
Phoenix.PubSub replication
┌──────────────────────────┬──────────────────────────┐
│ │ │
v v v
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ Tracker node A │ │ Tracker node B │ │ Tracker node C │
│ refs A,C,D │ │ refs A,B,C,D │ │ refs A,B,D │
└───────┬────────┘ └───────┬────────┘ └───────┬────────┘
│ temporary views │ │
└──────────────────────────┴──────────────────────────┘
heartbeat + CRDT merge
│
v
converged refs A,D,E after reconnect
Convergence means replicas that can communicate and continue exchanging state eventually agree. It does not mean every intermediate read is identical, nor does it replay application PubSub events missed during a partition.
2.6 Metadata Discipline
Presence metadata is replicated and broadcast. Store only small ephemeral fields needed for liveness presentation: device class, coarse activity state, connection timestamp, and opaque identifiers. Durable name, avatar, team, incident role, or clearance should be fetched in one batch through fetch/2 or an application query.
fetch/2 runs on list and updates. It should avoid N+1 queries by collecting all keys, querying once, and enriching the grouped result. A Phoenix.Presence module may implement handle_metas/4 to consume presence metadata changes on the Elixir side; keep that optional callback bounded. At the lower-level Phoenix.Tracker boundary, handle_diff/2 executes in the tracker server context, so blocking I/O or an unhandled exception can delay or crash tracking. Optional work belongs in a supervised task or downstream durable pipeline.
2.7 Common Misconceptions
- “Presence says the user is logged in.” It says tracked processes are currently believed alive; authentication is separate.
- “A leave diff is an audit event.” It may represent timeout, partition, deploy, tab close, or tracker policy.
- “Each user has one presence.” One key can have many metas.
- “CRDT means every node is always consistent.” It means mergeable eventual convergence, not synchronous agreement.
- “Hard failure is immediate.” Failure detectors trade detection speed against false positives.
3. Project Specification
3.1 What You Will Build
Create a collaborative incident workspace with:
- A responder roster grouped by logical user.
- Expandable device details for every active meta.
- Coarse activity states such as active, away, and reconnecting.
- A visible
UNCERTAINstate when a node or connection is suspected but convergence is pending. - A cluster diagnostics panel showing local node, tracker replica, last diff, known metas, and convergence drill timing.
- Development controls for graceful tab close, abrupt process loss, node isolation, reconnect, and delayed profile fetching.
The durable incident membership table determines who may enter the room and preserves incident participation history. Presence only answers who appears connected now.
3.2 Functional Requirements
- Authorization before tracking: Only authorized incident responders may track or list room presence.
- Stable key: Use one opaque stable key per logical user.
- Many metas: Preserve each connection with its own ref and device metadata.
- Grouped roster: A user remains online until the last meta leaves.
- Initial synchronization: Apply full state before diffs and tolerate diffs that race with initial loading.
- Reconnect overlap: Show old and new refs without duplicating the logical user.
- Failure uncertainty: Distinguish graceful leave from suspected hard loss.
- Compact replication: Keep tracked metadata bounded and non-sensitive.
- Batch enrichment: Resolve durable display details in one query per state/diff cycle.
- Bounded callbacks: Presence
handle_metas/4performs no blocking external work; any optional raw Tracker exercise keepshandle_diff/2equally bounded. - Diagnostics: Measure time from isolation to uncertainty, leave, reconnect, and convergence.
- Non-authoritative behavior: No business transaction is triggered solely by presence join/leave.
3.3 Non-Functional Requirements
- Convergence target: Under the local three-node drill, all connected nodes report the same final refs within 10 seconds after connectivity is restored.
- Callback budget: p99 diff callback duration under 25 ms without profile-fetch latency included.
- Metadata budget: At most 512 encoded bytes per meta in the reference scenario.
- Privacy: No email, token, role secret, or incident narrative in replicated metadata.
- Resilience: A failed enrichment query may degrade display detail but must not stop tracker convergence.
- Observability: Node, topic class, and outcome are bounded dimensions; raw user IDs remain in traces/logs rather than metric labels.
3.4 Presence Data Outline
Presence key: opaque user identifier
Meta:
phx_ref: tracker-generated unique reference
phx_ref_prev: previous ref when updated, optional
device_id: opaque connection/device identifier
device_class: laptop | phone | tablet
activity: active | away
connected_at: UTC timestamp
tracker_node: bounded node alias
Fetched profile detail:
display_name, avatar_url, incident_role
source: authorized database query
3.5 Real World Outcome
Run three application nodes, join incident room INC-104 from two laptop tabs and one phone as Douglas, then join from one laptop as Margarita. The roster groups the three Douglas metas and shows one logical user. Close the second laptop tab: Douglas remains online with two devices.
Next, isolate the node hosting the phone. The UI must not instantly assert that the phone definitely left. It marks that connection uncertain according to your failure policy. Reconnect the phone on a new node, producing a new ref while the old ref is still known. After Tracker converges, all three nodes show the same final refs.
The reference transcript is:
Room INC-104 — Responders
Douglas ONLINE devices=3 [laptop:A, tab:C, phone:B]
Margarita ONLINE devices=1 [laptop:D]
leave ref=C -> Douglas remains ONLINE devices=2
partition node_b -> phone ref=B status=UNCERTAIN
reconnect phone ref=E -> temporary metas=[B,E]
convergence complete -> metas=[A,E] consistent_on=3/3 nodes
audit truth changed by presence diff=false
4. Solution Architecture
4.1 High-Level Design
┌─────────────────────┐ authorize ┌──────────────────────┐
│ Channel / LiveView │────────────>│ Incident membership │
└──────────┬──────────┘ │ durable authority │
│ track authorized user └──────────────────────┘
v
┌─────────────────────┐ deltas ┌─────────────────────┐
│ Presence / Tracker A│<----------->│ Presence / Tracker B│
│ local refs A,C,D │ PubSub │ local ref B │
└──────────┬──────────┘ └──────────┬──────────┘
│ state + diff │ state + diff
v v
┌─────────────────────┐ ┌─────────────────────┐
│ Client sync reducer │ │ Client sync reducer │
└──────────┬──────────┘ └──────────┬──────────┘
└──────────────────┬────────────────┘
v
grouped responder roster
4.2 Key Components
| Component | Responsibility | Key Decision |
|---|---|---|
| Incident membership service | Durable authorization and participation history | Never derive membership from Presence |
| Presence module | Track/untrack/update and enrich list | Compact meta, batched fetch |
| Phoenix.Tracker | Replicate liveness deltas | Accept eventual consistency |
| Client sync reducer | Apply state then refs-based diffs | Never remove whole key for one meta leave |
| Roster projection | Group metas and derive online/uncertain | Display uncertainty explicitly |
| Failure drill controller | Isolate/reconnect nodes in development | Deterministic timestamps and refs |
| Telemetry handlers | Measure callbacks and convergence | No blocking handler work |
4.3 Invariants
- A logical user appears once in the roster regardless of meta count.
- A user is not displayed offline while any accepted meta remains.
- Presence cannot grant room access.
- Every leave removes only the matching ref.
- Durable audit rows are never created from unverified presence diffs.
- Tracker callbacks remain bounded even when enrichment or audit dependencies fail.
4.4 Convergence Algorithm Overview
ON initial state:
replace local presence map using supported state synchronization
batch-fetch authorized display details
render grouped roster
ON presence diff:
apply joins and leaves by exact ref
derive users affected by the diff
batch-fetch missing durable display details
update grouped roster
ON suspected replica loss:
preserve uncertainty marker until Tracker reports the applicable change
ON reconnect:
accept new ref; do not manually delete old ref
allow Tracker merge/down policy to converge
5. Implementation Guide
5.1 Development Environment Setup
Verify versions and create three named development nodes through your preferred local release, terminal, or container workflow. The exact node-launch mechanism may vary, but the observable check should resemble:
$ epmd -names
epmd: up and running on port 4369 with data:
name room_a at port 9101
name room_b at port 9102
name room_c at port 9103
All nodes need the same cookie, compatible Phoenix.PubSub configuration, and direct connectivity. Record the topology you actually test.
5.2 Suggested Project Structure
presence_workspace/
├── lib/presence_workspace/
│ ├── incidents/membership.ex # durable authority
│ ├── presence.ex # Phoenix.Presence behaviour
│ ├── presence_projection.ex # grouped keys/metas
│ └── telemetry.ex
├── lib/presence_workspace_web/
│ ├── channels/incident_channel.ex
│ └── live/incident_room_live.ex
├── test/presence_workspace/
│ ├── presence_projection_test.exs
│ └── presence_cluster_test.exs
└── scripts/
└── presence_partition_drill.md # commands and expected observations
5.3 The Core Question You’re Answering
“How do I represent ‘online’ honestly when users have many connections and the cluster cannot know failure instantly?”
Your written answer should define online, offline, uncertain, reconnecting, and converged in terms of observable refs and tracker state—not human intent.
5.4 Concepts You Must Understand First
- State and diff synchronization
- Why must initial state precede ordinary diffs?
- How does a
phx_refidentify one meta? - Reference: Phoenix Presence server and JavaScript client docs.
- CRDT convergence
- What does conflict-free merge guarantee after communication resumes?
- What does it not guarantee during a partition?
- Book: “Designing Data-Intensive Applications, 2nd Edition,” replication and distributed systems chapters.
- Failure detection
- Why is silence ambiguous?
- How do down and permanent-down windows affect UX?
- Process ownership
- What happens to tracked metas when their owning process exits?
- How does abrupt node loss differ from orderly untracking?
- Callback isolation
- Why should Presence
handle_metas/4remain bounded, and why is blocking raw Trackerhandle_diff/2even more dangerous? - Which work belongs in a supervised task or durable pipeline?
- Why should Presence
5.5 Questions to Guide Your Design
- Which stable identifier groups a user across devices without exposing private data?
- Which metadata is truly ephemeral and necessary on every node?
- How does the UI distinguish one meta leave from the final meta leave?
- When does the UI show
UNCERTAIN, and what clears it? - How will a failed batch profile query affect the roster?
- Is the Tracker at the supervision-tree root under
:one_for_one, and what does a rolling deploy look like under the safepermdown_on_shutdownpolicy available to that topology?
5.6 Thinking Exercise
Draw two nodes and one user with refs A and C on node A and ref B on node B. Trace:
- Graceful close of C.
- Network isolation of B.
- Reconnect on node C as ref E.
- Delayed observation of B’s down status.
- Connectivity restoration and convergence.
For each step, list each node’s possible local view and the safest UI label. Then explain why none of those steps should charge a bill or create a compliance attendance record.
5.7 The Interview Questions They’ll Ask
- “How is Phoenix Presence different from PubSub subscriptions?”
- “Why can one presence key contain multiple metas?”
- “What consistency model does Phoenix.Tracker provide?”
- “Why can a disconnected user remain visible temporarily?”
- “How do Presence
handle_metas/4and raw Trackerhandle_diff/2differ, and what work is dangerous inside either callback?” - “Why isn’t presence a valid authorization or audit source?”
5.8 Hints in Layers
Hint 1 — Render the raw shape first: Inspect grouped keys and metas before inventing an online boolean.
Hint 2 — Let refs drive mutation: Remove exact refs using supported sync behavior; never infer removal by device name.
Hint 3 — Degrade enrichment, not tracking: If profile data fails, show an opaque responder label and preserve liveness convergence.
Hint 4 — Separate graceful from abrupt drills: A tab close, process kill, node halt, and network partition have different timing.
Hint 5 — Measure convergence from a shared scenario ID: Compare final ref sets across nodes without using raw user IDs as metrics.
5.9 Books That Will Help
| Topic | Book | Focus |
|---|---|---|
| Phoenix Presence | “Real-Time Phoenix” by Stephen Bussey | Presence and Channels chapters |
| Replication and convergence | “Designing Data-Intensive Applications, 2nd Edition” | Replication, distributed systems, and CRDT discussion |
| Operational failure | “Release It!, 2nd Edition” | Stability patterns and failure isolation |
| Integration boundaries | “Enterprise Integration Patterns” | Message channels and event messages |
5.10 Implementation Phases
Phase 1 — Durable membership and single-node presence (4–6 hours)
- Define authorized incident membership.
- Track one connection with minimal metadata.
- Render grouped state.
Checkpoint: An unauthorized user cannot track or list; one authorized user appears once.
Phase 2 — Multi-device state and diff (4–5 hours)
- Open three connections under one key.
- Apply state and diffs by ref.
- Keep the user online as individual refs leave.
Checkpoint: Closing one of three tabs yields devices=2, not offline.
Phase 3 — Batch enrichment and callback safety (3–5 hours)
- Add compact meta validation.
- Batch-fetch display details.
- Isolate optional failure-prone work.
Checkpoint: A delayed profile source degrades names/avatars without blocking Tracker callbacks.
Phase 4 — Cluster and hard-failure drill (5–8 hours)
- Run three connected nodes.
- Isolate one node and record local views.
- Reconnect with a new ref and observe convergence.
Checkpoint: All connected nodes reach the same final refs within the measured target.
Phase 5 — Deploy policy and tests (4–6 hours)
- Compare graceful permanent-down enabled/disabled behavior.
- Test rolling restart, abrupt halt, and partition.
- Document the chosen product language for uncertainty.
Checkpoint: Test reports distinguish all failure modes and prove no business truth depends on diffs.
5.11 Key Implementation Decisions
| Decision | Options | Recommendation | Rationale |
|---|---|---|---|
| Logical key | Connection ID / user ID | Opaque stable user ID | Groups devices without exposing details |
| Meta detail | Full profile / compact ephemeral fields | Compact fields | Limits replication and privacy risk |
| User online rule | Latest tab / any meta | Any accepted meta | Avoids false offline transitions |
| Profile enrichment | Per meta query / batched fetch | Batched fetch | Prevents N+1 work |
| Shutdown behavior | Immediate permdown / convergence window | First verify root-level :one_for_one, then choose from measured deploy UX |
Immediate permdown is safe only with the documented supervision topology |
| Audit handling | Presence diff / explicit durable event | Explicit durable event | Presence is eventual and ephemeral |
6. Testing Strategy
6.1 Test Categories
| Category | Purpose | Examples |
|---|---|---|
| Projection unit | Verify grouping and exact-ref mutation | One key with A/B/C; remove C |
| Authorization | Separate presence from access | Revoked responder cannot track |
| Callback performance | Keep Tracker work bounded | Slow profile source isolated |
| Cluster integration | Verify eventual convergence | Partition B, reconnect as E |
| Lifecycle | Compare graceful and abrupt loss | Tab close vs node halt |
| Privacy | Enforce metadata schema and size | Reject secret or oversized meta |
6.2 Critical Test Cases
- One user with three metas renders one roster row and
devices=3. - Removing one ref preserves the other refs and online status.
- Removing the final ref changes the user to offline according to UI policy.
- A duplicate join ref does not duplicate a device.
- A leave for an unknown ref does not remove the logical key.
- Initial state plus queued diff produces the correct final refs.
- Profile fetch uses one batch for all affected keys.
- Profile fetch failure does not crash the tracker path.
- Abrupt node loss shows uncertainty before convergence.
- Reconnect overlap temporarily permits old and new refs.
- Restored connectivity converges all nodes to the same set.
- Presence diffs never write durable attendance/audit rows.
6.3 Deterministic Test Data
Room: INC-104
Authorized keys: user-42, user-77
Initial metas:
user-42 -> A(node_a,laptop), B(node_b,phone), C(node_a,tab)
user-77 -> D(node_c,laptop)
Sequence:
leave C
isolate node_b
join E(node_c,phone)
mark B down after configured window
restore node_b connectivity
Expected converged refs:
user-42 -> [A,E]
user-77 -> [D]
7. Common Pitfalls & Debugging
7.1 Frequent Mistakes
| Pitfall | Symptom | Correction |
|---|---|---|
| Flatten key to boolean | One tab close makes user offline | Preserve the meta collection |
| Store profile in meta | Large replicated payload and leaks | Batch-fetch durable detail |
| Block callback work | Presence handling stalls; raw Tracker work can stall heartbeats/diffs | Bound handle_metas/4; offload optional work from either layer |
| Treat leave as intent | False audit or workflow events | Use explicit durable commands |
| Expect instant hard-loss detection | “Ghost” users reported as bug | Model and explain uncertainty window |
| Assume transitive cluster membership | Nodes see different rosters | Verify direct connectivity and topology |
7.2 Debugging Strategies
- Log scenario ID, tracker node, ref, operation, and monotonic timestamp.
- Compare
Presence.listresults on every node at controlled checkpoints. - Inspect node connectivity before blaming CRDT merge.
- Measure Presence
handle_metas/4duration; if you run the optional raw Tracker experiment, also measurehandle_diff/2duration and tracker mailbox length during injected latency. - Capture both the raw ref set and the grouped roster; grouping bugs often masquerade as replication bugs.
7.3 Performance Traps
Frequent activity updates create high diff volume. Large metadata multiplies cluster traffic. fetch/2 on every change can overload the database if it performs one query per meta. Avoid broadcasting cursor pixels or keystrokes as Presence metadata; use a separate ephemeral channel with sampling/coalescing.
8. Extensions & Challenges
8.1 Beginner Extensions
- Display device count and last connected time.
- Add a tooltip explaining
UNCERTAINversusOFFLINE. - Show raw refs in a development-only diagnostics drawer.
8.2 Intermediate Extensions
- Add coarse active/away updates with a minimum update interval.
- Compare Channel and LiveView clients using the same Presence module.
- Add tenant-scoped rooms and cross-tenant authorization tests.
8.3 Advanced Extensions
- Measure convergence across three geographically separated development nodes.
- Simulate a rolling deploy under both permanent-down policies and compare churn.
- Build a replayable, durable incident attendance log from explicit join/leave commands—not Presence diffs.
9. Real-World Connections
9.1 Industry Applications
- Collaborative editors: Presence shows cursors/devices while the document log stores durable edits.
- Incident response: Presence shows current responders while the incident record stores assigned roles and actions.
- Customer support: Agent availability is a hint for routing, not the authoritative staffing schedule.
- Gaming and social systems: Online status tolerates convergence; entitlements and purchases do not.
9.2 Related Open Source Projects
- Phoenix.Presence: Server behavior and client-oriented state/diff representation.
- Phoenix.Tracker: Heartbeat and CRDT-based distributed tracking.
- Phoenix.PubSub: Transport used to replicate tracker changes and broadcast Presence diffs.
9.3 Interview Relevance
The project provides a concrete answer to “what does online mean in a distributed system?” It demonstrates failure-detector uncertainty, replicated-state convergence, multi-device modeling, callback isolation, and the boundary between ephemeral liveness and durable business truth.
10. Resources
10.1 Essential Reading
- Phoenix.Presence — server behavior, metadata shape, and
fetch/2guidance. - Phoenix.Tracker — CRDT, heartbeat, callback, and shutdown semantics.
- Phoenix JavaScript Presence — supported state and diff synchronization.
- OTP
:pg— strong eventual membership and non-transitive views. - “Real-Time Phoenix” by Stephen Bussey — Presence and Channels chapters.
10.2 Tools & Documentation
- Phoenix.PubSub — distributed transport configuration.
- Telemetry — bounded instrumentation handlers.
epmd, remote IEx, and network fault tooling for the local cluster drill.
10.3 Related Projects in This Series
- Project 4: Establishes the distributed PubSub substrate.
- Project 5: Provides the LiveView incident workspace that renders the roster.
- Project 7: Supplies the mailbox and callback pressure techniques used to validate Presence safety.
11. Self-Assessment Checklist
11.1 Understanding
- I can define key, meta,
phx_ref, state, diff, and convergence. - I can explain why hard failure is not detected instantly.
- I can explain how one user remains online after one tab closes.
- I can defend the metadata boundary.
- I can state why Presence is not authorization or audit truth.
11.2 Implementation
- Multi-device grouping and exact-ref removal work.
- Initial state plus diffs survives reconnect.
- Profile detail is batch-fetched and failure-isolated.
- The three-node partition drill converges.
- Callback duration and metadata size meet budgets.
11.3 Growth
- I documented graceful close, process kill, node halt, and partition separately.
- I can explain the shutdown policy trade-off.
- I can reproduce and diagnose a temporary ghost meta.
- I can explain this consistency model in an interview.
12. Submission / Completion Criteria
Minimum Viable Completion
- One logical user supports at least three visible metas.
- Closing one meta does not create a false offline state.
- State and diff synchronization produces the expected final set.
- Presence is gated by durable authorization.
Full Completion
- All functional requirements and critical tests pass.
- A three-node partition/reconnect drill is documented with timestamps.
- Metadata and callback budgets are verified.
- Durable business behavior is proven independent of Presence diffs.
Excellence
- Compare both shutdown policies during a rolling deployment.
- Produce a convergence timeline visualization for every node.
- Demonstrate degraded profile enrichment without tracker delay or crash.
Return to the Pub/Sub in Elixir deep-dive guide or browse the expanded project index.