Listener Best Practices
Keep listeners mutation-only
No HTTP, no external DB, no emit or submit. Listeners run on the hot write path. External I/O belongs in side_effects or downstream consumers.
Prefer projections for queryable state
If a dashboard or API reads the data via named queries, materialize it in a projection. Listeners update entity snapshots — not projection tables.
Design one-directional chains
Avoid cycles: listener A emits indirectly → listener B → back to A. The runtime detects cycles and errors.
Limit resolve: breadth
Each lookup() loads a full entity snapshot. Many resolves per listener add latency. For fan-out to thousands of entities, use emit_each or submit in side_effects.
Common mistakes
Performing I/O in listeners. Only entity state mutations allowed.
Using listeners for projection use cases. Use projections for read models.
Circular listener chains. Keep reactions acyclic.
Large resolve: lookups on the synchronous path. Fan out asynchronously instead.
Next steps
- Examples — reference patterns
- Defining Listeners — syntax
- Workflows — Side Effects — async alternatives