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.