A practical field guide · Free to use
Event Replay Validation Checklist
A replay is useful only when you can explain what should be reconstructed and compare that expectation with the result. Use this worksheet to test a small event stream before relying on a larger projection.

Start with a fixture you can check by hand
Choose one stream and one projection. Record the event schema, projection version, ordering rule and tenant before running anything. A fixture small enough to inspect is easier to diagnose than a large production export. Keep customer payloads out of a public reproduction; synthetic events should exercise the behaviour without exposing their original records.
Write the expected final state before running the implementation. For an illustrative inventory stream, add ten units, remove three, then add one. The expected state is eight. At the second event it is seven. This example tests arithmetic and an ordered history; it does not establish throughput, transactional isolation or durability under a power failure.
Name the failure boundary
A replay in the same process, a restart after a clean shutdown, and recovery after abrupt termination are separate tests. Label each result with the boundary actually exercised. If the process flushed its buffers before exit, do not describe that as an abrupt-crash test. Record the storage directory and the exact command used to reopen it.
Keep recovery tests in an isolated disposable environment. Stop a process only after checking that it is your fixture and that no shared database or customer workload depends on it. A failed recovery is useful evidence when the last acknowledged write and the point of interruption are recorded. It is not useful when the input history is unknown.
Compare the state and the route used to produce it
Run the projection against the original fixture and save the result. Rebuild from the same ordered events into an empty destination, then compare fields and event counts. Test a historical position separately from the latest state. Record how duplicate delivery, rejected events and missing sequence positions are handled by your actual implementation.
Repeat the comparison after the chosen restart boundary. If the endpoint is tenant-scoped, include the tenant in the request and record it in the test notes. An empty response may be a query-boundary mistake rather than data loss. Preserve both responses and the request shape so another engineer can distinguish those causes.
Use the result to decide the next test
Mark each expectation passed, failed or not run. A passing small fixture supports that fixture and its tested environment. It does not prove the recovery of every projection, version or workload. Add a new fixture when a real failure exposes a new boundary; keep the old fixture so a fix does not erase the regression check.
The linked AllSource walkthrough gives a concrete starting point. This checklist adds a reusable record for your own comparison. A framework's existing persistent checkpointer may already meet your needs; use the same fixture and failure boundary to compare it fairly. Prefer the simplest mechanism that satisfies the observed requirement.
| Fixture | add 10 → remove 3 → add 1 |
|---|---|
| Expected latest / historical | 8 / 7 after event 2 |
| Restart boundary | Clean shutdown / abrupt termination / not run |
| Observed state | Record actual values and differences |
| Reproduction | Commit, command, tenant, schema and storage path |
Your blank worksheet
Download the text file and complete it in your own notes, or print this page. No account or purchase is required for this worksheet. Your completed notes are not submitted by this page.
- Fixture and synthetic event IDs:
- Expected ordering rule:
- Tenant / stream:
- Schema and projection version:
- Expected state before run:
- Observed initial state:
- Restart boundary actually tested:
- Observed recovered state:
- Pass / fail / not run:
- Reproduction command and next test:
