Operations
Projection rebuild runbook
Rebuild disposable read models with the go-sequent replay pipeline: prepare, replay, catchup, optimize and golive, with the library API, CLI schema stages and operational tips.
Projection rebuild runbook
The replay pipeline follows Sequent 8: prepare, replay, catchup, optimize, golive, with an optional abort.
Ledger and balance projectors must stay strongly consistent, so on the live path they remain SyncInTxn. Rebuild is for disposable read models, or for filling a new projection from history.
Library API
pipe := &replay.Pipeline{
Name: "balances",
Source: eventSource, // implements StreamAll
Publisher: syncInTxnWithProjectorsOnly,
Schema: &replay.PostgresSchema{Pool: pool}, // or replay.NoopSchema{}
State: replay.NewMemoryState(), // or a DB-backed StateStore in your app
ManagedTables: []string{"account_balances"},
}
if err := pipe.RunAll(ctx); err != nil {
return err
}
Pipeline also has Prepare, Replay, Optimize, GoLive and Abort, so you can run the stages one at a time. Other fields are ReplaySchema, ViewSchema and BatchSize. When BatchSize is zero, Replay uses 1000.
The publisher replays through PublishProjectorsOnly. That excludes workflows, so a rebuild never re-triggers side effects such as emails or payments.
State is a StateStore. replay.NewMemoryState() forgets progress when the process exits. Use a durable store if a rebuild must survive a restart. The projector_replay_states table, created by migrations, is available for that.
Stages
| Stage | Action |
|---|---|
| prepare | Create the replay_* schema, create managed tables with CREATE TABLE … (LIKE …), truncate |
| replay | Stream historical events into the replay projectors and tables |
| catchup | Apply events appended since the high-water mark while the live system keeps running |
| optimize | Run ANALYZE and add indexes as needed |
| golive | Briefly swap: move the live tables aside and promote the replay tables into the view schema |
| abort | DROP SCHEMA replay_* CASCADE |
CLI: schema stages only
The CLI drives the schema side of a rebuild:
go run ./cmd/go-sequent migrate -dsn "$GO_SEQUENT_PG_DSN"
go run ./cmd/go-sequent replay -dsn "$GO_SEQUENT_PG_DSN" \
-projector balances -stage prepare -tables account_balances
# then, as needed: -stage optimize | golive | abort
The CLI accepts the stages prepare, optimize, golive and abort. It cannot stream events, because it does not know your projector registrations. The replay and catchup stages must run from your own application binary, with the pipeline above. See Migrations and CLI.
Operational tips
- Size
BatchSizefor your event volume. Large batches mean fewer round trips and longer transactions. - During
golive, pause writers or serialize them briefly if your swap is not lock-free. - After
golive, keepSyncInTxnprojectors as the source of truth for balances. - Track progress through
projector_replay_statesor your ownStateStore. - If something looks wrong before
golive, runabort. Live tables have not been touched yet.
Related
Docs track the go-sequent library. When APIs drift, the source wins.