Runtime Settings
Most configuration flags bind once at startup. A curated subset can be
overridden at runtime via the /admin/settings page, the mr admin settings
CLI, or the /v1/admin/settings HTTP API -- no restart required.
How precedence works
- Boot flag / env var supplies the initial value.
- If the
runtime_settingstable has a row for the key, that override wins. - When an override differs from the boot value (flag, env var, or built-in default), one WARN line is logged at startup so operators are not silently surprised.
Reset via the UI (Reset button), CLI (mr admin settings reset <key>), or API
(DELETE /v1/admin/settings/<key>) removes the override and returns to the
boot value.
Runtime-editable settings
| Key | Type | Bounds | Boot flag | Takes effect |
|---|---|---|---|---|
max_upload_size | int64 (bytes) | 1 KiB–1 TiB; 0 = unlimited | -max-upload-size | next upload request |
upload_concurrency | int | 1–16 | (runtime only) | next page render |
upload_widget_file_threshold | int | 1–10000 | (runtime only) | next page render |
upload_widget_size_threshold | int64 (bytes) | 1 MiB–1 TiB | (runtime only) | next page render |
max_import_size | int64 (bytes) | 1 MiB–1 TiB | -max-import-size | next import parse |
mrql_default_limit | int | 1–100000 | -mrql-default-limit | next MRQL query |
mrql_page_query_budget | int | 0–100000; 0 disables | -mrql-page-query-budget | next page render |
mrql_query_timeout | duration | 100ms–5m | -mrql-query-timeout | next MRQL query |
export_retention | duration | 1m–30d | -export-retention | next sweep + UI disclosure |
remote_connect_timeout | duration | 1s–10m | -remote-connect-timeout | next remote download |
remote_idle_timeout | duration | 1s–1h | -remote-idle-timeout | next remote download |
remote_overall_timeout | duration | 10s–24h | -remote-overall-timeout | next remote download |
remote_user_agent | string | at most 8192 bytes, no control characters; empty = browser-like default | -remote-user-agent | next remote download |
download_failed_retention | duration | 1h–365d | -download-failed-retention | next history sweep |
download_history_retention | duration | 1h–365d | -download-history-retention | next history sweep |
download_cockpit_limit | int | 1–200 | -download-cockpit-limit | next jobs-panel render |
share_public_url | string (http/https URL) | absolute http/https URL; empty = relative /s/<token> only | -share-public-url | next share link render |
docs_site_base_url | string (http/https URL) | absolute; non-empty host | -docs-site-base-url | next page render |
docs_links_disabled | int | 0–1; 1 hides links | -docs-links-disabled | next page render |
hash_similarity_threshold | int | 0–11 (v2 pairs stored up to distance 11) | -hash-similarity-threshold | next hash comparison |
hash_ahash_threshold | uint64 | 0–64; 0 disables | -hash-ahash-threshold | next hash comparison |
hash_backfill_paused | int | 0–1; 1 pauses the v2 backfill | (runtime only) | next backfill cycle |
Metadata index build status
Indexed keys are configured in each resource category, group category, or note type editor, alongside its metadata schema. See indexed metadata keys.
The Metadata index builds section on this page shows background build status
and errors. GET /v1/admin/settings/metadata-index-status exposes the same status
for administrators. Saved category changes are normally picked up within five
seconds. Failed builds retry after a minute; each reconciliation has a 30-minute
budget. PostgreSQL concurrent builds interrupted by shutdown are repaired on
retry or restart.
Bulk resource uploads
max_upload_size bounds one request body. That distinction matters on the
create-resource page, which has two ways of submitting:
- Native post - the browser sends every selected file in one multipart body,
so
max_upload_sizecaps the batch as a whole. - Client-side widget - above
upload_widget_file_thresholdfiles orupload_widget_size_thresholdbytes, the page sends one request per file,upload_concurrencyat a time, with a progress bar and per-file errors. Each file is then capped individually, and the widget refuses an oversized file in the browser rather than spending the transfer to be rejected.
All three are read when the create-resource page renders and embedded in the form, so a change applies to the next page load rather than to an upload already in flight.
Set upload_widget_file_threshold to 1 to put every multi-file selection
through the widget. SQLite has exactly one writer, so upload_concurrency above
about 3 buys little there; Postgres tolerates more.
Audit trail
Every change writes a row to log_entries with entity_type=runtime_setting,
the key as entity_name, old→new values in message, and the request IP in
ip_address. Visible at /logs (filter entity type runtime_setting), or via
GET /v1/logs.
CLI reference
See mr admin settings.