Configuration
pg-kinetic accepts configuration from defaults, a TOML file, environment variables, and CLI flags.
Precedence
- Built-in defaults are created first.
- When
--config-fileorPG_KINETIC_CONFIG_FILEis set, pg-kinetic parses that TOML file at startup. - Non-default CLI flags and non-default environment values override the TOML file.
The merge code compares the base CLI/env config against Config::default(). A value equal to the built-in default is not treated as an override.
Unknown TOML fields are not a safe validation mechanism. Use pg-kinetic preflight --config <path> and a real startup check before rollout.
Minimal Runtime Config
[connection]
listen_addr = "0.0.0.0:6432"
backend_addr = "127.0.0.1:5432"
[health]
health_addr = "0.0.0.0:9091"
readiness_backend_check_interval_ms = 1000
readiness_timeout_ms = 5000
Route Config
routes is parsed from TOML, but the current proxy runtime uses only the first effective route:
[[routes]]
[routes.primary]
address = "127.0.0.1:5432"
connect_timeout_ms = 1000
tls_mode = "disable"
[[routes.replicas]]
address = "127.0.0.1:5433"
connect_timeout_ms = 1000
tls_mode = "disable"
weight = 1
[routes.read_routing]
read_routing_mode = "prefer_replica"
fallback_policy = "primary"
[routes.freshness]
freshness_policy = "session_write_lsn"
max_replica_lag_ms = 1000
read_after_write_timeout_ms = 500
[routes.ha]
replica_health_interval_ms = 1000
replica_health_timeout_ms = 500
If routes is empty, the proxy builds one route from connection.backend_addr.
Database/User Pools
[[pools]] maps a startup database and user pair to a backend service address.
[[pools]]
database = "app_a"
user = "app_a"
backend_addr = "127.0.0.1:5432"
max_backends = 20
[[pools]]
database = "app_b"
user = "app_b"
backend_addr = "127.0.0.1:5432"
If [[pools]] is empty, pg-kinetic keeps the existing single default route from connection.backend_addr.
When [[pools]] is non-empty, the startup database and user must match one configured pool before backend checkout. Application name is intentionally ignored for selection. Unmatched clients are rejected with SQLSTATE 3D000, and duplicate (database,user) entries are rejected during configuration parsing.
Each pool is bounded by the lower of the global capacity.max_backends and its optional max_backends. The global capacity.max_backends semaphore remains the aggregate cap across all configured pools; it is not multiplied by the number of [[pools]] entries.
v1 uses a single shared backend service identity: pg-kinetic does not infer per-pool credentials. In pass-through authentication, client credentials continue to be forwarded according to the existing auth configuration; pool entries only select the configured backend_addr.
Query Guardrails
Guardrails run after the existing SQL analysis and fingerprinting step and before backend checkout. Defaults keep them disabled.
[guardrails]
mode = "observe"
block_unqualified_dml = true
block_ddl = true
allowlist_file = "/etc/pg-kinetic/query-fingerprints.txt"
Use the rollout sequence Observe -> review -> Enforce: first collect bounded fingerprint observations, review the resulting fingerprint shapes without exposing query literals, then populate the bounded allowlist and switch to enforce. Observe mode allows traffic. Enforce mode allows only allowlisted fingerprints; hard rules remain denials in enforce mode. Invalid allowlist reloads keep the last valid atomic snapshot.
SHOW GUARDRAILS reports only mode, hard-rule switches, and bounded counts. Denials use SQLSTATE 42501 and a generic message. pg_kinetic_guardrail_denials_total uses only the fixed rule labels unqualified_dml, ddl, and unknown_fingerprint.
Runtime Field Reference
| Field | Type | Default | CLI | Environment | Reload | Failure mode |
|---|---|---|---|---|---|---|
connection.listen_addr | socket address | 127.0.0.1:6543 | --listen-addr | PG_KINETIC_LISTEN_ADDR | restart | Startup fails if bind fails or value cannot parse. |
connection.backend_addr | socket address | 127.0.0.1:5432 | --backend-addr | PG_KINETIC_BACKEND_ADDR | restart | Startup/preflight fails if value cannot parse; readiness fails when backend cannot connect. |
capacity.max_clients | integer | 10000 | --max-clients | PG_KINETIC_MAX_CLIENTS | restart | Client admission is capped at this value. |
capacity.max_backends | integer | 100 | --max-backends | PG_KINETIC_MAX_BACKENDS | restart | Global backend connection cap; each pool is capped by the lower of this value and pool_max_size. |
capacity.max_checkout_waiters | integer | 1000 | --max-checkout-waiters | PG_KINETIC_MAX_CHECKOUT_WAITERS | restart | Excess backend checkout waiters are rejected. |
pool_max_size | integer | 100 | --pool-max-size | PG_KINETIC_POOL_MAX_SIZE | restart | Lifecycle-aware per-pool cap; each pool is capped by the lower of this value and capacity.max_backends. |
pool_min_idle | integer | 0 | --pool-min-idle | PG_KINETIC_POOL_MIN_IDLE | restart | Idle reaping never removes connections below this floor. |
pool_idle_timeout_ms | milliseconds | 1800000 | --pool-idle-timeout-ms | PG_KINETIC_POOL_IDLE_TIMEOUT_MS | restart | Idle backends older than this bound are eligible for reaping. 0 disables the bound. |
pool_max_lifetime_ms | milliseconds | 0 | --pool-max-lifetime-ms | PG_KINETIC_POOL_MAX_LIFETIME_MS | restart | Idle backends older than this lifetime are eligible for reaping. 0 disables the bound. |
performance.checkout_timeout_ms | milliseconds | 1000 | --checkout-timeout-ms | PG_KINETIC_CHECKOUT_TIMEOUT_MS | restart | Backend checkout times out after this duration. |
performance.pool_mode | enum | transaction | --pool-mode | PG_KINETIC_POOL_MODE | restart | Values are transaction and session. Session mode dedicates a checked-out backend to a client until disconnect. |
performance.recovery_mode | enum | recover | --recovery-mode | PG_KINETIC_RECOVERY_MODE | restart | Invalid enum fails parse. Values: recover, rollback_only, drop. |
performance.recovery_timeout_ms | milliseconds | 5000 | --recovery-timeout-ms | PG_KINETIC_RECOVERY_TIMEOUT_MS | restart | Recovery exceeding this duration discards the backend. |
performance.backend_reset_query | string | DISCARD ALL | --backend-reset-query | PG_KINETIC_BACKEND_RESET_QUERY | restart | Invalid SQL fails at backend execution time. |
guardrails.mode | enum | off | --guardrails-mode | PG_KINETIC_GUARDRAILS_MODE | restart | Values are off, observe, and enforce. |
guardrails.block_unqualified_dml | bool | false | --guardrails-block-unqualified-dml | PG_KINETIC_GUARDRAILS_BLOCK_UNQUALIFIED_DML | restart | In enforce mode, conservatively blocks unqualified DELETE and UPDATE statements. |
guardrails.block_ddl | bool | false | --guardrails-block-ddl | PG_KINETIC_GUARDRAILS_BLOCK_DDL | restart | In enforce mode, blocks classified DDL statements before backend checkout. |
guardrails.allowlist_file | optional path | unset | --guardrails-allowlist-file | PG_KINETIC_GUARDRAILS_ALLOWLIST_FILE | reload | New files replace the bounded allowlist atomically; invalid files leave the previous snapshot active. |
qos.max_route_in_flight | integer | 100 | --max-route-in-flight | PG_KINETIC_MAX_ROUTE_IN_FLIGHT | restart | Route concurrency above the cap queues or rejects. |
qos.max_route_waiters | integer | 1000 | --max-route-waiters | PG_KINETIC_MAX_ROUTE_WAITERS | restart | Excess route waiters are rejected. |
qos.query_timeout_ms | milliseconds | 30000 | --query-timeout-ms | PG_KINETIC_QUERY_TIMEOUT_MS | restart | Query cycle times out after this duration. |
qos.idle_client_timeout_ms | milliseconds | 300000 | --idle-client-timeout-ms | PG_KINETIC_IDLE_CLIENT_TIMEOUT_MS | restart | Idle client sessions are closed. |
qos.idle_transaction_timeout_ms | milliseconds | 60000 | --idle-transaction-timeout-ms | PG_KINETIC_IDLE_TRANSACTION_TIMEOUT_MS | restart | Idle pinned transactions are closed or recovered. |
qos.max_client_buffer_bytes | bytes | 1048576 | --max-client-buffer-bytes | PG_KINETIC_MAX_CLIENT_BUFFER_BYTES | restart | Client buffering above the cap fails the session. |
qos.max_backend_buffer_bytes | bytes | 4194304 | --max-backend-buffer-bytes | PG_KINETIC_MAX_BACKEND_BUFFER_BYTES | restart | Backend buffering above the cap fails or discards the backend. |
qos.overload_error_code | SQLSTATE string | 53300 | --overload-error-code | PG_KINETIC_OVERLOAD_ERROR_CODE | restart | Invalid SQLSTATE shape can produce invalid client-facing errors. |
admin.admin_addr | optional socket address | unset | --admin-addr | PG_KINETIC_ADMIN_ADDR | restart | Startup fails if bind fails. |
admin.admin_require_tls | bool | false | --admin-require-tls | PG_KINETIC_ADMIN_REQUIRE_TLS | restart | Startup fails when TLS is required but server TLS config cannot load. |
admin.admin_allowed_user | optional string | unset | --admin-allowed-user | PG_KINETIC_ADMIN_ALLOWED_USER | restart | Non-matching admin startup user is rejected. |
admin.admin_query_timeout_ms | milliseconds | 1000 | --admin-query-timeout-ms | PG_KINETIC_ADMIN_QUERY_TIMEOUT_MS | restart | Admin query handling times out. |
admin.admin_max_clients | integer | 8 | --admin-max-clients | PG_KINETIC_ADMIN_MAX_CLIENTS | restart | Excess admin clients wait or are rejected. |
observability.metrics_addr | optional socket address | unset | --metrics-addr | PG_KINETIC_METRICS_ADDR | restart | Startup fails if metrics bind fails. |
observability.log_level | string | info | --log-level | PG_KINETIC_LOG_LEVEL | restart | A level (trace, debug, info, warn, error, off) or a filter directive such as pg_kinetic=debug,warn. RUST_LOG takes precedence when set. Startup fails on an unknown level or a malformed directive rather than falling back silently. |
observability.log_format | enum | text | --log-format | PG_KINETIC_LOG_FORMAT | restart | Values: text, json. Use json for structured log collection. |
observability.debug_trace_sampling_rate | float | 0.0 | --debug-trace-sampling-rate | PG_KINETIC_DEBUG_TRACE_SAMPLING_RATE | restart | Non-finite values are clamped to 0.0 at use. |
observability.phase_timing_sample_rate | float | 1.0 | --phase-timing-sample-rate | PG_KINETIC_PHASE_TIMING_SAMPLE_RATE | restart | Detailed protocol phase histograms are sampled per session; values are clamped to 0.0..=1.0, and core health, pool, error, and backpressure metrics remain unsampled. |
observability.otel_enabled | bool | false | --otel-enabled | PG_KINETIC_OTEL_ENABLED | restart | Export is disabled when false. |
observability.otel_endpoint | optional string | unset | --otel-endpoint | PG_KINETIC_OTEL_ENDPOINT | restart | Invalid endpoint fails at exporter setup/use. |
observability.otel_service_name | string | pg-kinetic | --otel-service-name | PG_KINETIC_OTEL_SERVICE_NAME | restart | Empty or misleading names affect telemetry identity. |
audit.enabled | bool | false | --audit-enabled | PG_KINETIC_AUDIT_ENABLED | restart | Enables bounded asynchronous statement audit records. |
audit.sink | optional path | unset | --audit-sink | PG_KINETIC_AUDIT_SINK | restart | JSON-lines destination; unset writes to stderr. Sink errors do not stop the proxy. |
audit.sample_rate | float | 1.0 | --audit-sample-rate | PG_KINETIC_AUDIT_SAMPLE_RATE | restart | Deterministic fingerprint-based sampling, clamped to 0.0..=1.0. |
audit.include_reads | bool | false | --audit-include-reads | PG_KINETIC_AUDIT_INCLUDE_READS | restart | Includes read-class statements; writes and non-read classes remain eligible by default. |
tls.client_tls_mode | enum | disable | --client-tls-mode | PG_KINETIC_CLIENT_TLS_MODE | restart | Invalid enum fails parse. Values: disable, allow, require, verify_client. |
tls.client_cert_path | optional path | unset | --client-cert-path | PG_KINETIC_CLIENT_TLS_CERT_PATH | restart | TLS startup fails if required file cannot load. |
tls.client_key_path | optional path | unset | --client-key-path | PG_KINETIC_CLIENT_TLS_KEY_PATH | restart | TLS startup fails if required key cannot load. |
tls.client_ca_path | optional path | unset | --client-ca-path | PG_KINETIC_CLIENT_TLS_CA_PATH | restart | Client verification fails if CA cannot load. |
tls.backend_tls_mode | enum | disable | --backend-tls-mode | PG_KINETIC_BACKEND_TLS_MODE | restart | Invalid enum fails parse. Values: disable, prefer, require, verify_ca, verify_full. |
tls.backend_ca_path | optional path | unset | --backend-ca-path | PG_KINETIC_BACKEND_TLS_CA_PATH | restart | Backend verification fails if CA cannot load. |
tls.backend_server_name | optional string | unset | --backend-server-name | PG_KINETIC_BACKEND_TLS_SERVER_NAME | restart | verify_full fails when name does not match backend cert. |
auth.auth_mode | enum | pass_through | --auth-mode | PG_KINETIC_AUTH_MODE | restart | Invalid enum fails parse. Values: pass_through, trust, scram_sha_256, md5. |
auth.auth_users_file | optional path | unset | --auth-users-file | PG_KINETIC_AUTH_USERS_FILE | reload asset | Startup/reload fails if the file cannot load. |
auth.backend_user | optional string | unset | --backend-user | PG_KINETIC_BACKEND_USER | reload | Must be paired with auth.backend_password_env_var_name; selects the dedicated upstream service role after local client authentication. Successful reloads retire idle pooled backends. |
auth.backend_password_env_var_name | optional string | unset | --backend-password-env-var-name | PG_KINETIC_BACKEND_PASSWORD_ENV_VAR_NAME | reload | Must be paired with auth.backend_user; names the injected service password read by EnvironmentCredentialProvider. Service credentials are invalid with pass_through; successful reloads retire idle pooled backends. |
auth.auth_query_enabled | bool | false | --auth-query-enabled | PG_KINETIC_AUTH_QUERY_ENABLED | restart | Dynamic lookup is disabled by default. Enabling it requires backend service credentials and a valid single-parameter query. |
auth.auth_query | string | SELECT usename, passwd FROM pg_shadow WHERE usename = $1 | --auth-query | PG_KINETIC_AUTH_QUERY | restart | Query must contain exactly one $1 placeholder. The lookup connection is dedicated to authentication and accepts SCRAM or MD5 verifier results only. |
auth.auth_query_cache_ttl_ms | milliseconds | 60000 | --auth-query-cache-ttl-ms | PG_KINETIC_AUTH_QUERY_CACHE_TTL_MS | restart | Successful dynamic lookups are cached until this TTL expires. 0 disables cache hits. |
auth.auth_failure_message_mode | enum | generic | --auth-failure-message-mode | PG_KINETIC_AUTH_FAILURE_MESSAGE_MODE | restart | detailed can expose more auth context to clients. |
reload.config_file | optional path | unset | --config-file | PG_KINETIC_CONFIG_FILE | restart | Startup/reload fails if file cannot read or parse. |
reload.config_reload_interval_ms | milliseconds | 5000 | --config-reload-interval-ms | PG_KINETIC_CONFIG_RELOAD_INTERVAL_MS | restart | Reload loop ticks at this interval. |
reload.reload_enabled | bool | false | --reload-enabled | PG_KINETIC_CONFIG_RELOAD_ENABLED | restart | Reload loop is disabled when false. |
drain.drain_timeout_ms | milliseconds | 30000 | --drain-timeout-ms | PG_KINETIC_DRAIN_TIMEOUT_MS | restart | Shutdown drain waits up to this duration. |
drain.reject_new_clients_during_drain | bool | false | --reject-new-clients-during-drain | PG_KINETIC_REJECT_NEW_CLIENTS_DURING_DRAIN | restart | New clients are rejected during drain when true. |
health.health_addr | optional socket address | unset | --health-addr | PG_KINETIC_HEALTH_ADDR | restart | Startup fails if bind fails. |
health.readiness_backend_check_interval_ms | milliseconds | 1000 | --readiness-backend-check-interval-ms | PG_KINETIC_READINESS_BACKEND_CHECK_INTERVAL_MS | restart | Backend health probe interval. |
health.readiness_timeout_ms | milliseconds | 5000 | --readiness-timeout-ms | PG_KINETIC_READINESS_TIMEOUT_MS | restart | Backend health probe timeout. |
socket.tcp_nodelay | bool | true | --tcp-nodelay | PG_KINETIC_TCP_NODELAY | restart | Socket option failure follows strict mode behavior. |
socket.tcp_keepalive | bool | false | --tcp-keepalive | PG_KINETIC_TCP_KEEPALIVE | restart | Enables TCP keepalive when supported. |
socket.tcp_keepalive_idle_ms | optional milliseconds | unset | --tcp-keepalive-idle-ms | PG_KINETIC_TCP_KEEPALIVE_IDLE_MS | restart | Unsupported values fail only in strict mode. |
socket.tcp_keepalive_interval_ms | optional milliseconds | unset | --tcp-keepalive-interval-ms | PG_KINETIC_TCP_KEEPALIVE_INTERVAL_MS | restart | Unsupported values fail only in strict mode. |
socket.tcp_keepalive_retries | optional integer | unset | --tcp-keepalive-retries | PG_KINETIC_TCP_KEEPALIVE_RETRIES | restart | Unsupported values fail only in strict mode. |
socket.tcp_user_timeout_ms | optional milliseconds | unset | --tcp-user-timeout-ms | PG_KINETIC_TCP_USER_TIMEOUT_MS | restart | Unsupported values fail only in strict mode. |
socket.tcp_send_buffer_bytes | optional bytes | unset | --tcp-send-buffer-bytes | PG_KINETIC_TCP_SEND_BUFFER_BYTES | restart | Unsupported values fail only in strict mode. |
socket.tcp_recv_buffer_bytes | optional bytes | unset | --tcp-recv-buffer-bytes | PG_KINETIC_TCP_RECV_BUFFER_BYTES | restart | Unsupported values fail only in strict mode. |
socket.strict_socket_option_mode | bool | false | --strict-socket-option-mode | PG_KINETIC_STRICT_SOCKET_OPTION_MODE | restart | Startup fails on unsupported socket options when true. |
resilience.breaker_failure_threshold | integer | 5 | --breaker-failure-threshold | PG_KINETIC_BREAKER_FAILURE_THRESHOLD | restart | Consecutive backend failures before opening the per-backend breaker. |
resilience.breaker_cooldown_ms | milliseconds | 5000 | --breaker-cooldown-ms | PG_KINETIC_BREAKER_COOLDOWN_MS | restart | Cooldown before one half-open recovery probe. |
resilience.hedging_enabled | bool | false | --hedging-enabled | PG_KINETIC_HEDGING_ENABLED | restart | Reserved safe read-hedge gate; duplicate backend forwarding remains disabled. |
resilience.hedge_delay_ms | milliseconds | 25 | --hedge-delay-ms | PG_KINETIC_HEDGE_DELAY_MS | restart | Delay used by a future safe read-hedge executor. |
resilience.failover_enabled | bool | false | --failover-enabled | PG_KINETIC_FAILOVER_ENABLED | restart | Enables one bounded retry for replay-safe reads when the backend is lost before any response bytes are sent. |
resilience.failover_max_reconnect_ms | milliseconds | 1000 | --failover-max-reconnect-ms | PG_KINETIC_FAILOVER_MAX_RECONNECT_MS | restart | Upper bound for replacement backend checkout during transparent failover; also bounded by the current query timeout. |
resilience.failover_replay_session_state | bool | true | --failover-replay-session-state | PG_KINETIC_FAILOVER_REPLAY_SESSION_STATE | restart | Replays tracked safe session settings such as application_name, search_path, timezone, datestyle, and extra_float_digits before retrying eligible reads. |
The hedge fields are inactive reservation points. Setting
resilience.hedging_enabled = true does not duplicate read forwarding in the
current runtime. Use Transparent failover for the
implemented retry behavior.
Runtime Lifecycle Fields
| Field | Type | Default | CLI | Environment | Reload | Failure mode |
|---|---|---|---|---|---|---|
runtime.lifecycle.startup_grace_ms | milliseconds | 30000 | --startup-grace-ms | PG_KINETIC_STARTUP_GRACE_MS | restart | Startup coordination uses this timeout. |
runtime.lifecycle.shutdown_grace_ms | milliseconds | 30000 | --shutdown-grace-ms | PG_KINETIC_SHUTDOWN_GRACE_MS | restart | Shutdown coordination uses this timeout. |
runtime.lifecycle.readiness_fail_during_drain | bool | true | --readiness-fail-during-drain | PG_KINETIC_READINESS_FAIL_DURING_DRAIN | restart | /readyz reports not ready during drain when true. |
runtime.lifecycle.pre_stop_drain_enabled | bool | true | --pre-stop-drain-enabled | PG_KINETIC_PRE_STOP_DRAIN_ENABLED | restart | HTTP /drain is not implemented, so do not wire Kubernetes hooks to it yet. |
runtime.lifecycle.pre_stop_drain_endpoint | string | /drain | --pre-stop-drain-endpoint | PG_KINETIC_PRE_STOP_DRAIN_ENDPOINT | restart | Informational until an HTTP drain endpoint exists. |
runtime.lifecycle.startup_backend_checks_enabled | bool | true | --startup-backend-checks-enabled | PG_KINETIC_STARTUP_BACKEND_CHECKS_ENABLED | restart | Startup readiness depends on backend checks when true. |
runtime.lifecycle.termination_grace_period_seconds | seconds | 65 | --termination-grace-period-seconds | PG_KINETIC_TERMINATION_GRACE_PERIOD_SECONDS | restart | Documents expected supervisor grace period. |
runtime.node.node_id | string | generated host/process id | --node-id | PG_KINETIC_NODE_ID | restart | Empty or invalid ids fail parse. |
runtime.engine.runtime_engine | enum | thread_per_core | --runtime-engine | PG_KINETIC_RUNTIME_ENGINE | restart | Values are thread_per_core, tokio_default, tokio_current_thread, and io_uring. |
runtime.engine.experimental_runtime_enabled | bool | false | --experimental-runtime-enabled | PG_KINETIC_EXPERIMENTAL_RUNTIME_ENABLED | restart | Legacy compatibility field; stable runtime engines do not require it. |
runtime.engine.runtime_shards | optional integer | unset | --runtime-shards | PG_KINETIC_RUNTIME_SHARDS | restart | Overrides automatic runtime shard sizing; 0 fails validation. |
runtime.production.control_plane_enabled | bool | false | --control-plane-enabled | PG_KINETIC_CONTROL_PLANE_ENABLED | restart | No control-plane runtime is documented as production-ready. |
runtime.production.mirroring_enabled | bool | false | --mirroring-enabled | PG_KINETIC_MIRRORING_ENABLED | restart | Live proxy still constructs a disabled mirror dispatcher. |
runtime.production.adaptive_enabled | bool | false | --adaptive-enabled | PG_KINETIC_ADAPTIVE_ENABLED | restart | Starts recommendation/simulation controller when true. |
runtime.production.pressure.enabled | bool | false | --pressure-enabled | PG_KINETIC_PRESSURE_ENABLED | restart | Enables PSI-driven dynamic route in-flight pressure limits. |
runtime.production.pressure.cpu_high_pct | float | 20.0 | --pressure-cpu-high-pct | PG_KINETIC_PRESSURE_CPU_HIGH_PCT | restart | CPU PSI some avg10 threshold; values must be finite and within 0.0..=100.0. |
runtime.production.pressure.mem_high_pct | float | 10.0 | --pressure-mem-high-pct | PG_KINETIC_PRESSURE_MEM_HIGH_PCT | restart | Memory PSI some avg10 threshold; values must be finite and within 0.0..=100.0. |
runtime.production.pressure.min_in_flight_floor | integer | 1 | --pressure-min-in-flight-floor | PG_KINETIC_PRESSURE_MIN_IN_FLIGHT_FLOOR | restart | Lowest dynamic per-route in-flight limit when pressure is high; must be greater than zero. |
runtime.production.pressure.window_ms | milliseconds | 5000 | --pressure-window-ms | PG_KINETIC_PRESSURE_WINDOW_MS | restart | Pressure control tick window; must be greater than zero. |
runtime.production.adaptive_mode | enum | recommend | --adaptive-mode | PG_KINETIC_ADAPTIVE_MODE | restart | Values are recommend and apply; apply mode records simulated apply outcomes only. |
runtime.production.adaptive_window_ms | milliseconds | 60000 | --adaptive-window-ms | PG_KINETIC_ADAPTIVE_WINDOW_MS | restart | Must be greater than zero. |
runtime.production.adaptive_min_confidence | float | 0.8 | --adaptive-min-confidence | PG_KINETIC_ADAPTIVE_MIN_CONFIDENCE | restart | Must be finite and within 0.0..=1.0. |
runtime.production.adaptive_apply_enabled | bool | false | --adaptive-apply-enabled | PG_KINETIC_ADAPTIVE_APPLY_ENABLED | restart | Required for adaptive_mode = "apply"; does not mutate live settings. |
runtime.production.adaptive_apply_allowlist | list | [] | --adaptive-apply-allowlist | PG_KINETIC_ADAPTIVE_APPLY_ALLOWLIST | restart | Required and duplicate-free for apply mode. |
runtime.production.adaptive_max_change_percent | integer | 10 | --adaptive-max-change-percent | PG_KINETIC_ADAPTIVE_MAX_CHANGE_PERCENT | restart | Must be between 1 and 100. |
The internal apply and guardrail wrappers are flattened by the parser. They are not TOML table names.
The top-level pool lifecycle settings are flattened in TOML and CLI parsing. They populate the internal pool_lifecycle fields max_size, min_idle, idle_timeout, and max_lifetime.
Reload compatibility is strict. Any runtime field change, including adaptive runtime scalar fields, is restart-required. Accepted reloads affect new client connections and reloadable assets such as auth user file contents or TLS certificate file contents at unchanged paths; they do not change existing sessions or already checked-out backends. Backend service credentials are resolved for each new backend authentication exchange, so rotating the injected environment value takes effect after idle backends are discarded or recycled.
Preview Configs Not In Main Runtime
[sharding], [policy], and [mirror] examples from preview docs are not part of the main live proxy config contract. Use the preview commands for those models:
pg-kinetic route-preview --config preview.toml --database app --user app --sql "select 1"
pg-kinetic policy-preview --config preview.toml --database app --user app --route primary --shard default --query-class read_candidate
Do not deploy sharding, policy, or mirroring config as live traffic configuration until the proxy runtime exposes and applies those configs.
Sharding preview fields:
| Field | Default | Notes |
|---|---|---|
sharding_enabled | false | Enables the offline sharding model for route-preview. |
multi_shard_policy | reject | Values are reject, first_match, and fan_out. |
route_map_reload_strict | true | Rejects overlapping route maps without explicit priority. |
route_preview_enabled | false | Marks preview intent; it does not activate live traffic sharding. |
route_maps | [] | Array of route-map entries. |
scope | required per route map | Scope object such as database_user, application_name, schema_table, or tenant_key. |
strategy | required per route map | Strategy object with kind hash, range, or list. |
targets | required per route map | Non-empty list of primary or replicas targets. |
priority | unset | Required when route maps overlap. |
Policy preview fields:
| Field | Default | Notes |
|---|---|---|
policy_mode | disabled | Values include disabled, dry-run, and enforcement modes supported by the parser. |
policy_files | [] | File references for policy documents. |
inline_rules | [] | Inline policy rules for preview and model validation. |
policy_id | generated default | Rule identifier shown in audit and preview output. |
hook_point | default policy hook | Hook point evaluated by the preview model. |
action | required for inline rules | Flattened inline rule action such as allow, deny, require primary, require replica, route override, shard override, or wasm. |
policy_audit.policy_audit_enabled | true | Enables audit event recording when policy paths run. |
policy_audit.policy_audit_sample_rate | 1.0 | Audit sampling rate. |
policy_wasm.policy_wasm_enabled | false | Required before wasm policy actions are accepted. |
policy_eval_timeout_ms | implementation default | Policy evaluation timeout. |
policy_max_context_bytes | implementation default | Redacted policy context size cap. |
Mirror preview fields:
| Field | Default | Notes |
|---|---|---|
mirroring_enabled | false | Top-level mirror model flag. Live traffic mirroring is not active today. |
mirror_mode | off | Mirror mode parser value. |
mirror_timeout_ms | 100 | Mirror task timeout. |
mirror_max_in_flight | 128 | In-flight mirror task cap. |
target.address | unset | Mirror target socket address. |
target.isolated | false | Marks the target as isolated from production. |
safety.mirror_writes_enabled | false | Allows write mirroring only when explicitly set. |
safety.mirror_transactions_enabled | false | Allows transaction mirroring only when explicitly set. |
safety.mirror_copy_enabled | false | Allows COPY mirroring only when explicitly set. |
safety.mirror_listen_notify_enabled | false | Allows LISTEN/NOTIFY mirroring only when explicitly set. |
safety.mirror_temp_table_enabled | false | Allows temp-table mirroring only when explicitly set. |
safety.mirror_session_mutation_enabled | false | Allows session-mutation mirroring only when explicitly set. |
safety.mirror_require_isolated_target | true | Rejects unsafe production-target reuse. |
sampling.mirror_sample_rate | 0.0 | Mirror sample rate. |
Secrets And TLS
- Keep private keys readable only by the pg-kinetic process user.
- Mount certificates and user files read-only.
- Rotate backend passwords by changing the injected secret and recycling idle backends when
backend_password_env_var_nameis used; existing checked-out sessions are unchanged. - Use
verify_fullonly withbackend_ca_pathandbackend_server_name. - Use
verify_clientonly with client cert, key, and CA paths present.
Validate Before Rollout
pg-kinetic preflight --config /etc/pg-kinetic/pg-kinetic.toml
Container:
docker run --rm \
-v "$PWD/pg-kinetic.toml:/etc/pg-kinetic/pg-kinetic.toml:ro" \
ghcr.io/hookwoods/pg-kinetic:latest \
preflight --config /etc/pg-kinetic/pg-kinetic.toml