Header menu logo FCQRS

5. Preparing for production

The domain model does not change when the application moves from a laptop to production. The operating environment does. Production readiness means deciding what happens when storage is slow, a projection fails, an external service accepts a request twice, or a node stops during a workflow.

Course position: the earlier chapters established the domain and its recovery rules. This final stage turns those rules into operational decisions. Complete the checklist once without leaving the course, then use Apply and Reference while configuring a real deployment.

1. Put the journal on durable storage

SQLite is suitable for local development and a single-process deployment. A multi-node cluster needs a database reachable by every node. Choose a supported provider, provision it as business-critical data, and test restore procedures. The journal is the source from which aggregate state and read models are recovered.

Back up the journal and snapshot store according to the database provider's guidance. A snapshot only shortens replay; losing snapshots does not lose business history. Losing journal events does.

See Configure the database.

2. Make every projection restart-safe

Commit the read-model update and its offset in the same database transaction whenever they share a store. If a projection writes to a remote index or several databases, use idempotent writes and record enough information to resume safely. “The handler is called again” must be a supported case.

Monitor projection failures and lag. A command may be safely stored while a query remains stale because its projection is stopped. Read-your-writes subscriptions coordinate a caller with a running projection; they do not repair a failed one.

See Add a projection and Read your writes.

3. Design workflows for partial failure

An external service and the saga journal do not share a transaction. The service may accept a request just before the process loses its connection or stops. Retrying can therefore repeat the request.

Motivation: Durable state solves only the part of a failure that happened before the last commit. Production design must make the uncertain work after that boundary observable, repeatable, or safe to resolve manually.

For every external command, decide:

Use the FCQRS correlation id as a tracing link. Use a domain-specific idempotency key when the remote operation needs deduplication.

4. Set snapshot policy from recovery measurements

The default snapshot interval is 30 persisted events. A smaller interval writes snapshots more often and replays fewer events. A larger interval reduces snapshot writes and increases recovery work. Measure recovery for representative large aggregates before changing it.

Snapshots do not replace events, and they do not make an impure fold safe. The recovered result must be the same with or without a snapshot.

5. Configure diagnostics before an incident

Send FCQRS logs through the host's ILoggerFactory and register its ActivitySource names with OpenTelemetry. Confirm that one correlation id connects the initial command, persisted events, saga transitions, follow-up commands, and projection work.

Payload diagnostics are useful in development but may contain personal or secret data. Disable payload rendering in sensitive environments and never put secrets in events unless the journal is designed to store them permanently.

See Observe your system.

6. Move to several nodes only when the single-node system is understood

FCQRS starts a one-node Akka.NET cluster by default. A multi-node deployment requires stable node addresses, seed-node discovery, shared durable storage, compatible message contracts, and operational monitoring for Akka.NET cluster and sharding state. The aggregate and saga definitions remain the same.

Test a rolling deployment with old and new nodes active together. Commands, events, and saga state must serialize across both versions.

7. Rehearse failure

Before release, run these exercises in a non-production environment:

Completion checklist

You are ready to use FCQRS effectively when you can answer these questions for your application:

You have completed the learning path

You can now move through the rest of the documentation without following another fixed order:

For a first real deployment, begin with Configure the database and Observe your system, then return to this completion checklist before release.

Type something to start searching.