Event Sourcing & CQRS · CQRS and Projections

Replaying and Rebuilding Projections

Create new read models from history and fix bugs by replay.

A superpower of event sourcing: fix a projection bug or add a new read model by replaying the event log. Rebuild into a new table/index (blue-green), let it catch up, then switch reads atomically and drop the old one. Replays must be fast (batching, disabling expensive indexes during rebuild), side-effect free (no emails!), and running alongside live traffic until caught up.

Rebuild practices

Concern Approach
Downtime Build new model alongside; swap reads
Speed Batch reads/writes; defer secondary indexes
Side effects Projections must never send emails/HTTP
Long histories Parallelize by stream / partition where order allows
Blue-green projection rebuild
1. Create order_summaries_v2 (new schema) and checkpoint 'order_summaries_v2' = 0
2. Run projector v2 from position 0 in batches of 5,000 (bulk inserts)
3. When lag < 1 s, switch the query layer to v2 (feature flag / view swap)
4. Keep v1 for rollback a few days, then drop it

Common pitfalls

  • Rebuilding in place (users see empty data).
  • Side effects firing again during replay.
  • Rebuilds that take days because of row-by-row writes.

Key points

  • Replay into a new model
  • Swap reads when caught up
  • No side effects in projections

Further reading: Kurrent: Event sourcing and projections

Practice questions

Why rebuild a projection into a new table instead of in place?

Answer

Users keep reading the old consistent model during the rebuild, and you can switch atomically once the new one has caught up (and roll back if needed).

Why must projection handlers not send emails?

Answer

Replays would resend them; side effects belong in policies/process managers that run once on live events.

Open in the app to mark lessons complete, take notes and track your progress.