Skip to content

Application properties

Keep configuration out of business code so development, tests and production can use different values. ApplicationProperties reads them through one shared path, including environment overrides and encrypted secrets.

For example, define the number of items on a page in application.properties:

page.size=20

Read it where the application needs that setting:

int pageSize = ApplicationProperties.getIntegerProperty("page.size", 20);

Override it for one deployment with the environment variable PAGE_SIZE=50. Use the same property API in every environment; it resolves the appropriate source. Other typed helpers include getProperty for text and getBooleanProperty for flags.

Properties are resolved in the following order of precedence:

  1. EnvironmentVariablesSource – e.g. export MY_SETTING=value
  2. SystemPropertiesSource – e.g. -Dmy.setting=value
  3. FluxzeroAdditionalPropertiesSource – locations configured with FLUXZERO_CONFIG_LOCATIONS
  4. ApplicationEnvironmentPropertiesSource – e.g. application-dev.properties
  5. ApplicationPropertiesSource – base fallback (application.properties)
  6. FluxzeroPropertiesSource – SDK defaults (fluxzero.properties or fluxzero.json)
  7. (Optional): Spring’s Environment is added as a fallback source if Spring is active

ApplicationPropertiesSource merges every application.properties resource visible on the application classpath. A shared module can therefore own common defaults once; each executable that depends on that module inherits them. Do not repeat the same key with different values across modules: the SDK logs a warning because class-loader ordering would make that value ambiguous. Put intentional overrides in an environment variable, system property, environment-specific file, or another higher-priority source. Spring Boot nested JARs remain separate classpath resources and are discovered automatically. A custom uber-JAR build that collapses equal resource names must merge overlapping application.properties files in its own packaging configuration.

To specify the environment (dev, prod, etc.), define:

Terminal window
export ENVIRONMENT=dev

This allows application-dev.properties to override base properties.

SDK-loaded property files accept both regular property names and their conventional environment-variable aliases. For example, FLUXZERO_AUTH_OIDC_LOGIN_STATE_SECRET can be resolved with ApplicationProperties.getProperty("fluxzero.auth.oidc.login-state-secret"). When both forms occur in the same source, the exact property name takes priority.


For class or package renames in stored data, configure fluxzero.serialization.typeAliases (FLUXZERO_SERIALIZATION_TYPE_ALIASES). See Type aliases for the syntax and examples.


fluxzero.model.graph.strict (FLUXZERO_MODEL_GRAPH_STRICT) defaults to false. Historical Graphs normally use current DOCUMENT-only values when the historical document revision is unavailable, while retaining historical relationships and proven absence. Set it to true for exact historical reads, or use graph.strict(true) for one view. graph.strict(false) restores ordinary reads for that view. This property is independent of fluxzero.defaults.version; assertions, applies and replay remain strict. See Temporal Graphs.

fluxzero.defaults.version lets new applications opt into newer SDK defaults while existing applications keep compatibility behavior when the property is absent. Use yyyy.MM.dd values. Each version includes the defaults from earlier versions, and each behavior can still be overridden with its dedicated property.

For example:

fluxzero.defaults.version=2026.09.10

The table below lists the changes selected by each threshold. An explicit feature property takes precedence.

Proxy HTTP/2 response headers default to a 16 KiB maximum independently of the defaults date. Override it with fluxzero.proxy.http2MaxResponseHeaderSize (FLUXZERO_PROXY_HTTP2_MAX_RESPONSE_HEADER_SIZE); HTTP/1 and incoming header limits are unaffected.

Defaults versionEquivalent propertyWhat changes
>= 2026.05.20fluxzero.tracking.unconfiguredHandlerConsumerMode = perHandlerHandlers without an explicit @Consumer or matching custom ConsumerConfiguration get their own generated default consumer per handler class, instead of sharing one application default consumer per message type. This isolates tracking positions and handler failures for unconfigured handlers.
>= 2026.05.21fluxzero.scheduling.periodic.useDefaultInitialDelay = true@Periodic annotations that omit initialDelay use the schedule’s natural first deadline: fixed-delay schedules first run after delay, and cron schedules first run at the next cron match. Set initialDelay = 0 to request an immediate first run.
>= 2026.07.27fluxzero.tracking.unconfiguredHandlerConsumerMode = perPackageUnconfigured handlers share one generated consumer per exact handler package and message type. Explicit consumers and matching custom configurations remain more specific.
>= 2026.09.09fluxzero.websocket.reconnectBackoff.enabled = trueWebSocket reconnect attempts use equal jitter over a capped exponential delay instead of a fixed one-second interval. Set the dedicated property to false to retain fixed retries.
>= 2026.09.10fluxzero.eventsourcing.maxFetchBytes = 104857600Aggregate-history pages request at most 100 MiB of serialized event payload. Set the dedicated property to 0 to retain count-only pages.
>= 2026.10.04fluxzero.interceptApply.assertCurrent = trueValidating operations check the current input before each selected interceptor. Annotation ENABLED/DISABLED overrides the property; set false to retain replacement-only checks.
>= 2026.10.09fluxzero.search.collectionValues = trueAnnotation-independent range and field sorting semantics. Upgrade the Runtime and prepare indexed collections before opting in; set false to retain legacy behavior. See collection values.
>= 2026.10.18fluxzero.model.aliasTargets = trueModel commands distinguish primary-ID properties from alias properties. Activate after SDK and Runtime support identity selection; set false for compatibility selection. See alias targets.

The dedicated search override uses environment variable FLUXZERO_SEARCH_COLLECTION_VALUES. It wins in both directions: true enables the profile on older defaults, and false retains compatibility behavior on newer defaults.

Settings that are independent of this date, such as delivery guarantees and Model conflict policy, are described in their own guides.


Fluxzero supports secure storage of secrets using its built-in encryption utility. To use encryption:

  1. Generate a new key with:

    String key = DefaultEncryption.generateNewEncryptionKey();
    System.out.println(key);
    // => ChaCha20|KJh832h1f7shDFb... -> Save and use as ENCRYPTION_KEY
  2. Set the encryption key via an environment variable or system property:

    Terminal window
    export ENCRYPTION_KEY='ChaCha20|KJh832h1f7shDFb...'
  3. Encrypt values at build/deploy time:

    String encrypted = ApplicationProperties.encryptValue("secret-google-key");
    System.out.println(encrypted);
    // => encrypted|ChaCha20|mm8yeY8TXtNpdrwO:REdej56zvFXc:b7oQdmnpQpUzagKtma9JLQ==
  4. Add encrypted values to your config:

    google.apikey=encrypted|ChaCha20|mm8yeY8TXtNpdrwO:REdej56zvFXc:b7oQdmnpQpUzagKtma9JLQ==
  5. Resolve them normally in code:

    String apiKey = ApplicationProperties.getProperty("google.apikey");
    // -> "secret-google-key"

Decryption is transparent. Fluxzero detects encrypted values and decrypts them automatically.


Properties can be defined in your test/resources/application.properties or overridden via system properties:

Terminal window
-Dmy.test.override=true

Or dynamically inject mock values:

TestFixture.create(MyHandler.class)
.withProperty("my.test.value", "stub")
.whenCommand("/users/create-job.json")
.expectSchedules(ScheduledJob.class);

© 2026 Fluxzero