Skip to main content

mz_adapter_dyncfgs/
dyncfgs.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! Dyncfgs used by the adapter layer.
11
12use std::time::Duration;
13
14use mz_dyncfg::{Config, ConfigSet, ParameterScope};
15
16pub const ALLOW_USER_SESSIONS: Config<bool> = Config::new(
17    "allow_user_sessions",
18    true,
19    "Whether to allow user roles to create new sessions. When false, only system roles will be permitted to create new sessions.",
20    ParameterScope::Environment,
21);
22
23// Slightly awkward with the WITH prefix, but we can't start with a 0..
24pub const WITH_0DT_DEPLOYMENT_MAX_WAIT: Config<Duration> = Config::new(
25    "with_0dt_deployment_max_wait",
26    // One year, which in practice makes it so we never cut over when not
27    // hydrated. To prevent cutting over unilaterally when there is an issue.
28    Duration::from_hours(365 * 24),
29    "How long to wait at most for clusters to be hydrated, when doing a zero-downtime deployment.",
30    ParameterScope::Environment,
31);
32
33pub const WITH_0DT_DEPLOYMENT_DDL_CHECK_INTERVAL: Config<Duration> = Config::new(
34    "with_0dt_deployment_ddl_check_interval",
35    Duration::from_secs(5 * 60),
36    "How often to check for DDL changes during zero-downtime deployment.",
37    ParameterScope::Environment,
38);
39
40pub const ENABLE_0DT_DEPLOYMENT_PANIC_AFTER_TIMEOUT: Config<bool> = Config::new(
41    "enable_0dt_deployment_panic_after_timeout",
42    false,
43    "Whether to panic if the maximum wait time is reached but preflight checks have not succeeded.",
44    ParameterScope::Environment,
45);
46
47pub const WITH_0DT_DEPLOYMENT_CAUGHT_UP_CHECK_INTERVAL: Config<Duration> = Config::new(
48    // The feature flag name is historical.
49    "0dt_deployment_hydration_check_interval",
50    Duration::from_secs(10),
51    "Interval at which to check whether clusters are caught up, when doing zero-downtime deployment.",
52    ParameterScope::Environment,
53);
54
55pub const WITH_0DT_CAUGHT_UP_CHECK_ALLOWED_LAG: Config<Duration> = Config::new(
56    "with_0dt_caught_up_check_allowed_lag",
57    Duration::from_secs(60),
58    "Maximum allowed lag when determining whether collections are caught up for 0dt deployments.",
59    ParameterScope::Environment,
60);
61
62pub const WITH_0DT_CAUGHT_UP_CHECK_CUTOFF: Config<Duration> = Config::new(
63    "with_0dt_caught_up_check_cutoff",
64    Duration::from_secs(2 * 60 * 60), // 2 hours
65    "Collections whose write frontier is behind 'now' by more than the cutoff are ignored when doing caught-up checks for 0dt deployments.",
66    ParameterScope::Environment,
67);
68
69pub const ENABLE_0DT_CAUGHT_UP_REPLICA_STATUS_CHECK: Config<bool> = Config::new(
70    "enable_0dt_caught_up_replica_status_check",
71    true,
72    "Enable checking for crash/OOM-looping replicas during 0dt caught-up checks. Emergency break-glass flag to disable this feature if needed.",
73    ParameterScope::Environment,
74);
75
76// TODO(aljoscha): Remove this break-glass flag after a couple of releases, once
77// the sustained-health gate has proven itself in production. It only exists as a
78// fleet-wide automatic revert to the prior "caught-up implies ready" behavior.
79pub const ENABLE_0DT_CAUGHT_UP_STABILITY_CHECK: Config<bool> = Config::new(
80    "enable_0dt_caught_up_stability_check",
81    true,
82    "Require clusters to stay caught-up and healthy for a stability period before being considered ready during 0dt deployments. Emergency break-glass flag: disabling reverts to treating a caught-up cluster as ready with no replica-health requirement, which differs from setting the stability period to zero (a zero period still requires all replicas to be healthy).",
83    ParameterScope::Environment,
84);
85
86pub const WITH_0DT_CAUGHT_UP_CHECK_STABILITY_PERIOD: Config<Duration> = Config::new(
87    "with_0dt_caught_up_check_stability_period",
88    Duration::from_secs(10 * 60), // 10 minutes
89    "Required continuous hydration before a caught-up cluster is ready for 0dt cutover. Each non-exempt replica's period is capped at its catalog creation age when it hydrated. Missing creation evidence retains the full period.",
90    ParameterScope::Environment,
91);
92
93pub const ENABLE_0DT_HYDRATE_MIGRATED_BUILTIN_MVS: Config<bool> = Config::new(
94    "enable_0dt_hydrate_migrated_builtin_mvs",
95    true,
96    "Write-enable replacement-migrated builtin materialized views while read-only during a 0dt \
97     deployment, so they hydrate before cut-over and keep gating promotion. Emergency break-glass \
98     flag: disabling excludes migrated MVs (and their dependents) from the caught-up check again, \
99     so promotion proceeds with them unhydrated. Not an exact revert: a collection with no live \
100     leader frontier must be hydrated either way. Only takes effect when the leader is new enough \
101     for the write to make progress, and is read once at startup, so changing it means setting it \
102     on the leader and restarting the new deployment.",
103    ParameterScope::Environment,
104);
105
106/// Enable logging of statement lifecycle events in mz_internal.mz_statement_lifecycle_history.
107pub const ENABLE_STATEMENT_LIFECYCLE_LOGGING: Config<bool> = Config::new(
108    "enable_statement_lifecycle_logging",
109    true,
110    "Enable logging of statement lifecycle events in mz_internal.mz_statement_lifecycle_history.",
111    ParameterScope::Environment,
112);
113
114/// Enable installation of introspection subscribes.
115pub const ENABLE_INTROSPECTION_SUBSCRIBES: Config<bool> = Config::new(
116    "enable_introspection_subscribes",
117    true,
118    "Enable installation of introspection subscribes.",
119    ParameterScope::Environment,
120);
121
122/// The plan insights notice will not investigate fast path clusters if plan optimization took longer than this.
123pub const PLAN_INSIGHTS_NOTICE_FAST_PATH_CLUSTERS_OPTIMIZE_DURATION: Config<Duration> = Config::new(
124    "plan_insights_notice_fast_path_clusters_optimize_duration",
125    // Looking at production values of the mz_optimizer_e2e_optimization_time_seconds metric, most
126    // optimizations run faster than 10ms, so this should still work well for most queries. We want
127    // to avoid the case where an optimization took just under this value and there are lots of
128    // clusters, so the extra delay to produce the plan insights notice will take the optimization
129    // time * the number of clusters longer.
130    Duration::from_millis(10),
131    "Enable plan insights fast path clusters calculation if the optimize step took less than this duration.",
132    ParameterScope::Environment,
133);
134
135/// Whether to use an expression cache on boot.
136pub const ENABLE_EXPRESSION_CACHE: Config<bool> = Config::new(
137    "enable_expression_cache",
138    true,
139    "Use a cache to store optimized expressions to help speed up start times. \
140     Read at startup, so changing it takes effect on the next restart.",
141    ParameterScope::Environment,
142);
143
144/// Whether to enable password authentication.
145pub const ENABLE_PASSWORD_AUTH: Config<bool> = Config::new(
146    "enable_password_auth",
147    false,
148    "Enable password authentication.",
149    ParameterScope::Environment,
150);
151
152/// Upper bound on the number of transitive dependencies validated for a
153/// read-then-write statement (e.g. `DELETE ... WHERE ... IN (SELECT ...)`).
154/// Validation walks the read set's dependency graph, which is user controlled
155/// and can be arbitrarily large. The bound rejects pathological graphs with a
156/// clean error instead of consuming unbounded time and memory.
157pub const READ_THEN_WRITE_MAX_DEPENDENCIES: Config<usize> = Config::new(
158    "read_then_write_max_dependencies",
159    100_000,
160    "Maximum number of transitive dependencies validated for a read-then-write \
161     statement before it is rejected.",
162    ParameterScope::Environment,
163);
164
165/// OIDC issuer URL.
166pub const OIDC_ISSUER: Config<Option<&'static str>> = Config::new(
167    "oidc_issuer",
168    None,
169    "OIDC issuer URL.",
170    ParameterScope::Environment,
171);
172
173/// OIDC audience (client IDs). When empty, audience validation is skipped.
174/// Validates that the JWT's `aud` claim contains at least one of these values.
175/// It is insecure to skip validation because it is the only
176/// mechanism preventing attackers from authenticating using a JWT
177/// issued by a dummy application, but from the same identity provider.
178pub const OIDC_AUDIENCE: Config<fn() -> serde_json::Value> = Config::new(
179    "oidc_audience",
180    || serde_json::json!([]),
181    "OIDC audience (client IDs). A JSON array of strings. When empty, audience validation is skipped.",
182    ParameterScope::Environment,
183);
184
185/// OIDC authentication claim to use as username
186pub const OIDC_AUTHENTICATION_CLAIM: Config<&'static str> = Config::new(
187    "oidc_authentication_claim",
188    "sub",
189    "OIDC authentication claim to use as username.",
190    ParameterScope::Environment,
191);
192
193/// Whether OIDC group-to-role sync is enabled.
194/// When true, JWT group claims are used to sync role memberships on login.
195pub const OIDC_GROUP_ROLE_SYNC_ENABLED: Config<bool> = Config::new(
196    "oidc_group_role_sync_enabled",
197    false,
198    "Enable OIDC JWT group-to-role membership sync on login.",
199    ParameterScope::Environment,
200);
201
202/// The JWT claim path that contains group memberships. May be a bare claim
203/// name (e.g. `groups`) or a dot-separated path into nested objects (e.g.
204/// `customClaims.groups`).
205pub const OIDC_GROUP_CLAIM: Config<&'static str> = Config::new(
206    "oidc_group_claim",
207    "groups",
208    "JWT claim path containing group memberships for role sync. Supports dot-separated paths into nested objects (e.g. customClaims.groups).",
209    ParameterScope::Environment,
210);
211
212/// Whether to reject login when group sync fails (strict/fail-closed mode).
213/// When false (default), sync failures are logged but login proceeds (fail-open).
214pub const OIDC_GROUP_ROLE_SYNC_STRICT: Config<bool> = Config::new(
215    "oidc_group_role_sync_strict",
216    false,
217    "When true, reject login if OIDC group-to-role sync fails (fail-closed).",
218    ParameterScope::Environment,
219);
220
221pub const PERSIST_FAST_PATH_ORDER: Config<bool> = Config::new(
222    "persist_fast_path_order",
223    true,
224    "If set, send queries with a compatible literal constraint or ordering clause down the Persist fast path.",
225    ParameterScope::Environment,
226);
227
228/// Whether to enforce that S3 Tables connections are in the same region as the Materialize
229/// environment.
230pub const ENABLE_S3_TABLES_REGION_CHECK: Config<bool> = Config::new(
231    "enable_s3_tables_region_check",
232    false,
233    "Whether to enforce that S3 Tables connections are in the same region as the environment.",
234    ParameterScope::Environment,
235);
236
237/// Whether the MCP agent endpoint is enabled.
238pub const ENABLE_MCP_AGENT: Config<bool> = Config::new(
239    "enable_mcp_agent",
240    true,
241    "Whether the MCP agent HTTP endpoint is enabled. When false, requests to /api/mcp/agent return 503 Service Unavailable.",
242    ParameterScope::Environment,
243);
244
245/// Whether the MCP agent query tool is enabled.
246/// When false, the `query` tool is hidden from tools/list and calls to it return an error.
247/// Agents can still use `get_data_products` and `get_data_product_details`.
248pub const ENABLE_MCP_AGENT_QUERY_TOOL: Config<bool> = Config::new(
249    "enable_mcp_agent_query_tool",
250    true,
251    "Whether the MCP agent query tool is enabled. When false, the query tool is not advertised and calls to it are rejected. Agents can still discover and inspect data products.",
252    ParameterScope::Environment,
253);
254
255/// Whether the MCP agent read_data_product tool is enabled.
256/// When false, the `read_data_product` tool is hidden from tools/list and calls to it return an error.
257/// The `query` tool is the general-purpose alternative for reading data products.
258pub const ENABLE_MCP_AGENT_READ_DATA_PRODUCT_TOOL: Config<bool> = Config::new(
259    "enable_mcp_agent_read_data_product_tool",
260    true,
261    "Whether the MCP agent read_data_product tool is enabled. When false, the read_data_product tool is not advertised and calls to it are rejected. Agents can use the query tool to read data products.",
262    ParameterScope::Environment,
263);
264
265/// Whether the MCP developer endpoint is enabled.
266pub const ENABLE_MCP_DEVELOPER: Config<bool> = Config::new(
267    "enable_mcp_developer",
268    true,
269    "Whether the MCP developer HTTP endpoint is enabled. When false, requests to /api/mcp/developer return 503 Service Unavailable.",
270    ParameterScope::Environment,
271);
272
273/// Whether the MCP developer query tool is enabled.
274/// When false, the `query` tool is hidden from tools/list and calls to it return an error.
275/// Developers can still use `query_system_catalog`.
276pub const ENABLE_MCP_DEVELOPER_QUERY_TOOL: Config<bool> = Config::new(
277    "enable_mcp_developer_query_tool",
278    true,
279    "Whether the MCP developer query tool is enabled. When false, the query tool is not advertised and calls to it are rejected. Developers can still use query_system_catalog.",
280    ParameterScope::Environment,
281);
282
283/// Whether the MCP endpoints serve the 2026-07-28 protocol alongside
284/// 2025-11-25. When off, every request is served as today, including one that
285/// asks for 2026-07-28, so modern clients keep falling back to `initialize`.
286pub const ENABLE_MCP_PROTOCOL_2026_07_28: Config<bool> = Config::new(
287    "enable_mcp_protocol_2026_07_28",
288    true,
289    "Whether the MCP endpoints serve the 2026-07-28 protocol revision alongside 2025-11-25. When false, requests are served on the 2025-11-25 protocol only.",
290    ParameterScope::Environment,
291);
292
293/// Whether the unified MCP endpoint at `/api/mcp` is enabled. Separate from the
294/// `/api/mcp/agent` and `/api/mcp/developer` flags, so each route rolls out on
295/// its own.
296pub const ENABLE_MCP_UNIFIED: Config<bool> = Config::new(
297    "enable_mcp_unified",
298    false,
299    "Whether the unified MCP HTTP endpoint is enabled. When false, requests to /api/mcp return 503 Service Unavailable.",
300    ParameterScope::Environment,
301);
302
303/// Whether the external metrics endpoint on environmentd is enabled.
304pub const ENABLE_PUBLIC_METRICS_ENDPOINT: Config<bool> = Config::new(
305    "enable_public_metrics_endpoint",
306    true,
307    "Whether the external metrics endpoint on environmentd is enabled. When false, requests return 503.",
308    ParameterScope::Environment,
309);
310
311/// Maximum size (in bytes) of MCP tool response content after JSON serialization.
312/// Responses exceeding this limit are rejected with a clear error telling the
313/// agent to narrow its query. Keeps responses within LLM context window limits.
314pub const MCP_MAX_RESPONSE_SIZE: Config<usize> = Config::new(
315    "mcp_max_response_size",
316    1_000_000,
317    "Maximum size in bytes of MCP tool response content. Responses exceeding this limit are rejected with an error telling the agent to narrow its query.",
318    ParameterScope::Environment,
319);
320
321/// Maximum time an MCP request may run before it is aborted and a timeout
322/// error is returned to the client.
323pub const MCP_REQUEST_TIMEOUT: Config<Duration> = Config::new(
324    "mcp_request_timeout",
325    Duration::from_secs(60),
326    "Maximum time an MCP request may run before it is aborted with a timeout error.",
327    ParameterScope::Environment,
328);
329
330/// Maximum size (in bytes) of a webhook request body, measured after
331/// decompression. Requests whose body exceeds this limit are rejected with
332/// HTTP 413. Applies only to the webhook route; other HTTP routes use a
333/// separate static limit.
334pub const WEBHOOK_MAX_REQUEST_SIZE_BYTES: Config<usize> = Config::new(
335    "webhook_max_request_size_bytes",
336    // Matches `MAX_REQUEST_SIZE`, the static limit the other environmentd HTTP routes use.
337    5 * 1024 * 1024,
338    "The maximum size in bytes of a webhook request body, measured after decompression.",
339    ParameterScope::Environment,
340);
341
342/// Maximum temporary storage a webhook `CHECK` expression may allocate while
343/// validating one request. A `CHECK` that exceeds it fails the request with HTTP
344/// 400 rather than holding the memory.
345///
346/// A `CHECK` can allocate a multiple of the request body, and `environmentd`
347/// evaluates one per in-flight request. Without a bound proportionate to the
348/// request, bounded network input becomes unbounded heap on a process shared by
349/// every connection. The default is 4x `WEBHOOK_MAX_REQUEST_SIZE_BYTES`, well
350/// above what a realistic `CHECK` (an HMAC, a `decode`, a `concat` with a
351/// secret) needs and well below the 100 MiB per-call ceiling used in a cluster.
352///
353/// NOTE: this is runtime-reconfigurable, so it must only bound a single webhook
354/// validation. Do not feed it (or any mutable budget) to a `RowArena` used in a
355/// compute dataflow (see `mz_repr::RowArena::with_budget`).
356pub const WEBHOOK_VALIDATION_MEMORY_BUDGET_BYTES: Config<usize> = Config::new(
357    "webhook_validation_memory_budget_bytes",
358    20 * 1024 * 1024,
359    "The maximum bytes of temporary storage a webhook CHECK expression may allocate while validating one request.",
360    ParameterScope::Environment,
361);
362
363/// Budget for the backlog a `SUBSCRIBE` (or `COPY (SUBSCRIBE ...) TO STDOUT`)
364/// may accumulate in environmentd while waiting for a slow client to read.
365///
366/// The subscribe producer runs on the non-blockable coordinator loop, so it
367/// cannot apply backpressure to a slow client. Instead the coordinator retires
368/// the subscribe once its buffered backlog exceeds this budget, bounding the
369/// memory a slow client can make the shared process hold.
370///
371/// The backlog excludes the message the client is currently draining, so this
372/// bounds the accumulation of messages, not the size of any single one.
373/// `max_result_size` is what bounds an individual message. A client that keeps
374/// up holds at most one message at a time, so it stays at a zero backlog and a
375/// large snapshot batch is delivered rather than retired.
376pub const SUBSCRIBE_MAX_BUFFERED_BYTES: Config<usize> = Config::new(
377    "subscribe_max_buffered_bytes",
378    128 * 1024 * 1024,
379    "Maximum bytes a SUBSCRIBE may buffer in environmentd for a slow client before it is retired with an error.",
380    ParameterScope::Environment,
381);
382
383/// Number of user IDs to pre-allocate in a batch. Pre-allocating IDs avoids
384/// a persist write + oracle call per DDL statement.
385pub const USER_ID_POOL_BATCH_SIZE: Config<u32> = Config::new(
386    "user_id_pool_batch_size",
387    512,
388    "Number of user IDs to pre-allocate in a batch for DDL operations.",
389    ParameterScope::Environment,
390);
391
392/// Maximum number of txns-shard write attempts before rebuilding `environmentd`.
393///
394/// The effective minimum is one attempt.
395pub const GROUP_COMMIT_MAX_ATTEMPTS: Config<usize> = Config::new(
396    "group_commit_max_attempts",
397    100,
398    "Maximum number of txns-shard write attempts before rebuilding environmentd. Values below 1 are treated as 1.",
399    ParameterScope::Environment,
400);
401
402/// OIDC client ID for the web console.
403pub const CONSOLE_OIDC_CLIENT_ID: Config<&'static str> = Config::new(
404    "console_oidc_client_id",
405    "",
406    "OIDC client ID for the web console.",
407    ParameterScope::Environment,
408);
409
410/// Space-separated OIDC scopes requested by the web console.
411pub const CONSOLE_OIDC_SCOPES: Config<&'static str> = Config::new(
412    "console_oidc_scopes",
413    "",
414    "Space-separated OIDC scopes requested by the web console.",
415    ParameterScope::Environment,
416);
417
418/// Interval at which to collect per-object arrangement size snapshots for the history table.
419pub const ARRANGEMENT_SIZE_HISTORY_COLLECTION_INTERVAL: Config<Duration> = Config::new(
420    "arrangement_size_history_collection_interval",
421    // Disabled by default until https://github.com/MaterializeInc/materialize/pull/37455 lands.
422    Duration::ZERO,
423    "Interval at which to collect and snapshot per-object arrangement sizes \
424     into mz_internal.mz_object_arrangement_size_history.",
425    ParameterScope::Environment,
426);
427
428/// How long to retain per-object arrangement size history.
429pub const ARRANGEMENT_SIZE_HISTORY_RETENTION_PERIOD: Config<Duration> = Config::new(
430    "arrangement_size_history_retention_period",
431    Duration::from_hours(7 * 24),
432    "How long to retain rows in mz_internal.mz_object_arrangement_size_history.",
433    ParameterScope::Environment,
434);
435
436/// How often to sweep replicas for completed object and replica hydration episodes.
437pub const HYDRATION_HISTORY_COLLECTION_INTERVAL: Config<Duration> = Config::new(
438    "hydration_history_collection_interval",
439    Duration::from_secs(60),
440    "How often to record completed object and replica hydration episodes. A zero duration prevents new collection and retention sweeps.",
441    ParameterScope::Environment,
442);
443
444/// How long to retain completed object hydration episodes.
445pub const HYDRATION_HISTORY_RETENTION_PERIOD: Config<Duration> = Config::new(
446    "hydration_history_retention_period",
447    Duration::from_hours(30 * 24),
448    "How long to retain rows in mz_internal.mz_object_hydration_history.",
449    ParameterScope::Environment,
450);
451
452/// How long to retain completed replica hydration episodes for capacity planning.
453pub const REPLICA_HYDRATION_HISTORY_RETENTION_PERIOD: Config<Duration> = Config::new(
454    "replica_hydration_history_retention_period",
455    Duration::from_hours(120 * 24),
456    "How long to retain rows in mz_internal.mz_replica_hydration_history.",
457    ParameterScope::Environment,
458);
459
460/// How frequently the catalog `*_info` metrics (`mz_object_info`,
461/// `mz_cluster_info`, …) are reconciled with the catalog. A zero duration
462/// disables reconciliation.
463pub const CATALOG_INFO_METRICS_RECONCILE_INTERVAL: Config<Duration> = Config::new(
464    "catalog_info_metrics_reconcile_interval",
465    Duration::from_secs(30),
466    "How frequently to reconcile the catalog `*_info` metrics with the catalog. A zero duration disables reconciliation.",
467    ParameterScope::Environment,
468);
469
470/// Server-side `statement_timeout` to set on Postgres/CRDB connections used by
471/// the Postgres/CRDB timestamp oracle. A zero value leaves the statement
472/// timeout unset.
473pub const PG_TIMESTAMP_ORACLE_STATEMENT_TIMEOUT: Config<Duration> = Config::new(
474    "pg_timestamp_oracle_statement_timeout",
475    crate::timestamp_oracle::DEFAULT_PG_TIMESTAMP_ORACLE_STATEMENT_TIMEOUT,
476    "The server-side statement timeout to set on Postgres/CRDB connections used by the \
477    Postgres/CRDB timestamp oracle. A value of zero leaves the statement timeout unset.",
478    ParameterScope::Environment,
479);
480
481/// Cadence of the cluster controller's reconcile tick.
482pub const CLUSTER_CONTROLLER_TICK_INTERVAL: Config<Duration> = Config::new(
483    "cluster_controller_tick_interval",
484    Duration::from_secs(5),
485    "How often the cluster controller runs a reconcile tick.",
486    ParameterScope::Environment,
487);
488
489/// Whether replacement compute must catch up before graceful cut-over or
490/// automatic hydration-burst retirement.
491///
492/// Enabled by default.
493pub const ENABLE_CLUSTER_RECONFIGURATION_LAG_GATE: Config<bool> = Config::new(
494    "enable_cluster_reconfiguration_lag_gate",
495    true,
496    "Whether graceful reconfiguration and hydration-burst retirement require surviving replicas \
497    to be within cluster_reconfiguration_allowed_lag of the retiring replicas, on top of being hydrated.",
498    ParameterScope::Environment,
499);
500
501/// Allowed compute lag for graceful reconfiguration and hydration-burst retirement.
502pub const CLUSTER_RECONFIGURATION_ALLOWED_LAG: Config<Duration> = Config::new(
503    "cluster_reconfiguration_allowed_lag",
504    Duration::from_secs(60),
505    "Maximum allowed lag when determining whether surviving compute replicas \
506    have caught up with replicas retired by graceful reconfiguration or hydration burst.",
507    ParameterScope::Environment,
508);
509
510/// Whether a config-shape `ALTER CLUSTER` returns immediately, with the
511/// controller converging in the background, or blocks the session on a
512/// wait-shim until the reconfiguration completes or its deadline passes.
513///
514/// Defaults on. This is the break-glass switch back to the blocking wait-shim
515/// if returning immediately causes trouble.
516pub const ENABLE_BACKGROUND_ALTER_CLUSTER: Config<bool> = Config::new(
517    "enable_background_alter_cluster",
518    true,
519    "Whether a config-shape ALTER CLUSTER returns immediately (true) or the session blocks on a wait-shim over the durable reconfiguration record (false).",
520    ParameterScope::Environment,
521);
522
523/// The reconfiguration deadline written when a config-shape `ALTER CLUSTER`
524/// omits `WITH (WAIT ...)`. What happens when the deadline passes un-hydrated is
525/// the record's `on_timeout` action.
526pub const DEFAULT_CLUSTER_RECONFIGURATION_TIMEOUT: Config<Duration> = Config::new(
527    "default_cluster_reconfiguration_timeout",
528    Duration::from_secs(60 * 60 * 24),
529    "The reconfiguration deadline written when a config-shape ALTER CLUSTER omits WITH (WAIT ...).",
530    ParameterScope::Environment,
531);
532
533/// Break-glass for the hydration-burst strategy: when off the controller never
534/// runs a burst replica; graceful reconfiguration and `ON REFRESH` scheduling
535/// are unaffected.
536///
537/// A cluster can only carry an `AUTO SCALING STRATEGY` while its SQL acceptance
538/// feature flag is on, so this is the second of the two gates burst sits
539/// behind.
540pub const ENABLE_HYDRATION_BURST: Config<bool> = Config::new(
541    "enable_hydration_burst",
542    true,
543    "Whether the cluster controller's hydration-burst strategy may run a burst replica (break-glass; leaves graceful reconfiguration and ON REFRESH untouched).",
544    ParameterScope::Environment,
545);
546
547/// The burst-replica linger duration written into a new `burst` record when the
548/// cluster's `AUTO SCALING STRATEGY` omits `LINGER DURATION`. The burst replica
549/// stays up this long after the steady-state replicas first hydrate.
550pub const DEFAULT_HYDRATION_BURST_LINGER: Config<Duration> = Config::new(
551    "default_hydration_burst_linger",
552    Duration::from_secs(0),
553    "The burst-replica linger duration written when an AUTO SCALING STRATEGY omits LINGER DURATION.",
554    ParameterScope::Environment,
555);
556
557/// Adds the full set of all adapter `Config`s.
558pub fn all_dyncfgs(configs: ConfigSet) -> ConfigSet {
559    configs
560        .add(&ALLOW_USER_SESSIONS)
561        .add(&CLUSTER_CONTROLLER_TICK_INTERVAL)
562        .add(&ENABLE_CLUSTER_RECONFIGURATION_LAG_GATE)
563        .add(&CLUSTER_RECONFIGURATION_ALLOWED_LAG)
564        .add(&ENABLE_BACKGROUND_ALTER_CLUSTER)
565        .add(&DEFAULT_CLUSTER_RECONFIGURATION_TIMEOUT)
566        .add(&ENABLE_HYDRATION_BURST)
567        .add(&DEFAULT_HYDRATION_BURST_LINGER)
568        .add(&WITH_0DT_DEPLOYMENT_MAX_WAIT)
569        .add(&WITH_0DT_DEPLOYMENT_DDL_CHECK_INTERVAL)
570        .add(&ENABLE_0DT_DEPLOYMENT_PANIC_AFTER_TIMEOUT)
571        .add(&WITH_0DT_DEPLOYMENT_CAUGHT_UP_CHECK_INTERVAL)
572        .add(&WITH_0DT_CAUGHT_UP_CHECK_ALLOWED_LAG)
573        .add(&WITH_0DT_CAUGHT_UP_CHECK_CUTOFF)
574        .add(&ENABLE_0DT_CAUGHT_UP_REPLICA_STATUS_CHECK)
575        .add(&ENABLE_0DT_CAUGHT_UP_STABILITY_CHECK)
576        .add(&WITH_0DT_CAUGHT_UP_CHECK_STABILITY_PERIOD)
577        .add(&ENABLE_0DT_HYDRATE_MIGRATED_BUILTIN_MVS)
578        .add(&ENABLE_STATEMENT_LIFECYCLE_LOGGING)
579        .add(&ENABLE_INTROSPECTION_SUBSCRIBES)
580        .add(&PLAN_INSIGHTS_NOTICE_FAST_PATH_CLUSTERS_OPTIMIZE_DURATION)
581        .add(&ENABLE_EXPRESSION_CACHE)
582        .add(&ENABLE_PASSWORD_AUTH)
583        .add(&READ_THEN_WRITE_MAX_DEPENDENCIES)
584        .add(&OIDC_ISSUER)
585        .add(&OIDC_AUDIENCE)
586        .add(&OIDC_AUTHENTICATION_CLAIM)
587        .add(&OIDC_GROUP_ROLE_SYNC_ENABLED)
588        .add(&OIDC_GROUP_CLAIM)
589        .add(&OIDC_GROUP_ROLE_SYNC_STRICT)
590        .add(&PERSIST_FAST_PATH_ORDER)
591        .add(&ENABLE_S3_TABLES_REGION_CHECK)
592        .add(&ENABLE_MCP_AGENT)
593        .add(&ENABLE_MCP_AGENT_QUERY_TOOL)
594        .add(&ENABLE_MCP_AGENT_READ_DATA_PRODUCT_TOOL)
595        .add(&ENABLE_MCP_DEVELOPER)
596        .add(&ENABLE_MCP_DEVELOPER_QUERY_TOOL)
597        .add(&ENABLE_MCP_PROTOCOL_2026_07_28)
598        .add(&ENABLE_MCP_UNIFIED)
599        .add(&ENABLE_PUBLIC_METRICS_ENDPOINT)
600        .add(&MCP_MAX_RESPONSE_SIZE)
601        .add(&MCP_REQUEST_TIMEOUT)
602        .add(&WEBHOOK_MAX_REQUEST_SIZE_BYTES)
603        .add(&WEBHOOK_VALIDATION_MEMORY_BUDGET_BYTES)
604        .add(&SUBSCRIBE_MAX_BUFFERED_BYTES)
605        .add(&USER_ID_POOL_BATCH_SIZE)
606        .add(&GROUP_COMMIT_MAX_ATTEMPTS)
607        .add(&CONSOLE_OIDC_CLIENT_ID)
608        .add(&CONSOLE_OIDC_SCOPES)
609        .add(&ARRANGEMENT_SIZE_HISTORY_COLLECTION_INTERVAL)
610        .add(&ARRANGEMENT_SIZE_HISTORY_RETENTION_PERIOD)
611        .add(&HYDRATION_HISTORY_COLLECTION_INTERVAL)
612        .add(&HYDRATION_HISTORY_RETENTION_PERIOD)
613        .add(&REPLICA_HYDRATION_HISTORY_RETENTION_PERIOD)
614        .add(&CATALOG_INFO_METRICS_RECONCILE_INTERVAL)
615        .add(&PG_TIMESTAMP_ORACLE_STATEMENT_TIMEOUT)
616}