Configuration properties

All framework properties live under the spring.ddd.* namespace and are bound automatically via Spring Boot @ConfigurationProperties. Sensible defaults are chosen so most applications run without any explicit configuration. All duration properties accept ISO-8601 duration strings (e.g. PT1S, PT30S, PT1M).

Event Sourcing

Prefix: spring.ddd.eventsourcing

These properties are shared across EventSourcingProperties (core runtime) and EventSourcingJdbcProperties (JDBC-specific), both bound under the same prefix.

Property Type Default Notes

enabled

Boolean

true

Master switch for the event-sourcing infrastructure.

validation.enabled

Boolean

true

Run bean validation on an aggregate before persisting it.

snapshot.enabled

Boolean

true

Enable snapshot creation to avoid replaying the full event stream.

snapshot.threshold

Long

100

Number of events after which a new snapshot is created.

batch-size

Int

100

Maximum number of aggregates fetched per round-trip when bulk-loading via findAllById. Caps bind-parameter count for dialect safety; large id lists are split into batches of this size. @Min(1).

dialect

DialectType

AUTO

SQL dialect for the JDBC event and snapshot stores. AUTO detects the dialect from the DataSource at startup. Values: AUTO, POSTGRES, MYSQL, MARIADB, H2, HSQLDB, SQLSERVER.

schema.auto

Boolean

true

Apply the event-store and snapshot DDL scripts on startup. Idempotent — safe against an existing schema. Set to false when using Flyway or Liquibase.

base-packages

List<String>

[]

Base packages scanned for @EventSourced aggregates. Empty (default) uses the Spring Boot application’s package tree. Set this when aggregates live outside that tree.

Partitioning

Prefix: spring.ddd.partitioning

This namespace configures the partition coordination substrate shared by CQRS and event sourcing, not an event-sourcing-only concern: it applies equally to a partitioned @Partitioned projection in an application with no event store at all.

Not every property in this namespace reaches every consumer of it: partitions, polling., instance., rebalance-interval and graceful-shutdown-timeout are module-agnostic — bound by PartitioningProperties in spring-ddd-messaging, so they apply the same way whether or not JDBC coordination storage is on the classpath. enabled, dialect and schema.auto are bound by PartitionCoordinationProperties in spring-ddd-messaging-jdbc and reach only the JDBC half of the substrate: they decide whether the JDBC coordination tables and beans exist at all, not how partitioning behaves once they do.

Property Type Default Notes

enabled

Boolean

true

Whether the JDBC partition coordination substrate is active. Set to false to skip the coordination tables and the PartitionCoordinatorManager for a consumer that never uses @Partitioned projections or partitioned event-store consumption.

dialect

CoordinationDialectType

AUTO

Storage dialect for the coordination tables (PARTITION_MEMBER, PARTITION_OWNERSHIP, PARTITION_SOURCE_CURSOR). AUTO detects the dialect from the DataSource at startup; set it explicitly when the database product name is not recognised. Values: AUTO, POSTGRES, MYSQL, MARIADB, H2, HSQLDB, SQLSERVER.

schema.auto

Boolean

true

Apply the coordination tables' DDL script on startup. Idempotent — safe against an existing schema. Set to false when using Flyway or Liquibase.

partitions

Int

256

Fixed partition count for the event store; valid values are powers of two 1, 2, 4, …​, 32768; 1 means a single partition (no partitioning); immutable once initialized. Keep it well above the number of instances you run - the default 256 is comfortable for any realistic cluster. Ownership is drawn per bucket, so a count near your instance count splits the load visibly unevenly, and at a handful of buckets an instance can draw none of them and idle.

polling.batch-size

Int

1000

Max events read from one owned partition per poll page; bounds the poll batch. Must be at least 1.

polling.interval

Duration

PT1S

Polling cadence for partitioned event consumption.

instance.id

String

host/pod name

Stable, unique id for this process within a consumer’s set of instances. Defaults to the OS host name (falling back to a random id if unresolvable); set it explicitly when the host name is not stable or not unique, for example behind an orchestrator that recycles pod names. Must not be blank when set.

instance.heartbeat-interval

Duration

PT5S

How often an instance renews its liveness row. Must be shorter than instance.stale-timeout.

instance.stale-timeout

Duration

PT30S

An instance is considered dead once its last heartbeat is older than this, measured by the database clock. Also the ownership-lease duration.

rebalance-interval

Duration

PT10S

How often an instance re-evaluates partition ownership across the live member set. Must be shorter than instance.stale-timeout.

graceful-shutdown-timeout

Duration

PT15S

Drain window an instance allows in-flight work before deregistering its membership and releasing its owned partitions on shutdown.

All five durations must be positive. instance.heartbeat-interval must be shorter than instance.stale-timeout, and rebalance-interval must be shorter than instance.stale-timeout — both keep an instance from being declared stale, or a rebalance from being skipped, before it has had a fair chance to renew.

CQRS commands & queries

Prefix: spring.ddd.cqrs

Property Type Default Notes

enabled

Boolean

true

Master switch for the CQRS infrastructure (commands, queries, projections).

command.enabled

Boolean

true

Enable the command pipeline (CommandBus and @CommandHandler dispatch).

query.enabled

Boolean

true

Enable the query pipeline (QueryBus and @QueryHandler dispatch).

Projections

Prefix: spring.ddd.cqrs.projection

The properties below tune the one shared executor that every projection draws from. A given projection’s own apply-concurrency cap is a separate, per-projection knob — the concurrency attribute on @JsonProjection / @JpaProjection / @InMemoryProjection (default 0 = uncapped), overridable per environment under overrides.<name>.concurrency (see Scaling overrides) — see Scaling projections.

Property Type Default Notes

executor.concurrency-limit

Int

available processors

Worker threads in the shared keyed executor that partitions projection work by read-model id (same id serial, different ids parallel). @Min(1).

optimistic-lock.retry.max-attempts

Int

3

Maximum attempts a projection makes to apply an event when it loses optimistic-lock races with a concurrent dispatcher. Each retry re-reads the row in a fresh transaction.

optimistic-lock.retry.delay

Duration

PT0.05S

Base wait (full-jitter random in [0, value]) between optimistic-lock retries. Set to PT0S to retry immediately.

default-on-error

OnError

HALT

Application-wide error policy for persistent projections that do not declare their own policy. Must be HALT or SKIP; INHERIT is rejected at startup. Not applied to @InMemoryProjection (always HALT).

executor.queue-capacity

Int

1024

Per-worker bounded queue capacity for the projection keyed executor. @Min(1).

in-memory.max-read-models

Int

0

Per-projection cap on the number of in-memory read models. 0 (the default) means unbounded; any positive value caps the count. @Min(0); exceeding a positive bound halts the projection.

Projection consumer

Prefix: spring.ddd.cqrs.projection.consumer

Validation: polling.interval must be positive and strictly less than lease-ttl; lease-ttl must be at least 1 second (sub-second values truncate to zero in SQL and cause instant lease expiry).

Property Type Default Notes

polling.interval

Duration

PT1S

Wake/poll cadence. The consumer also wakes on an after-commit signal. Must be positive and < lease-ttl.

polling.batch-size

Int

1000

Maximum source-position window scanned per pass. @Min(1).

lease-ttl

Duration

PT1M

Single-consumer lease TTL; failover latency is approximately this value. Must be >= PT1S.

max-in-flight

Int

256

Maximum log positions the catch-up consumer dispatches ahead of the durable checkpoint before awaiting completions. Smaller values reduce crash re-work; larger values allow more parallelism slack. @Min(1).

retry.max-attempts

Int

3

Total attempts (1 initial + retries) to apply a single event before the per-projection error policy fires. @Min(1).

retry.delay

Duration

PT0.1S

Base backoff before the first apply retry. Must be positive.

retry.delay-multiplier

Double

1.0

Exponential growth factor applied between apply retries. 1.0 means fixed delay. Must be >= 1.0.

retry.max-delay

Duration

PT5S

Upper bound on the (multiplied) apply-retry backoff. Must be >= retry.delay.

stall-warn-interval

Duration

PT30S

How long a catch-up apply may block the consumer (awaiting keyed-executor capacity or a drain barrier) before a liveness warning is logged. Diagnostic only — the consumer keeps waiting. Must be positive.

Projection high-water-mark

Prefix: spring.ddd.cqrs.projection.high-water-mark

Validation: polling.interval must be positive and strictly less than lease-ttl; lease-ttl must be at least 1 second.

Property Type Default Notes

polling.interval

Duration

PT1S

Detector poll cadence. Must be positive.

polling.batch-size

Int

1000

Maximum positions read per poll (bounds catch-up batch size). @Min(1).

lease-ttl

Duration

PT1M

Single-writer lease TTL; failover latency is approximately this value. Must be >= PT1S.

Cascade rebuild

Prefix: spring.ddd.cqrs.projection.cascade-rebuild

This same polling.interval also paces the in-place rebuild driver for @Partitioned projections - the two pollers share one poll-cadence knob rather than each exposing its own.

Property Type Default Notes

polling.interval

Duration

PT1S

Idle wait between driver ticks that advance in-progress projection rebuilds gated on upstream completion (both the cascade-rebuild driver and the @Partitioned in-place rebuild driver). Must be positive.

upstream-hwm-stall-warn-interval

Duration

PT30S

How long a persistent, event-sourced upstream may stall below its high-water mark before a blocked downstream rebuild logs a stall warning. Must be positive.

upstream-hwm-wait-timeout

Duration

PT2M

Hard ceiling after which a downstream rebuild HALTs if its persistent, event-sourced upstream stays stalled below the high-water mark. Must be positive and greater than upstream-hwm-stall-warn-interval.

Scaling overrides

Prefix: spring.ddd.cqrs.projection.overrides

Per-environment overrides of a projection’s two independent scaling levers — its apply-concurrency cap and its @Partitioned opt-in — keyed by the projection’s storage name (overrides.<name>.*). Every field defers to the projection’s annotation when unset — see Scaling projections.

Property Type Notes

overrides.<name>.concurrency

Int

Overrides the projection annotation’s concurrency attribute (@JsonProjection / @JpaProjection / @InMemoryProjection) — the per-instance cap on aggregate ids applied in parallel. Unset defers to the annotation. 0 explicitly relaxes this projection to uncapped for this environment, even if the annotation sets a cap; >= 1 caps it. @Min(0) when set.

overrides.<name>.partitioned.enabled

Boolean

Overrides whether partitioned (cross-instance) consumption is active for this projection. Unset defers to the annotation (enabled whenever @Partitioned is present).

Projection store

Prefix: spring.ddd.cqrs.projection.jdbc.store

This prefix configures the shared relational persistence layer (SQL dialect, bookkeeping tables) that all projection-store implementations use. It has no dedicated enabled flag; the shared beans are contributed by whichever durable projection store is enabled (spring.ddd.cqrs.projection.json.enabled / spring.ddd.cqrs.projection.jpa.enabled), and shared via @ConditionalOnMissingBean when both are active.

Property Type Default Notes

dialect

ProjectionDialectType

AUTO

Database dialect for projection-store SQL. AUTO detects from the DataSource. Values: AUTO, POSTGRES, MYSQL, MARIADB, H2, HSQLDB, SQLSERVER.

table-creation

TableCreation

AUTO

Whether to create missing projection-store bookkeeping tables on startup. AUTO creates them if absent; NONE skips DDL entirely (use when managing the schema externally). Values: AUTO or NONE.

replay-lease-ttl

Duration

PT1M

Lease TTL for an in-progress replay; renewed at half the duration.

read-model-metadata-table-name

String

READ_MODEL_METADATA

Name of the read-model sidecar table. Override to match an existing schema.

JSON projection store

Prefix: spring.ddd.cqrs.projection.json

Configures the JSON-over-JDBC projection store (@JsonProjection).

Property Type Default Notes

enabled

Boolean

true

Enable the @JsonProjection store auto-configuration.

default-read-model-table-name

String

PROJECTION_STORE

Shared table for @JsonProjection beans that do not specify an explicit table attribute.

table-creation

TableCreation

AUTO

Whether to create the JSON read-model tables (default-read-model-table-name and dedicated @QueryField tables) on startup. Independent of the bookkeeping tables (spring.ddd.cqrs.projection.jdbc.store.table-creation). Values: AUTO or NONE.

CQRS JPA

Prefix: spring.ddd.cqrs.jpa

Property Type Default Notes

enabled

Boolean

true

Enable the JPA aggregate command-handler infrastructure. The @JpaProjection store is a separate concern, gated independently by spring.ddd.cqrs.projection.jpa.enabled.

JPA projection store

Prefix: spring.ddd.cqrs.projection.jpa

Property Type Default Notes

enabled

Boolean

true

Enable the @JpaProjection store (the JpaProjectionStoreFactory and its shared JDBC bookkeeping). Independent of spring.ddd.cqrs.jpa.enabled, which gates the JPA aggregate command handlers.

CQRS–Event Sourcing bridge

Prefix: spring.ddd.cqrs.eventsourcing

Property Type Default Notes

enabled

Boolean

true

Enable the bridge that feeds committed events from the event store into the projection pipeline.

Projection actuator

Prefix: spring.ddd.cqrs.projection.actuator

Property Type Default Notes

lag-threshold

Long?

unset

Optional lag threshold (in event positions). When set, a projection whose lag exceeds this value drives the health indicator DOWN. When unset, lag never affects health — operators alert on the cqrs.projection.lag metric instead. Must be @Positive when set.

Saga

Prefix: spring.ddd.saga

Property Type Default Notes

enabled

Boolean

true

Master switch for the saga runtime.

table-name

String

SAGA_INSTANCE

Table holding persisted saga instances. Must match the pattern [A-Za-z_][A-Za-z0-9_]* (a valid SQL identifier). Overridable per saga type via @SagaTable.

schema.auto

Boolean

true

Apply the saga instance table DDL on startup. Set to false when managing the schema externally.

Saga deadlines

Prefix: spring.ddd.saga.deadline

Validation: both polling.interval and leaseTtl must be positive, and leaseTtl must strictly exceed polling.interval.

Property Type Default Notes

enabled

Boolean

true

Enable the deadline poller.

polling.interval

Duration

PT30S

How often the single-active poller sweeps for due deadlines. Must be positive and < lease-ttl.

lease-ttl

Duration

PT2M

How long an acquired sweep lease is held. Must be positive and strictly exceed polling.interval.

polling.batch-size

Int

100

Maximum number of due deadlines fetched per sweep. @Min(1).

table-name

String

SAGA_DEADLINE

The deadline table. Must be a valid SQL identifier.

lock-table-name

String

SAGA_DEADLINE_LOCK

The sweep-lock table used for single-active leader election. Must be a valid SQL identifier.

schema.auto

Boolean

true

Apply the deadline and deadline-lock table DDL on startup.

Saga inbound

Prefix: spring.ddd.saga.inbound

Validation: both polling.interval and leaseTtl must be positive, and leaseTtl must strictly exceed polling.interval; dispatchTimeout must be positive.

Property Type Default Notes

enabled

Boolean

true

Master switch for the ordered-inbound consumer. The bridge also gates on EventStore presence.

table-name

String

SAGA_INBOUND_CHECKPOINT

Table holding per-saga-type inbound checkpoints and leases. Must be a valid SQL identifier.

polling.interval

Duration

PT1S

How often the consumer wakes to check for new positions. Must be positive and < lease-ttl.

lease-ttl

Duration

PT1M

How long an acquired inbound lease is held. Must be positive and strictly exceed polling.interval.

polling.batch-size

Int

100

Maximum positions fetched per pass. Must be positive (@Positive).

dispatch-timeout

Duration

PT60S

Upper bound the consumer waits for a single record’s work to complete on the shared keyed executor before aborting the pass (the checkpoint stays unadvanced and the record is retried on the next poll). A liveness backstop against a permanently-wedged keyed task; set it well above the slowest legitimate handler-plus-transaction. Must be positive.

schema.auto

Boolean

true

Apply the inbound-checkpoint table DDL on startup.

Saga retention

Prefix: spring.ddd.saga.retention

Deletes completed sagas whose completion is older than a configurable age. See Saga Retention for the guide.

Validation: polling.cron and polling.interval cannot both be set while enabled is true; lease-ttl must be positive and, on the interval path, strictly exceed the effective poll interval; max-age (global and per override) must be positive; polling.cron must be -, blank, or a valid cron expression; polling.batch-size must be between 1 and 1000.

Property Type Default Notes

enabled

Boolean

false

Master switch for the retention sweeper.

max-age

Duration

P30D

Delete completed sagas whose completion is older than this. Must be positive.

polling.interval

Duration

(unset)

Fixed-delay sweep cadence. Mutually exclusive with polling.cron. When neither is set, retention sweeps hourly.

polling.cron

String

-

Spring 6-field cron expression driving the sweep. - or empty disables cron. Mutually exclusive with polling.interval.

lease-ttl

Duration

PT2H

How long an acquired sweep lease is held. On the interval path it must exceed the effective poll interval; on the cron path it must be positive.

polling.batch-size

Int

100

Maximum rows deleted per statement; the sweep drains in batches of this size. Must be 11000 — the delete binds one parameter per row, kept under SQL Server’s 2100-parameter statement limit.

overrides.<saga-type>.enabled

Boolean

(inherits)

Opt a saga type in or out, keyed by @Saga(type). Falls back to the global switch. Retention runs only when the global enabled is true, so a per-type override is effective for opting a type out — it cannot enable retention on its own.

overrides.<saga-type>.max-age

Duration

(inherits)

Per-type retention window. Falls back to the global max-age.

Routing

Prefix: spring.ddd.routing

Map-typed properties are keyed by user-chosen names (rulesets, destinations) or by a message’s canonical name (commands, queries) — <namespace>.<name> of its @Command/@Query, falling back to the fully-qualified class name when it declares no namespaced name; see Routing.

Property Type Default Notes

rulesets.<name>.enabled

Boolean

true

Gates the @Router("<name>") bean carrying this ruleset; active unless explicitly disabled.

destinations.<name>.transport

String

Transport id for the named destination. Must match a registered CommandDispatcher/QueryDispatcher bean; validated eagerly at startup.

destinations.<name>.url

String

null

Transport-specific address for the named destination; interpreted by the matching dispatcher.

commands.<message-name>

String

Static command route: message canonical name (<namespace>.<name> of its @Command, else fully-qualified class name) to destination name.

queries.<message-name>

String

Static query route: message canonical name (<namespace>.<name> of its @Query, else fully-qualified class name) to destination name.

Spring Modulith properties

The following properties are not defined by Spring DDD. They are owned by Spring Modulith and the framework honors them because it integrates with the Modulith event-publication store. Consult the Spring Modulith Integration page and the upstream documentation for their meaning and defaults.

Property Purpose

spring.modulith.events.completion-mode

Whether Modulith marks event publications complete inline (SYNCHRONOUS) or asynchronously.

spring.modulith.events.republish-outstanding-events-on-restart

Replay incomplete event publications on application restart.

spring.modulith.events.externalization.mode

Controls which events are forwarded to an external message broker.

spring.modulith.events.jdbc.schema-initialization.enabled

Create the Modulith event-publication tables on startup.

spring.modulith.events.jdbc.schema

Schema name used for Modulith event-publication tables.