This version is still in development and is not considered stable yet. For the latest stable version, please use Korvet 0.19!

Configuration Reference

Complete configuration reference for Korvet.

All korvet properties have sensible defaults. You can override them via application.yml, environment variables (e.g. KORVET_BROKER_PORT), or command-line arguments (e.g. --korvet.broker.port=9092). Unknown korvet properties fail startup (strict binding) — a typo is caught immediately rather than silently ignored.

General

Top-level Korvet runtime settings: namespace and the entry points into each sub-system.

korvet.max-partitions-per-topic

Env var: KORVET_MAX_PARTITIONS_PER_TOPIC · Type: integer · Default: 128

Maximum partitions a single topic may be created with or grown to. Per-partition fan-out (one Redis stream per partition, per-partition stats reads, and the storage worker’s sweep) taxes the shared connection pool, so an absurd count wedges the broker (#1231). Enforced on the admin API, the Kafka CreateTopics path (including validate-only) and alter, and auto-create patterns are validated against it at startup. Raise it if a deployment legitimately runs larger topics.

korvet.namespace

Env var: KORVET_NAMESPACE · Type: string · Default: korvet

Logical namespace applied to all storage and registry state this Korvet instance owns. Must not contain whitespace or the : delimiter — colons are appended internally to compose sub-namespaces.

Admin

HTTP Admin API bootstrap credentials.

korvet.admin.anonymous-prometheus

Env var: KORVET_ADMIN_ANONYMOUS_PROMETHEUS · Type: boolean · Default: false

Serve GET /actuator/prometheus without authentication for scrapers that cannot send credentials. When false (the default), Prometheus must scrape with HTTP Basic admin credentials.

korvet.admin.bootstrap

Env var: KORVET_ADMIN_BOOTSTRAP · Type: boolean · Default: true

Create the default admin credential at startup when it does not already exist.

korvet.admin.first-run-setup-enabled

Env var: KORVET_ADMIN_FIRST_RUN_SETUP_ENABLED · Type: boolean · Default: true

Enable the unauthenticated first-run setup endpoint that creates the first admin user while the admin user store is empty.

korvet.admin.password

Env var: KORVET_ADMIN_PASSWORD · Type: string · Default: admin

Password for the bootstrapped admin credential. Change this before exposing the Admin API.

korvet.admin.security-enabled

Env var: KORVET_ADMIN_SECURITY_ENABLED · Type: boolean · Default: true

When false, the Admin API and UI are served without authentication: the security filter chains permit every request and the SPA skips its login screen. Intended for local, single-user contexts such as korvet demo. Defaults to true.

korvet.admin.username

Env var: KORVET_ADMIN_USERNAME · Type: string · Default: admin

Username for the bootstrapped admin credential.

Jwt

JWT session settings for the Admin API cookie auth.

korvet.admin.jwt.expiry

Env var: KORVET_ADMIN_JWT_EXPIRY · Type: duration · Default: 8h

Lifetime of an admin session JWT. Defaults to 8 hours.

korvet.admin.jwt.secret

Env var: KORVET_ADMIN_JWT_SECRET · Type: string

HMAC-SHA256 signing secret for admin session JWTs. Must be at least 32 characters. If not set, a random key is generated at startup (all sessions are invalidated on restart).

Login Throttle

korvet.admin.login-throttle.initial-lockout

Env var: KORVET_ADMIN_LOGIN_THROTTLE_INITIAL_LOCKOUT · Type: duration · Default: 30s

Lockout applied when the login failure threshold is reached; doubles with each further failure.

korvet.admin.login-throttle.max-failures

Env var: KORVET_ADMIN_LOGIN_THROTTLE_MAX_FAILURES · Type: integer · Default: 10

Consecutive failed logins for a username+IP pair before a lockout starts.

korvet.admin.login-throttle.max-lockout

Env var: KORVET_ADMIN_LOGIN_THROTTLE_MAX_LOCKOUT · Type: duration · Default: 15m

Ceiling for the exponential login lockout. Failure counters also reset after this much time passes without a failed attempt.

Metrics History

korvet.admin.metrics-history.enabled

Env var: KORVET_ADMIN_METRICS_HISTORY_ENABLED · Type: boolean · Default: true

Enable the GET /api/v1/metrics/history series. When disabled, the endpoint returns an empty series; the in-process history store keeps running because per-topic and storage rates read from it.

korvet.admin.metrics-history.interval

Env var: KORVET_ADMIN_METRICS_HISTORY_INTERVAL · Type: duration · Default: 15s

Step of the in-process metrics history store; counters yield per-step rates at this cadence. Defaults to 15 seconds.

korvet.admin.metrics-history.max-series

Env var: KORVET_ADMIN_METRICS_HISTORY_MAX_SERIES · Type: integer · Default: 10000

Cap on the number of per-topic meter series tracked by the in-process metrics history store (cardinality guardrail; per-topic meters multiply, while the topic-free curated meters are a bounded set and always tracked). Once reached, new per-topic series are rejected with a logged warning.

korvet.admin.metrics-history.retention

Env var: KORVET_ADMIN_METRICS_HISTORY_RETENTION · Type: duration · Default: 1h

How much metrics history to retain; capacity is retention divided by interval samples per series. The buffers are in-memory only and do not survive a restart. Defaults to 1 hour.

Oauth

korvet.admin.oauth.audience

Env var: KORVET_ADMIN_OAUTH_AUDIENCE · Type: string

Required id_token audience (aud claim), typically the client ID.

korvet.admin.oauth.client-id

Env var: KORVET_ADMIN_OAUTH_CLIENT_ID · Type: string

OAuth client ID registered at the identity provider for the admin console.

korvet.admin.oauth.client-secret

Env var: KORVET_ADMIN_OAUTH_CLIENT_SECRET · Type: string

OAuth client secret. Leave unset for public clients - the flow uses PKCE and does not require a secret. Set it only for identity providers that demand a confidential client.

korvet.admin.oauth.clock-skew

Env var: KORVET_ADMIN_OAUTH_CLOCK_SKEW · Type: duration · Default: 30s

Tolerated clock skew when checking token expiry and not-before times. Applied at whole-second granularity, rounded up.

korvet.admin.oauth.enabled

Env var: KORVET_ADMIN_OAUTH_ENABLED · Type: boolean · Default: false

Enable OIDC single sign-on for the admin console. Requires issuer-uri, client-id, audience, and a role mapping.

korvet.admin.oauth.issuer-uri

Env var: KORVET_ADMIN_OAUTH_ISSUER_URI · Type: string

Expected id_token issuer (iss claim). Also used to resolve the IdP’s authorization, token, and JWKS endpoints from the OIDC discovery document. Resolution is lazy, so startup does not depend on IdP availability.

korvet.admin.oauth.jwks-uri

Env var: KORVET_ADMIN_OAUTH_JWKS_URI · Type: string

JWKS endpoint override. When unset, the endpoint is discovered from <issuer-uri>/.well-known/openid-configuration.

korvet.admin.oauth.provider-name

Env var: KORVET_ADMIN_OAUTH_PROVIDER_NAME · Type: string · Default: SSO

Identity provider display name shown on the login page’s single sign-on button.

korvet.admin.oauth.redirect-uri

Env var: KORVET_ADMIN_OAUTH_REDIRECT_URI · Type: string

Redirect URI registered at the identity provider for the console callback. When unset, it is derived from the incoming login request as <scheme>://<host>/api/v1/auth/oidc/callback.

korvet.admin.oauth.scopes

Env var: KORVET_ADMIN_OAUTH_SCOPES · Type: string · Default: openid profile

Scopes requested from the identity provider.

korvet.admin.oauth.username-claim

Env var: KORVET_ADMIN_OAUTH_USERNAME_CLAIM · Type: string · Default: preferred_username

id_token claim used as the console username.

Roles

korvet.admin.oauth.roles.admin-group

Env var: KORVET_ADMIN_OAUTH_ROLES_ADMIN_GROUP · Type: string

Group or role value granting the ADMIN console role.

korvet.admin.oauth.roles.claim

Env var: KORVET_ADMIN_OAUTH_ROLES_CLAIM · Type: string · Default: groups

id_token claim carrying the user’s groups or roles; a JSON array or a single string.

korvet.admin.oauth.roles.viewer-group

Env var: KORVET_ADMIN_OAUTH_ROLES_VIEWER_GROUP · Type: string

Group or role value granting the VIEWER (read-only) console role.

Segment Inspection

korvet.admin.segment-inspection.queue-capacity

Env var: KORVET_ADMIN_SEGMENT_INSPECTION_QUEUE_CAPACITY · Type: integer · Default: 8

Remote segment inspections that may wait for a thread once every thread is busy. Beyond that, requests report the segment without its remote metadata immediately instead of waiting.

korvet.admin.segment-inspection.threads

Env var: KORVET_ADMIN_SEGMENT_INSPECTION_THREADS · Type: integer · Default: 8

Remote segment inspections that may run at once. Threads are started on demand up to this many and released once idle, so it also caps how many threads a remote store that stops responding can occupy.

korvet.admin.segment-inspection.timeout

Env var: KORVET_ADMIN_SEGMENT_INSPECTION_TIMEOUT · Type: duration · Default: 5s

Longest a segment detail request waits for remote segment inspection before reporting the segment without its remote metadata. Raise it for a catalog that legitimately takes longer to plan manifests. Defaults to 5 seconds.

korvet.admin.segment-inspection.ttl

Env var: KORVET_ADMIN_SEGMENT_INSPECTION_TTL · Type: duration · Default: 10s

How long a completed remote segment inspection is reused before the remote store is read again. Any persisted change to the segment invalidates it sooner. Defaults to 10 seconds; zero disables reuse.

Broker

Kafka-wire broker listener and group coordinator: bind address, TLS, request limits, backpressure, and rebalance tuning.

korvet.broker.advertised-host

Env var: KORVET_BROKER_ADVERTISED_HOST · Type: string

Hostname advertised to clients via the Kafka metadata response. Leave unset (null) to fall back to host, or to localhost when host binds to all interfaces (0.0.0.0); blank/whitespace values are rejected.

korvet.broker.advertised-port

Env var: KORVET_BROKER_ADVERTISED_PORT · Type: integer

Port advertised to clients via the Kafka metadata response. Defaults to port when unset.

korvet.broker.boss-threads

Env var: KORVET_BROKER_BOSS_THREADS · Type: integer · Default: 1

Netty boss (accept) thread count.

korvet.broker.cert-file

Env var: KORVET_BROKER_CERT_FILE · Type: file path

PEM-encoded server certificate (or chain). Required when tls=true.

korvet.broker.client-auth-required

Env var: KORVET_BROKER_CLIENT_AUTH_REQUIRED · Type: boolean · Default: false

Require clients to present a certificate (mTLS).

korvet.broker.drain-timeout

Env var: KORVET_BROKER_DRAIN_TIMEOUT · Type: duration · Default: 5s

Bound on how long shutdown waits for in-flight requests to finish once draining has begun. Parked long-poll fetches complete immediately when draining begins, so this only has to cover requests doing real work (produces, admin calls).

korvet.broker.enabled

Env var: KORVET_BROKER_ENABLED · Type: boolean · Default: true

Enable the broker listener.

korvet.broker.fetch-max-wait

Env var: KORVET_BROKER_FETCH_MAX_WAIT · Type: duration · Default: 500ms

Maximum time a fetch request will block waiting for fetch.min.bytes to be satisfied.

korvet.broker.fetch-partition-max-bytes

Env var: KORVET_BROKER_FETCH_PARTITION_MAX_BYTES · Type: data size · Default: 1MB

Default upper bound on per-partition bytes returned by a fetch.

korvet.broker.global-max-pending-bytes

Env var: KORVET_BROKER_GLOBAL_MAX_PENDING_BYTES · Type: data size · Default: 400MB

Broker-wide pending memory budget shared across all connections: suspend admission on every connection once aggregate pending bytes exceed this.

korvet.broker.global-resume-pending-bytes

Env var: KORVET_BROKER_GLOBAL_RESUME_PENDING_BYTES · Type: data size · Default: 200MB

Broker-wide backpressure release threshold: resume admission once aggregate pending bytes drop below this. Must be < globalMaxPendingBytes.

korvet.broker.group-reclaim-min-idle

Env var: KORVET_BROKER_GROUP_RECLAIM_MIN_IDLE · Type: duration · Default: 1m

Minimum time a consumer group’s pending entry must be idle before a fetching member may reclaim it from another consumer (XAUTOCLAIM). Recovers records delivered to a member that died before acknowledging them; values below typical commit cadences risk double delivery to live members.

korvet.broker.host

Env var: KORVET_BROKER_HOST · Type: string · Default: 0.0.0.0

Listener host (interface to bind to).

korvet.broker.id

Env var: KORVET_BROKER_ID · Type: integer · Default: 0

Numeric broker id advertised to Kafka clients. Must be unique across a multi-node deployment.

korvet.broker.in-flight-limit

Env var: KORVET_BROKER_IN_FLIGHT_LIMIT · Type: integer · Default: 500

Per-connection in-flight request limit: on the reactor-netty stack, requests execute concurrently up to this bound while responses are emitted in request order; on the netty stack it caps the in-order response queue (reads pause at the cap, and a connection whose queue reaches twice the cap is closed).

korvet.broker.key-file

Env var: KORVET_BROKER_KEY_FILE · Type: file path

PEM-encoded server private key. Required when tls=true.

korvet.broker.key-password

Env var: KORVET_BROKER_KEY_PASSWORD · Type: secret

Passphrase protecting keyFile, if encrypted.

korvet.broker.listeners

Env var: KORVET_BROKER_LISTENERS · Type: list of Listener

Additional named listeners served alongside the primary listener, so the same broker can advertise different endpoints to different client networks (Kafka’s advertised.listeners): for example an in-network Docker listener plus a port-forwarded localhost listener for host-side clients. Each listener binds its own port and advertises its own endpoint; TLS and SASL settings apply to every listener.

korvet.broker.max-pending-bytes

Env var: KORVET_BROKER_MAX_PENDING_BYTES · Type: data size · Default: 100MB

Backpressure threshold: pause reads from the wire once this many bytes are pending outbound.

korvet.broker.max-request-bytes

Env var: KORVET_BROKER_MAX_REQUEST_BYTES · Type: data size · Default: 100MB

Maximum size of a single inbound Kafka request. Requests larger than this are rejected.

korvet.broker.port

Env var: KORVET_BROKER_PORT · Type: integer · Default: 9092

Listener TCP port.

korvet.broker.produce-timeout

Env var: KORVET_BROKER_PRODUCE_TIMEOUT · Type: duration · Default: 5s

Server-side cap on how long a single partition’s storage write may run before it is surfaced as REQUEST_TIMED_OUT. Because produce responses are sent in request order per connection, a stalled write would otherwise hold the head of the in-order response queue (and every pipelined request behind it) for the client’s full timeoutMs — collapsing throughput on the connection. The effective bound per partition is the smaller of this value and the client-supplied request timeout. Set to zero to disable the server-side cap.

korvet.broker.producer-id-expiration

Env var: KORVET_BROKER_PRODUCER_ID_EXPIRATION · Type: duration · Default: 1d

Idle time after which the dedup state of an idempotent producer is evicted, bounding per-producer memory when producer ids churn (each new connection allocates a fresh id). Evicting an idle producer only means a very late retry is no longer detected as a duplicate, matching Kafka’s producer.id.expiration.ms semantics.

korvet.broker.rebalance-delay

Env var: KORVET_BROKER_REBALANCE_DELAY · Type: duration · Default: 3s

Grace period before triggering a consumer-group rebalance after a member joins or leaves.

korvet.broker.rebalance-threads

Env var: KORVET_BROKER_REBALANCE_THREADS · Type: integer · Default: max(2, available CPU cores)

Scheduler thread-pool size for the group coordinator.

korvet.broker.response-queue-timeout

Env var: KORVET_BROKER_RESPONSE_QUEUE_TIMEOUT · Type: duration · Default: 10s

Upper bound on how long a single request may hold the head of the per-connection, in-order response queue before it is failed with REQUEST_TIMED_OUT. Prevents a request whose handler never completes from stalling every later request on the connection. Fetch requests additionally get their fetchMaxWait long-poll budget on top of this.

korvet.broker.resume-pending-bytes

Env var: KORVET_BROKER_RESUME_PENDING_BYTES · Type: data size · Default: 50MB

Backpressure release threshold: resume reads once pending bytes drop below this. Must be < maxPendingBytes.

korvet.broker.stack

Env var: KORVET_BROKER_STACK · Type: netty, reactor_netty · Default: netty

Transport stack for the Kafka listener: netty (legacy hand-rolled Netty bootstrap with the CompletableFuture pipeline) or reactor-netty (Reactor Netty TcpServer with the reactive pipeline).

korvet.broker.tls

Env var: KORVET_BROKER_TLS · Type: boolean · Default: false

Enable TLS on the listener. When true, certFile and keyFile are required.

korvet.broker.trust-cert-file

Env var: KORVET_BROKER_TRUST_CERT_FILE · Type: file path

PEM-encoded CA trust store for verifying client certificates (mTLS). Required when clientAuthRequired=true.

korvet.broker.worker-threads

Env var: KORVET_BROKER_WORKER_THREADS · Type: integer · Default: 0

Netty worker (IO) thread count. 0 lets Netty pick a default based on CPU count.

Acl

korvet.broker.acl.enabled

Env var: KORVET_BROKER_ACL_ENABLED · Type: boolean · Default: false

Enable topic ACL enforcement. Requires SASL authentication to be enabled.

Metrics

korvet.broker.metrics.group-lag-cardinality-cap

Env var: KORVET_BROKER_METRICS_GROUP_LAG_CARDINALITY_CAP · Type: integer · Default: 1000

Maximum number of consumer groups published as lag gauges. When the live group count exceeds this cap, the publisher marks all lag gauges unknown (NaN) and logs a warning to prevent unbounded time-series cardinality.

korvet.broker.metrics.group-lag-refresh-interval

Env var: KORVET_BROKER_METRICS_GROUP_LAG_REFRESH_INTERVAL · Type: duration · Default: 15s

Interval between refreshes of the sampled per-consumer-group lag gauges (korvet.group.lag).

korvet.broker.metrics.offset-cardinality-cap

Env var: KORVET_BROKER_METRICS_OFFSET_CARDINALITY_CAP · Type: integer · Default: 10000

Maximum number of (topic, partition) pairs published as offset gauges. When the live topic-partition count exceeds this cap, the publisher skips the refresh and logs a warning to prevent unbounded time-series cardinality.

korvet.broker.metrics.offset-refresh-interval

Env var: KORVET_BROKER_METRICS_OFFSET_REFRESH_INTERVAL · Type: duration · Default: 15s

Interval between refreshes of per-topic-partition offset gauges (korvet.broker.max_offset, korvet.broker.log_start_offset).

Sasl

korvet.broker.sasl.enabled

Env var: KORVET_BROKER_SASL_ENABLED · Type: boolean · Default: false

Enable SASL authentication on the listener.

korvet.broker.sasl.mechanisms

Env var: KORVET_BROKER_SASL_MECHANISMS · Type: list of string · Default: SCRAM-SHA-256

SASL mechanisms advertised to clients. Must be a non-empty subset of SUPPORTED. Defaults to SCRAM-SHA-256 only — PLAIN must be opted in explicitly, and OAUTHBEARER requires the korvet.broker.sasl.oauth identity provider settings. Both PLAIN and OAUTHBEARER require TLS.

Gssapi

korvet.broker.sasl.gssapi.keytab-file

Env var: KORVET_BROKER_SASL_GSSAPI_KEYTAB_FILE · Type: file path

Keytab holding the broker principal’s keys.

korvet.broker.sasl.gssapi.principal

Env var: KORVET_BROKER_SASL_GSSAPI_PRINCIPAL · Type: string

Broker Kerberos principal, e.g. kafka/broker1.example.com@EXAMPLE.COM.

korvet.broker.sasl.gssapi.service-name

Env var: KORVET_BROKER_SASL_GSSAPI_SERVICE_NAME · Type: string · Default: kafka

Kerberos service name clients authenticate against; must match the clients' sasl.kerberos.service.name.

Oauth

korvet.broker.sasl.oauth.audience

Env var: KORVET_BROKER_SASL_OAUTH_AUDIENCE · Type: string

Required token audience (aud claim).

korvet.broker.sasl.oauth.clock-skew

Env var: KORVET_BROKER_SASL_OAUTH_CLOCK_SKEW · Type: duration · Default: 30s

Tolerated clock skew when checking token expiry and not-before times. Applied at whole-second granularity, rounded up.

korvet.broker.sasl.oauth.groups-claim

Env var: KORVET_BROKER_SASL_OAUTH_GROUPS_CLAIM · Type: string

Token claim whose values are mapped to group:-prefixed ACL principals. When set, the connection’s ACL policy is the union of the rules granted to the principal claim’s value and to group:<name> for each value of this claim. Unset by default: only the principal claim participates in ACL resolution.

korvet.broker.sasl.oauth.issuer-uri

Env var: KORVET_BROKER_SASL_OAUTH_ISSUER_URI · Type: string

Expected token issuer (iss claim). Also used to resolve the JWKS endpoint from the issuer’s OIDC discovery document when no JWKS URI is configured.

korvet.broker.sasl.oauth.jwks-uri

Env var: KORVET_BROKER_SASL_OAUTH_JWKS_URI · Type: string

JWKS endpoint override. When unset, the endpoint is discovered from <issuer-uri>/.well-known/openid-configuration.

korvet.broker.sasl.oauth.max-reauth

Env var: KORVET_BROKER_SASL_OAUTH_MAX_REAUTH · Type: duration · Default: 5m

Maximum lifetime of an authenticated OAUTHBEARER session before the client must re-authenticate on the same connection (KIP-368). The advertised session lifetime is the smaller of the token expiry and this cap, and sessions that miss the deadline are disconnected. Bounds the window during which IdP-side changes (revoked clients, group membership) remain unseen by the broker.

korvet.broker.sasl.oauth.principal-claim

Env var: KORVET_BROKER_SASL_OAUTH_PRINCIPAL_CLAIM · Type: string · Default: sub

Token claim mapped to the connection principal used for topic ACLs.

korvet.broker.sasl.oauth.tenant-claim

Env var: KORVET_BROKER_SASL_OAUTH_TENANT_CLAIM · Type: string

Token claim carried onto the connection context as the tenant id. Extraction only — no enforcement is attached to it yet (multi-tenancy is tracked in issue #1383).

Mcp

korvet.mcp.enabled

Env var: KORVET_MCP_ENABLED · Type: boolean · Default: false

Whether the MCP endpoint is served. Defaults to false.

korvet.mcp.token

Env var: KORVET_MCP_TOKEN · Type: string

Static bearer token MCP clients must present when admin security is enabled. Ignored when admin security is disabled.

Redis

Primary Redis client used by the broker, registries, and (unless overridden) storage.

korvet.redis.cluster

Env var: KORVET_REDIS_CLUSTER · Type: boolean · Default: false

Treat the target as a Redis Cluster (uses Lettuce RedisClusterClient).

korvet.redis.host

Env var: KORVET_REDIS_HOST · Type: string · Default: localhost

Redis host. Ignored when uri is set.

korvet.redis.io-threads

Env var: KORVET_REDIS_IO_THREADS · Type: integer · Default: available CPU cores

Size of the Lettuce IO (event-loop) thread pool.

korvet.redis.password

Env var: KORVET_REDIS_PASSWORD · Type: secret

Password for AUTH.

korvet.redis.port

Env var: KORVET_REDIS_PORT · Type: integer · Default: 6379

Redis port. Ignored when uri is set.

korvet.redis.timeout

Env var: KORVET_REDIS_TIMEOUT · Type: duration · Default: 1m

Default per-command timeout.

korvet.redis.uri

Env var: KORVET_REDIS_URI · Type: string

Redis URI (redis://…​ or rediss://…​). When set, supersedes host/port/username/password.

korvet.redis.username

Env var: KORVET_REDIS_USERNAME · Type: string

Username for ACL authentication. Leave unset for password-only AUTH.

Circuit Breaker

Fail-fast circuit breaker around Redis stream operations on the primary client.

korvet.redis.circuit-breaker.enabled

Env var: KORVET_REDIS_CIRCUIT_BREAKER_ENABLED · Type: boolean · Default: true

Enable the stream-operation circuit breaker.

korvet.redis.circuit-breaker.log-interval

Env var: KORVET_REDIS_CIRCUIT_BREAKER_LOG_INTERVAL · Type: duration · Default: 30s

Minimum interval between breaker-state log lines (rate-limit for repeated open events).

korvet.redis.circuit-breaker.open-duration

Env var: KORVET_REDIS_CIRCUIT_BREAKER_OPEN_DURATION · Type: duration · Default: 30s

How long the breaker stays open before allowing a probe call.

Metrics

Client-side latency metrics published by Lettuce for the primary Redis client.

korvet.redis.metrics.enabled

Env var: KORVET_REDIS_METRICS_ENABLED · Type: boolean · Default: false

Enable command-latency metrics collection.

korvet.redis.metrics.histogram

Env var: KORVET_REDIS_METRICS_HISTOGRAM · Type: boolean · Default: false

Publish per-command histograms in addition to summary statistics.

korvet.redis.metrics.local-distinction

Env var: KORVET_REDIS_METRICS_LOCAL_DISTINCTION · Type: boolean · Default: false

Split metrics by local (client) socket address — useful in pooled deployments.

korvet.redis.metrics.max-latency

Env var: KORVET_REDIS_METRICS_MAX_LATENCY · Type: duration · Default: 5m

Upper bound used when bucketing latency samples.

korvet.redis.metrics.min-latency

Env var: KORVET_REDIS_METRICS_MIN_LATENCY · Type: duration · Default: 1ms

Lower bound used when bucketing latency samples.

Pool

Connection-pool sizing for the primary Redis client.

korvet.redis.pool.max-wait

Env var: KORVET_REDIS_POOL_MAX_WAIT · Type: duration · Default: 3s

Maximum time a caller will block waiting to borrow a connection from a saturated pool.

korvet.redis.pool.size

Env var: KORVET_REDIS_POOL_SIZE · Type: integer · Default: 32

Maximum number of pooled connections. Each in-flight per-partition produce write holds one connection for its XADD, so size this at least to the sum of partitions across all topics produced to concurrently, plus headroom for the metadata reads that share this pool. Too small a pool queues writes until acquisition times out and produces fail.

Schema Registry

Embedded Confluent-compatible schema-registry HTTP endpoint.

korvet.schema-registry.default-compatibility

Env var: KORVET_SCHEMA_REGISTRY_DEFAULT_COMPATIBILITY · Type: none, backward, backward_transitive, forward, forward_transitive, full, full_transitive · Default: backward

Default compatibility level applied to newly-created subjects.

korvet.schema-registry.enabled

Env var: KORVET_SCHEMA_REGISTRY_ENABLED · Type: boolean · Default: true

Enable the embedded schema-registry HTTP endpoint.

korvet.schema-registry.validate-produce

Env var: KORVET_SCHEMA_REGISTRY_VALIDATE_PRODUCE · Type: boolean · Default: true

Reject produce requests whose payload doesn’t validate against the subject’s latest schema.

Storage

Storage settings split by tier: a Redis-backed local tier and optional object-store remote tier.

Local

Redis-backed local tier settings.

Compression

korvet.storage.local.compression.codec

Env var: KORVET_STORAGE_LOCAL_COMPRESSION_CODEC · Type: none, gzip, snappy, lz4, zstd · Default: none

Default compression codec for values at rest in Redis, applied to topics that do not pin their own storage.compression.type at creation. none stores values uncompressed and directly readable; any other codec compresses the value into its standard frame format. Plain compression is applied per record value and only pays off for values of roughly 1-4 KB and above; small-record topics such as log pipelines should use zstd, whose per-topic dictionary compression (on by default for zstd topics) recovers the redundancy that repeats across records. For large values use zstd for storage efficiency or snappy when CPU cost matters more; use none when payloads must stay directly readable from Redis or are random/already compressed. Values: none, gzip, snappy, lz4, zstd.

Dictionary

korvet.storage.local.compression.dictionary.max-sample-bytes

Env var: KORVET_STORAGE_LOCAL_COMPRESSION_DICTIONARY_MAX_SAMPLE_BYTES · Type: integer · Default: 16777216

Upper bound on the total bytes of sampled record values held in memory per topic while waiting to train. Also the training trigger for topics with large records.

korvet.storage.local.compression.dictionary.sample-count

Env var: KORVET_STORAGE_LOCAL_COMPRESSION_DICTIONARY_SAMPLE_COUNT · Type: integer · Default: 10000

Number of record values sampled before a topic’s dictionary is trained. Training triggers at this count or at max-sample-bytes, whichever is reached first. Must be at least 100 (fewer samples than that cannot train a useful dictionary).

korvet.storage.local.compression.dictionary.size-bytes

Env var: KORVET_STORAGE_LOCAL_COMPRESSION_DICTIONARY_SIZE_BYTES · Type: integer · Default: 65536

Size of the trained zstd dictionary in bytes. zstd guidance is roughly 100x this much training data, which the defaults satisfy for small structured records.

Read

korvet.storage.local.read.connections

Env var: KORVET_STORAGE_LOCAL_READ_CONNECTIONS · Type: integer · Default: 8

Number of dedicated Redis connections the reactive fetch/consume read path is sharded across, routed by stream key. Each Lettuce connection is pinned to a single event loop thread, so this bounds how many cores one broker’s read path can use. Mirrors korvet.storage.local.write.connections.

Redis

Sparse overrides for the local storage Redis client. Each unset field inherits the corresponding value from korvet.redis.

korvet.storage.local.redis.cluster

Env var: KORVET_STORAGE_LOCAL_REDIS_CLUSTER · Type: boolean

Treat the storage Redis target as a Redis Cluster.

korvet.storage.local.redis.host

Env var: KORVET_STORAGE_LOCAL_REDIS_HOST · Type: string

Storage Redis host. Ignored when uri is set.

korvet.storage.local.redis.io-threads

Env var: KORVET_STORAGE_LOCAL_REDIS_IO_THREADS · Type: integer

Storage Redis Lettuce IO thread-pool size.

korvet.storage.local.redis.password

Env var: KORVET_STORAGE_LOCAL_REDIS_PASSWORD · Type: secret

Storage Redis password.

korvet.storage.local.redis.port

Env var: KORVET_STORAGE_LOCAL_REDIS_PORT · Type: integer

Storage Redis port. Ignored when uri is set.

korvet.storage.local.redis.timeout

Env var: KORVET_STORAGE_LOCAL_REDIS_TIMEOUT · Type: duration

Storage Redis per-command timeout.

korvet.storage.local.redis.uri

Env var: KORVET_STORAGE_LOCAL_REDIS_URI · Type: string

Storage Redis URI. When set, overrides the primary Redis URI for storage traffic.

korvet.storage.local.redis.username

Env var: KORVET_STORAGE_LOCAL_REDIS_USERNAME · Type: string

Storage Redis ACL username.

Circuit Breaker

Sparse circuit-breaker overrides for the local storage Redis client.

korvet.storage.local.redis.circuit-breaker.enabled

Env var: KORVET_STORAGE_LOCAL_REDIS_CIRCUIT_BREAKER_ENABLED · Type: boolean

Enable the storage Redis stream-operation circuit breaker.

korvet.storage.local.redis.circuit-breaker.log-interval

Env var: KORVET_STORAGE_LOCAL_REDIS_CIRCUIT_BREAKER_LOG_INTERVAL · Type: duration

Minimum interval between storage Redis breaker-state log lines.

korvet.storage.local.redis.circuit-breaker.open-duration

Env var: KORVET_STORAGE_LOCAL_REDIS_CIRCUIT_BREAKER_OPEN_DURATION · Type: duration

How long the storage Redis circuit breaker stays open before allowing a probe call.

Metrics

Sparse metrics overrides for the local storage Redis client.

korvet.storage.local.redis.metrics.enabled

Env var: KORVET_STORAGE_LOCAL_REDIS_METRICS_ENABLED · Type: boolean

Enable command-latency metrics for the storage Redis client.

korvet.storage.local.redis.metrics.histogram

Env var: KORVET_STORAGE_LOCAL_REDIS_METRICS_HISTOGRAM · Type: boolean

Publish per-command histograms for the storage Redis client.

korvet.storage.local.redis.metrics.local-distinction

Env var: KORVET_STORAGE_LOCAL_REDIS_METRICS_LOCAL_DISTINCTION · Type: boolean

Split storage Redis metrics by local socket address.

korvet.storage.local.redis.metrics.max-latency

Env var: KORVET_STORAGE_LOCAL_REDIS_METRICS_MAX_LATENCY · Type: duration

Upper bound used when bucketing storage Redis latency samples.

korvet.storage.local.redis.metrics.min-latency

Env var: KORVET_STORAGE_LOCAL_REDIS_METRICS_MIN_LATENCY · Type: duration

Lower bound used when bucketing storage Redis latency samples.

Pool

Sparse pool overrides for the local storage Redis client.

korvet.storage.local.redis.pool.max-wait

Env var: KORVET_STORAGE_LOCAL_REDIS_POOL_MAX_WAIT · Type: duration

Maximum time a caller will block waiting to borrow a storage Redis connection.

korvet.storage.local.redis.pool.size

Env var: KORVET_STORAGE_LOCAL_REDIS_POOL_SIZE · Type: integer

Maximum number of pooled storage Redis connections.

Write

korvet.storage.local.write.connections

Env var: KORVET_STORAGE_LOCAL_WRITE_CONNECTIONS · Type: integer · Default: 8

Number of dedicated Redis connections the produce write path is sharded across, routed by stream key. Each Lettuce connection is pinned to a single event loop thread, so this bounds how many cores one broker’s write path can use (issue #885).

korvet.storage.local.write.wait-replicas

Env var: KORVET_STORAGE_LOCAL_WRITE_WAIT_REPLICAS · Type: integer · Default: 0

Number of Redis replicas that must acknowledge each produce write (enforced with a Redis WAIT after the batch’s XADDs) before the record is acknowledged to the Kafka producer. 0 (the default) acknowledges as soon as the Redis master accepts the write, so a Redis failover can lose up to the replication lag. A positive value gives Kafka acks=all-like durability at the cost of an extra round trip per write batch plus the replication latency.

korvet.storage.local.write.wait-timeout

Env var: KORVET_STORAGE_LOCAL_WRITE_WAIT_TIMEOUT · Type: duration · Default: 1s

Upper bound on how long a produce write waits for the replica acknowledgements required by wait-replicas. When it expires before enough replicas have acknowledged, the produce fails so the producer can retry.

Remote

Optional object-store remote tier settings.

korvet.storage.remote.path

Env var: KORVET_STORAGE_REMOTE_PATH · Type: string

Object-store path for the remote Iceberg table (e.g. s3://bucket/korvet/cold). Absent/blank disables the remote tier — Korvet runs local-only on Redis Streams.

Iceberg

Iceberg table, writer, and remote-read settings.

korvet.storage.remote.iceberg.row-group-size

Env var: KORVET_STORAGE_REMOTE_ICEBERG_ROW_GROUP_SIZE · Type: data size · Default: 128MB

Parquet row-group size for Iceberg data files written by the remote segment store. Maps to Iceberg write.parquet.row-group-size-bytes.

korvet.storage.remote.iceberg.target-file-size

Env var: KORVET_STORAGE_REMOTE_ICEBERG_TARGET_FILE_SIZE · Type: data size · Default: 128MB

Target size for Iceberg data files written by the remote segment store. Maps to Iceberg write.target-file-size-bytes.

Read

Bounded executor settings for Iceberg metadata and Parquet reads.

korvet.storage.remote.iceberg.read.queue-capacity

Env var: KORVET_STORAGE_REMOTE_ICEBERG_READ_QUEUE_CAPACITY · Type: integer · Default: 64

Maximum number of Iceberg reads waiting behind active read threads. Additional reads fail immediately instead of growing an unbounded backlog after client timeouts.

korvet.storage.remote.iceberg.read.threads

Env var: KORVET_STORAGE_REMOTE_ICEBERG_READ_THREADS · Type: integer · Default: 4

Maximum number of concurrent Iceberg metadata refresh and Parquet read tasks. These operations include blocking object-store I/O, so a value above the available processors can be appropriate for high-latency storage.

Metrics

korvet.storage.remote.metrics.common-tags

Env var: KORVET_STORAGE_REMOTE_METRICS_COMMON_TAGS · Type: map · Default: [:]

Extra tags attached to remote-tier Iceberg and object-storage SDK meters.

korvet.storage.remote.metrics.enabled

Env var: KORVET_STORAGE_REMOTE_METRICS_ENABLED · Type: boolean · Default: true

Enable Iceberg and object-storage SDK metrics for the remote tier when a Micrometer MeterRegistry is available.

S3

S3 connection settings for the remote tier object store. Only consulted when korvet.storage.remote.path starts with s3://.

korvet.storage.remote.s3.access-key-id

Env var: KORVET_STORAGE_REMOTE_S3_ACCESS_KEY_ID · Type: string

Access-key id. Maps to Iceberg s3.access-key-id.

korvet.storage.remote.s3.endpoint

Env var: KORVET_STORAGE_REMOTE_S3_ENDPOINT · Type: string

Optional endpoint URL for non-AWS S3-compatible stores (e.g. MinIO). Maps to s3.endpoint.

korvet.storage.remote.s3.path-style-access

Env var: KORVET_STORAGE_REMOTE_S3_PATH_STYLE_ACCESS · Type: boolean

Use path-style addressing instead of the default virtual-hosted-style. Maps to s3.path-style-access. Required for most non-AWS S3 stores.

korvet.storage.remote.s3.region

Env var: KORVET_STORAGE_REMOTE_S3_REGION · Type: string

AWS region (e.g. us-east-1). Maps to Iceberg client.region.

korvet.storage.remote.s3.secret-access-key

Env var: KORVET_STORAGE_REMOTE_S3_SECRET_ACCESS_KEY · Type: secret

Secret access key. Maps to s3.secret-access-key.

Worker

Storage worker: leader-locked periodic task that rolls eligible segments, offloads sealed segments, and enforces local and remote retention.

korvet.storage.worker.enabled

Env var: KORVET_STORAGE_WORKER_ENABLED · Type: boolean · Default: true

Enable the storage worker. The Redis leader lock ensures at most one enabled instance runs at a time across the cluster.

korvet.storage.worker.lease-duration

Env var: KORVET_STORAGE_WORKER_LEASE_DURATION · Type: duration · Default: 2m

Redis leader-lock lease duration. Must exceed tickInterval so a slow tick does not let the lease expire mid-flight.

korvet.storage.worker.tick-concurrency

Env var: KORVET_STORAGE_WORKER_TICK_CONCURRENCY · Type: integer · Default: 8

Number of topic-partitions the worker processes concurrently within a tick. With sustained high ingest across many partitions, a single sequential pass cannot reclaim memory as fast as it is produced; raising this bounds how far retention can fall behind. Phase ordering within each partition is unaffected.

korvet.storage.worker.tick-interval

Env var: KORVET_STORAGE_WORKER_TICK_INTERVAL · Type: duration · Default: 1m

Tick cadence for the storage worker loop.

Offload Jobs

korvet.storage.worker.offload-jobs.max-attempts

Env var: KORVET_STORAGE_WORKER_OFFLOAD_JOBS_MAX_ATTEMPTS · Type: integer · Default: 5

Number of offload attempts per segment before the job is marked failed and suspended. The worker retries a failed offload on every tick until this budget is exhausted; after that the segment is skipped until an operator retries the job through the admin API.

korvet.storage.worker.offload-jobs.retention-count

Env var: KORVET_STORAGE_WORKER_OFFLOAD_JOBS_RETENTION_COUNT · Type: integer · Default: 1000

Maximum number of finished (done) offload-job records retained in Redis; the oldest finished records are evicted beyond this cap. Failed and cancelled records are exempt: they carry the suspension state the worker relies on and are bounded by the live segment population.

Ui

korvet.ui.enabled

Env var: KORVET_UI_ENABLED · Type: boolean · Default: true

Whether the embedded SPA is served. Defaults to true.

Topic configuration patterns

The korvet.topics list is order-sensitive: each entry is a glob pattern plus optional field overrides, evaluated top-to-bottom with first-non-null-wins semantics. Fields not set by any matching pattern fall back to the built-in defaults. Per-topic admin-set overrides beat patterns.

The per-element fields (korvet.topics[n].partitions, compression, etc.) live on TopicPattern in korvet-server and are not enumerated in the tables above. The full list:

  • name (required) — glob pattern matched against topic names.

  • auto-create — whether unknown topics matching this pattern may be auto-created.

  • partitions, offset-sequence-bits

  • compression, remote-storage-enabled

  • retention-time, retention-bytes (*-bytes accepts data sizes such as 10GB)

  • max-message-bytes — largest record batch accepted at produce time (accepts data sizes such as 1MB)

  • local-retention-time, local-retention-bytes (*-bytes accepts data sizes such as 512MB)

  • segment-time, segment-bytes (*-bytes accepts data sizes such as 64MB)

As environment variables, list entries are addressed by index: korvet.topics[0].retention-time becomes KORVET_TOPICS_0_RETENTION_TIME, korvet.topics[1].auto-create becomes KORVET_TOPICS_1_AUTO_CREATE, and so on. Each indexed entry needs at least KORVET_TOPICS_<n>_NAME.

See the configuration guide for examples.

Environment variables

Every property can be set via an environment variable using Spring Boot’s relaxed binding: uppercase the property name, replace . and - with _. For example:

Property Environment variable

korvet.broker.max-request-bytes

KORVET_BROKER_MAX_REQUEST_BYTES

korvet.storage.remote.path

KORVET_STORAGE_REMOTE_PATH

korvet.storage.worker.enabled

KORVET_STORAGE_WORKER_ENABLED

The exact env-var name for every property is listed in the tables above. For the korvet.topics pattern list, entries are addressed by index, e.g. KORVET_TOPICS_0_NAME and KORVET_TOPICS_0_PARTITIONS.