ListenersBest Practices

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