Runtime configuration (:runtime)

The runtime.* section of application.yaml — HTTP server, metrics, info/config endpoints, health checks — plus logging levels and Kafka client passthrough.

The :runtime module reads its operational settings from the runtime.* block of application.yaml: the built-in HTTP server, Micrometer metrics, the /info and /config endpoint visibility, and the broker/Schema-Registry health checks. This page is a task-oriented walkthrough of that block. Two related top-level blocks — logging.* and the Kafka client passthrough under stoatflow.kafka.* — round out what you need to operate a runtime app.

runtime.* is the infrastructure half of the config. The engine half (lanes, commit barriers, state, watermarks) lives under stoatflow.* — see Core configuration. For the conceptual split, read Configuration model.

Where runtime config comes from

StoatFlowRuntime.fromConfig(...) loads application.yaml from the classpath, layers environment variables on top, and starts the HTTP + metrics server before your topology. The runtime.* block is only consulted by the :runtime module — a :core-only application has no HTTP server, no metrics endpoint, and no runtime: block to configure.

Every runtime.* key maps to an environment variable using the same __-separated convention as the engine config: double underscore (__) is a path separator, single underscore is a word boundary (kebab-case). The first segment is the config root, and it must name the block being targeted — for runtime.* keys that root is runtime, so runtime.http.port becomes RUNTIME__HTTP__PORT. (Engine keys under stoatflow.* use the STOATFLOW__ root; logging levels use LOGGING__LEVEL__.) A variable that does not start with one of these three recognised roots is ignored — STOATFLOW__RUNTIME__HTTP__PORT would resolve to the nonexistent path stoatflow.runtime.http.port and silently fail to set the port. Environment variables take precedence over YAML — convenient for per-environment overrides without rebuilding the image.

The full runtime.* shape

Every key shown here is at its default value, so this block is equivalent to omitting runtime: entirely. Trim it down to just the keys you actually change.

runtime:
  http:
    enabled: true        # serve the HTTP admin + metrics server
    host: 0.0.0.0        # bind address (all interfaces)
    port: 8080
    backlog: 50          # max pending socket connections
    debug:
      enabled: true      # register /debug/threads and /debug/barriers

  metrics:
    enabled: true        # expose /metrics in Prometheus format
    prefix: stoatflow    # prefix for all metric names
    recording-level: info  # info | debug | trace
    bind-jvm-metrics: true # JVM memory, GC, threads
    common-tags: {}      # tags applied to every metric

  endpoints:
    info:
      show-app: true
      show-java: true
      show-kafka: true
      show-uptime: true
      show-state: true
      show-watermarks: true
      show-topology: true
      show-endpoints: true
    config:
      enabled: true      # serve the /config endpoint

  health:
    kafka-broker:
      timeout-ms: 2000
    schema-registry:
      timeout-ms: 5000

HTTP server (runtime.http)

The runtime starts a JDK built-in HTTP server on a virtual-thread executor. It serves health probes, metrics, topology introspection, and the pause/unpause controls. See REST API for the full endpoint catalogue.

KeyDefaultPurpose
runtime.http.enabledtrueSet false to run with no HTTP server at all. You lose health probes, /metrics, and the admin endpoints — only do this for an embedded/library use case.
runtime.http.host0.0.0.0Bind address. 0.0.0.0 binds all interfaces (the right choice inside a container). Use 127.0.0.1 to restrict to loopback.
runtime.http.port8080Listen port.
runtime.http.backlog50Maximum pending connections in the socket backlog.
runtime.http.debug.enabledtrueRegisters /debug/threads and /debug/barriers. When false, both return 404. Disable to reduce attack surface on hardened deployments — there is no hot-path cost either way.

A typical production override binds a fixed port and turns the debug endpoints off:

runtime:
  http:
    port: 8080
    debug:
      enabled: false
/debug/threads and /debug/barriers are pull-only snapshots used to diagnose a stuck commit pipeline. They are safe to leave on, but if your threat model limits what the admin port exposes, gating them with runtime.http.debug.enabled: false is the supported way to remove them. See REST API.

Metrics (runtime.metrics)

Metrics are collected with Micrometer and exposed at /metrics in Prometheus text format. Scrape it from your existing monitoring stack — there is no agent to install. For the metric catalogue, see Metrics.

KeyDefaultPurpose
runtime.metrics.enabledtrueMaster switch for metric collection and the /metrics endpoint.
runtime.metrics.prefixstoatflowPrefix applied to every metric name. Change it if your conventions require a different namespace.
runtime.metrics.recording-levelinfoDetail level: info (essential operational metrics, production-safe), debug (higher-cardinality troubleshooting metrics), trace (deep internals, development only).
runtime.metrics.bind-jvm-metricstrueBinds JVM memory, GC, and thread metrics into the registry.
runtime.metrics.common-tags{}A map of tags applied to every metric — useful for environment, region, or service identification.

Common tags are how you keep one Prometheus/Grafana setup readable across many deployments:

runtime:
  metrics:
    prefix: stoatflow
    recording-level: info
    common-tags:
      env: production
      region: eu-west-1
      service: order-processor

Endpoint visibility (runtime.endpoints)

This block controls what the human-facing /info endpoint discloses and whether /config is served. It does not affect health, metrics, or topology endpoints.

/info fields

runtime.endpoints.info.* are individual booleans (all true by default) that include or omit a section from the /info JSON response:

KeyIncludes
show-appApplication id
show-javaJava runtime version and vendor
show-kafkaBootstrap servers
show-uptimeProcess uptime
show-stateStoatFlow application state with transition history
show-watermarksGlobal and per-partition watermark state
show-topologyTopology traits and active optimizations
show-endpointsThe list of available HTTP endpoints

/config endpoint

KeyDefaultPurpose
runtime.endpoints.config.enabledtrueServes the /config endpoint, which returns the merged effective configuration with sensitive values masked. Supports JSON and YAML via content negotiation.

To trim what an exposed admin port reveals — for example, hide the bootstrap servers from /info and turn off the config dump entirely:

runtime:
  endpoints:
    info:
      show-kafka: false
    config:
      enabled: false

Health checks (runtime.health)

The readiness and liveness probes aggregate a set of health indicators. Two of them have configurable timeouts here. See Health checks for how the indicators map to /health/live and /health/ready.

KeyDefaultPurpose
runtime.health.kafka-broker.timeout-ms2000Timeout for the broker connectivity check (via AdminClient).
runtime.health.schema-registry.timeout-ms5000Timeout for the Schema Registry connectivity check. This indicator auto-enables only when stoatflow.schema-registry-url is set.
runtime:
  health:
    kafka-broker:
      timeout-ms: 3000
    schema-registry:
      timeout-ms: 5000

Logging levels (logging.level)

logging.level is a top-level block (a sibling of stoatflow and runtime, not nested under either). It maps logger names to levels and applies them to Logback at startup, overriding whatever logback.xml set. Use ROOT for the root logger.

logging:
  level:
    ROOT: INFO
    io.stoatflow: DEBUG
    org.apache.kafka: WARN
    org.apache.kafka.clients.consumer: INFO

Valid levels are TRACE, DEBUG, INFO, WARN, ERROR, and OFF. Per-logger levels can also be set via environment variables with the LOGGING__LEVEL__ prefix — for example LOGGING__LEVEL__ORG_APACHE_KAFKA_CLIENTS=DEBUG sets org.apache.kafka.clients to DEBUG. The single-underscore segments become dots in the logger name. Environment variables take precedence over YAML when both name the same logger.

Kafka client passthrough (stoatflow.kafka)

Kafka client tuning lives under stoatflow.kafka.* (the engine half), not under runtime.* — but it is part of operating a runtime app, so it is worth knowing where it is. The three maps pass properties straight through to the underlying Kafka clients, applied on top of StoatFlow's framework defaults:

stoatflow:
  kafka:
    consumer:
      max.poll.records: 1000
      fetch.min.bytes: 65536
    producer:
      compression.type: lz4
      linger.ms: 50
    restoration-consumer:
      max.poll.records: 5000

A few forced overrides (for example bootstrap.servers, group.id, enable.auto.commit=false, and the transactional settings under exactly-once) cannot be overridden here — they are required for correctness. The full resolution order and the list of forced values are on Kafka client configuration.

These maps preserve dotted Kafka property names verbatim (linger.ms, max.poll.records). When setting them via environment variables, use the dedicated STOATFLOW__KAFKA__PRODUCER__* / STOATFLOW__KAFKA__CONSUMER__* form (e.g. STOATFLOW__KAFKA__PRODUCER__LINGER_MS=50) — the generic env path would mangle the dotted keys. Details on Kafka client configuration.

License (stoatflow.license)

The license block is also under stoatflow.*, not runtime.*, but the :runtime module bridges it to the engine and exposes license state via the /license endpoint and the license health indicator. The minimal form references the key from an environment variable:

stoatflow:
  license:
    key: ${STOATFLOW_LICENSE_KEY}
    environment: prod          # required for the Production tier
    cache-dir: /var/lib/stoatflow/state/license-cache

The full set of license keys, environment variables, and system properties — plus the production-tier requirements — is documented on License configuration.

Worked example

A production-leaning runtime + logging block: fixed port, debug endpoints off, environment tags on every metric, and a quieter Kafka client logger.

runtime:
  http:
    host: 0.0.0.0
    port: 8080
    debug:
      enabled: false
  metrics:
    enabled: true
    recording-level: info
    common-tags:
      env: production
      region: eu-west-1
  endpoints:
    config:
      enabled: false
  health:
    kafka-broker:
      timeout-ms: 3000

logging:
  level:
    io.stoatflow: INFO
    org.apache.kafka: WARN

Next steps