Skip to main content

Configuration

Insights uses a layered configuration system. Every setting can be specified through CLI flags, environment variables, or a YAML config file.

Priority Order​

When the same setting is defined in multiple places, the highest-priority source wins:

  1. CLI flags (e.g., --server nats://host:4222)
  2. Environment variables (e.g., INSIGHTS_NATS_SERVER=nats://host:4222)
  3. YAML config file (via --config, INSIGHTS_CONFIG, or a default search path; see Config File)
  4. Built-in defaults

Config File​

--config (or -c) is a global flag, so every subcommand can be driven from one file, not just the server. This matters with the default embedded NATS sink: the server serves its API on sink.port, and insights db query reaches it via the top-level nats: section. Pin both in one file and point every command at it:

# config.yaml
sink:
port: 4222 # server binds the embedded NATS here
nats:
server: nats://127.0.0.1:4222 # clients (query, checks, ops, ...) connect here
insights -c config.yaml # run the server
insights db query -c config.yaml "SELECT 1" # query it — no --server needed

The config file is found from three sources, each optional, in increasing precedence (later wins):

  1. <user-config-dir>/insights/config.yaml, e.g. ~/.config/insights/config.yaml on Linux, ~/Library/Application Support/insights/config.yaml on macOS.
  2. ./insights.yaml, auto-discovered in the working directory.
  3. INSIGHTS_CONFIG, an explicit path set via the environment.

An explicit --config/-c flag overrides all of these. With a file at one of the default locations, a bare insights db query "SELECT 1" works with no flags. Per-setting environment variables (INSIGHTS_*) still override any config file (see Priority Order).

Note: ./insights.yaml is read from the current working directory, so any directory you run insights from can supply configuration (as with git, cargo, and similar tools). Avoid running insights from untrusted or world-writable directories, or pass --config explicitly. CLI flags and INSIGHTS_* environment variables always override the file.

Keys the configuration does not define are ignored without a warning, and insights config check does not report them either, so a misspelled or removed key leaves its setting at the default. Compare a file against the sections below when a value seems to have no effect.

For a complete annotated example, see config.example.yaml.

Environment Variable Naming​

Every flag has a corresponding environment variable. The naming convention is:

  • Start with the INSIGHTS_ prefix
  • Replace dots with underscores
  • Convert to uppercase
FlagEnvironment Variable
--log-levelINSIGHTS_LOG_LEVEL
--data-dirINSIGHTS_DATA_DIR
--serverINSIGHTS_NATS_SERVER
--sys.credsINSIGHTS_SYS_CREDS
--scraper.intervalINSIGHTS_SCRAPER_INTERVAL
--web.portINSIGHTS_WEB_PORT
--db.retention.durationINSIGHTS_DB_RETENTION_DURATION
--sink.retentionINSIGHTS_SINK_RETENTION
--simulatorINSIGHTS_SIMULATOR

Nested sections add their prefix. For example, a scraper NATS connection uses INSIGHTS_SCRAPER_NATS_SERVER.

Subsystem Toggles​

Each subsystem is switched on or off with a shorthand named after it: --scraper, --indexer, --web, --simulator, --prometheus, --updater, --telemetry on the command line, INSIGHTS_SCRAPER, INSIGHTS_WEB, INSIGHTS_UPDATER, … in the environment. YAML is the exception: a section is a map there, so it keeps using its own enabled: key.

./insights --simulator --web=false --updater=false
INSIGHTS_SIMULATOR=true INSIGHTS_WEB=false INSIGHTS_UPDATER=false ./insights
web:
enabled: false
updater:
enabled: false

The verbose forms are accepted too: --web.enabled=false (hidden from --help) and INSIGHTS_WEB_ENABLED=false. The shorthand is applied last, so it wins when both are set: INSIGHTS_WEB=false with INSIGHTS_WEB_ENABLED=true leaves the web server off. A command-line flag still beats both environment variables.

The tables below list the shorthand as the CLI and environment form for each toggle; the YAML key is unchanged.

Configuration Sections​

log-level​

Controls logging verbosity. Accepted values: debug, info, warn, error.

FlagEnvDefault
--log-levelINSIGHTS_LOG_LEVELinfo

license​

License key for a trial build. Provide either a raw JWT string or a path to a file containing the JWT. If both are set, the file takes precedence.

A trial build requires a license unless the simulator is enabled (--simulator) or the node runs neither the indexer nor the scraper, such as insights web. Other builds require no license; leave this section unset there, since a license that is set is still verified at startup. For trials and expiry, see Licensing & Trial.

FlagEnvDefault
--license.tokenINSIGHTS_LICENSE_TOKEN(empty)
--license.fileINSIGHTS_LICENSE_FILE(empty)

data-dir​

Base directory for persistent storage. This directory holds the DuckDB database file (insights.db, or one systems/<id>.db per system on a node with several systems) and the embedded server's JetStream data (nats/).

When unset, a temporary directory is created and all data is lost on restart. Set this for any deployment where you want data to survive restarts.

FlagEnvDefault
--data-dirINSIGHTS_DATA_DIR(temp dir)

node.*: Node Identity​

Names this process. The node id addresses process diagnostics on the node-scoped API space ($INS.node.<id>.ops.pprof, $INS.node.<id>.ops.version, ...) and serves as a stable label for operator tooling, so it must survive restarts and deploys.

Defaults to the id of the system this node serves, which is operator-assigned and therefore survives a reschedule. A node serving several systems has no single id to borrow and must be named; a node serving none (a web node) falls back to the hostname, sanitized to a subject-safe token. Allowed characters: letters, digits, _, -.

Systems servedDefault
one (either config shape)that system's id
several (systems: list)none; node.id is required
none (web-only node)hostname (sanitized)
FlagEnvDefault
--node.idINSIGHTS_NODE_IDsee above

Two processes serving the same system must be named apart. Insights checks this at startup over $INS.ping and refuses to start on a clash rather than letting two nodes answer for one identity.

Labels. node.metadata is a map of operator-assigned labels describing where the process runs (region, rack, ...). They are reported on $INS.ping, so insights node list and the web UI can filter and group nodes by them; nothing addresses a subject with them. Keys allow letters, digits, _, - and . (up to 64 characters); values are free text without control characters (up to 256 characters); at most 16 pairs. An invalid label fails startup. node.metadata is YAML-only.

node:
id: central
metadata:
region: us-east-1
rack: b12

system.*: System Identity​

Names the monitored NATS system. The system id addresses everything that belongs to the system on the system-scoped API space ($INS.sys.<id>.db.query, $INS.sys.<id>.checks.list, ...). It is operator-assigned: no stable NATS system identifier can be derived (cluster names break on superclusters; system-account nkeys collapse for leaf nodes sharing a hub's system account). Allowed characters: letters, digits, _, -.

FlagEnvDefault
--system.idINSIGHTS_SYSTEM_IDdefault

Labels. system.metadata labels the monitored system (env, team, ...) on the same terms as node.metadata. Declare them where the system is scraped: a node that indexes a system without scraping it (a collector fills its stream) refuses to start with system.metadata set, because the collector describes the system. system.metadata is YAML-only.

The client subcommands read the same system.id / node.id keys from a shared config file to pick their target; their own --system/--node flags and INSIGHTS_SYSTEM/INSIGHTS_NODE envs (distinct from the server's INSIGHTS_SYSTEM_ID/INSIGHTS_NODE_ID) override them. See CLI → Selecting a system or node.

systems: Multiple Systems​

One instance can own several monitored systems. Each gets its own DuckDB instance (<data-dir>/systems/<id>.db), its own JetStream stream, its own indexer, and its own $INS.sys.<id>.* API. Nothing is shared or steered between them. Set the systems: list only on a node monitoring more than one system; a single-system node (the usual deployment, a collector, a federated site node) keeps the flat system:/sys:/scraper:/sink: config and leaves systems: empty.

For a collector-fed system (a systems: entry with no scrape: block), the stream is filled by a NATS mirror rather than a local scraper. See Federated Deployment for the collector, the leafnode setup, and the central node's mirror.

The list is YAML-only (there are no --systems.* flags). It is mutually exclusive with the flat single-system config: setting systems: together with a non-default system.id, a sys.* connection, or leaving indexer.enabled off is a config error (a node with a systems: list always indexes every listed system). The simulator cannot run with systems:.

Each entry:

KeyDefaultDescription
id(required)System identifier ($INS.sys.<id>.*, stream naming). Subject-safe token; unique across the list.
scrape.nats.*(none)Connection to the monitored system. Present ⇒ this node scrapes it (outbound-scraper mode); absent ⇒ collector-fed (a mirror fills its stream and this node only indexes). Same fields as sys.*.
scrape.intervalscraper.intervalScrape cadence for this system.
scrape.timeoutscraper.timeoutScrape request timeout.
retentionsink.retentionStream buffer depth. The database keeps history; this bounds the ingest buffer only. Enforced by pruning whole epochs, not by the stream's max_age.
stream.namescrape_<id> / mirror_<id>JetStream stream name: mirror_<id> for a collector-fed entry, scrape_<id> for one this node scrapes. Override only to adopt a stream an operator already built. The subject prefix is never configured here: a scraper on this node publishes under $INS.sys.<id>.scrape, and a collector-fed mirror declares its origin namespace in mirror.filter_subject.
stream.replicassink.replicasStream replica count. Requires a clustered sink.
stream.storagesink.storageStream storage class, file or memory.
mirror-api-prefix(none)Route to a collector-fed origin's JetStream API when it is not reached by a JetStream domain, such as a subject mapping or account import under a prefix of your choosing. A domain needs nothing here: the collector reports its own over $INS.sys.<id>.ops.sink.info. Rejected on an entry with a scrape: block.
metadata(none)Labels for this system, on the same terms as system.metadata. Allowed only on an entry with a scrape: block; a collector-fed system is labeled by its collector.
db.memory-limittop-level db.memory-limitPer-instance DuckDB buffer-pool cap. Each system has its own pool, so this is a per-instance value, not a shared budget.
db.threadstop-level db.threadsPer-instance DuckDB worker threads.
check-thresholdstop-level check-thresholdsPer-system check overrides, merged per check code onto the top-level set.
disabled-checkstop-level disabled-checksCheck codes this system turns off, unioned with the top-level list. An entry can add codes; it cannot re-enable one the top level disabled.

Still node-wide (not per-entry): data-dir, node, nats (the API connection), sink.embed, web, log-level, license, updater, and db.retention (the database's epoch-retention sweep). The top-level db: section is the per-instance default that each entry overrides.

On a node serving several systems:

  • Webhook endpoints are node-wide but scopable per system. A node serving several systems delivers every system's alerts to every endpoint by default; each alert carries a system label and each delivery-log entry records which system it was for. Scope an endpoint to a subset with its systems: field (see notifications).
  • The ops PostgreSQL attach (INSIGHTS_DB_ATTACH) is single-system only: it is applied only in the flat config, never with a systems: list.

sys.*: System Account Connection​

NATS connection used to scrape the target NATS system. Insights issues $SYS requests over this connection to collect server metrics. This is required when the simulator is disabled.

FlagEnvDescription
--sys.serverINSIGHTS_SYS_SERVERNATS server URL
--sys.credsINSIGHTS_SYS_CREDSPath to credentials file (.creds)
--sys.contextINSIGHTS_SYS_CONTEXTNATS context name (from nats context)
--sys.userINSIGHTS_SYS_USERUsername for basic auth
--sys.passwordINSIGHTS_SYS_PASSWORDPassword for basic auth
--sys.nkeyINSIGHTS_SYS_NKEYNKey seed for authentication
--sys.jwtINSIGHTS_SYS_JWTUser JWT for authentication
--sys.tls-certINSIGHTS_SYS_TLS_CERTTLS certificate path
--sys.tls-keyINSIGHTS_SYS_TLS_KEYTLS key path
--sys.tls-ca-certINSIGHTS_SYS_TLS_CA_CERTTLS CA certificate path
--sys.tls-firstINSIGHTS_SYS_TLS_FIRSTPerform TLS handshake before NATS protocol
--sys.socks-proxyINSIGHTS_SYS_SOCKS_PROXYSOCKS proxy URL
--sys.inbox-prefixINSIGHTS_SYS_INBOX_PREFIXRequest/reply inbox prefix (default _INBOX)

Inbox prefix. Leave inbox-prefix empty unless the account is not granted _INBOX.>, a common least-privilege setup on Synadia Cloud. Every reply Insights receives lands under this prefix, so the account must allow subscribing to <prefix>.>.

System account permissions. When using a dedicated user JWT instead of the full system account credentials, see the deployment guide for the required granular subject permissions.

nats.*: Top-Level NATS Connection​

NATS connection used by the API server and as the default for the indexer and scraper if they do not specify their own connections.

This connection is only needed when using an external NATS sink (--sink.embed=false). When the embedded sink is enabled (the default), Insights manages its own internal NATS server automatically.

The flags mirror sys.* above: drop the sys. prefix to get the nats-CLI-style client flags (e.g., --server, --creds, --context), with matching environment variables (--server reads INSIGHTS_NATS_SERVER) and YAML under nats:. The --nats.* spellings (--nats.server, ...) are accepted as hidden aliases.

Connection fallback order: the indexer uses indexer.nats, or the top-level nats if that is unset. The scraper uses scraper.nats, then the indexer's connection, then the top-level nats.

db.*: Database​

DuckDB configuration options.

FlagEnvDefaultDescription
--db.memory-limitINSIGHTS_DB_MEMORY_LIMIT4GiBDuckDB memory limit. Caps the buffer pool to prevent swapping
--db.threadsINSIGHTS_DB_THREADS0DuckDB worker threads (0 = auto, uses all cores)
--db.retention.durationINSIGHTS_DB_RETENTION_DURATION768hHow long to keep data in DuckDB (0 = disabled)
--db.retention.intervalINSIGHTS_DB_RETENTION_INTERVAL10mMinimum time between retention sweeps; a sweep runs right after the first epoch commit past it
--db.memory-profile.enabledINSIGHTS_DB_MEMORY_PROFILE_ENABLEDtrueEnable the live DuckDB memory profiler (samples duckdb_memory() for ops sizing / ops memory)
--db.memory-profile.intervalINSIGHTS_DB_MEMORY_PROFILE_INTERVAL2sMemory profiler sampling interval
--db.memory-profile.windowINSIGHTS_DB_MEMORY_PROFILE_WINDOW15mMemory profiler rolling window (peak + chart history)
--db.query-timeoutINSIGHTS_DB_QUERY_TIMEOUT2mMax duration for a single $INS.db.query statement (0 = unlimited)
--db.query-max-rowsINSIGHTS_DB_QUERY_MAX_ROWS100000Max rows the non-streaming $INS.db.query may return; a larger result is rejected with a 413 pointing at the streaming endpoint (0 = unlimited)
--db.query-stream.windowINSIGHTS_DB_QUERY_STREAM_WINDOW16Max unacknowledged stream chunks in flight (credit window)
--db.query-stream.chunk-sizeINSIGHTS_DB_QUERY_STREAM_CHUNK_SIZE512KiBTarget size of each streamed Arrow chunk
--db.query-stream.batch-timeoutINSIGHTS_DB_QUERY_STREAM_BATCH_TIMEOUT30sMax time to produce each stream batch (0 = unlimited)
--db.query-stream.ack-idle-timeoutINSIGHTS_DB_QUERY_STREAM_ACK_IDLE_TIMEOUT30sAbort a stream if the client stops acknowledging (0 = unlimited)
--db.query-stream.compressionINSIGHTS_DB_QUERY_STREAM_COMPRESSIONnoneStream chunk compression: none, lz4, or zstd (uses additional CPU)
--db.query-stream.max-rowsINSIGHTS_DB_QUERY_STREAM_MAX_ROWS1000000Abort a streamed query after this many rows, a safety limit for runaway unscoped scans (0 = unlimited)

The $INS.db.query.stream endpoint streams results as windowed Apache Arrow chunks so neither side buffers the whole result; insights db query uses it automatically. --db.query-max-rows caps only the non-streaming $INS.db.query endpoint. See API Reference → Query Endpoints for the wire protocol.

scraper.*: Scraper​

Controls how Insights collects metrics from NATS servers.

FlagEnvDefaultDescription
--scraperINSIGHTS_SCRAPERtrueEnable or disable the scraper
--scraper.intervalINSIGHTS_SCRAPER_INTERVAL1mTime between scrape cycles
--scraper.timeoutINSIGHTS_SCRAPER_TIMEOUT30sTimeout for individual scrape requests
--scraper.filter.allow.serversINSIGHTS_SCRAPER_FILTER_ALLOW_SERVERS(empty)Scrape only servers with these exact names
--scraper.filter.allow.clustersINSIGHTS_SCRAPER_FILTER_ALLOW_CLUSTERS(empty)Scrape only servers in these exact clusters
--scraper.filter.allow.tagsINSIGHTS_SCRAPER_FILTER_ALLOW_TAGS(empty)Scrape only servers carrying these exact tags
--scraper.filter.deny.serversINSIGHTS_SCRAPER_FILTER_DENY_SERVERS(empty)Never scrape servers with these exact names
--scraper.filter.deny.clustersINSIGHTS_SCRAPER_FILTER_DENY_CLUSTERS(empty)Never scrape servers in these exact clusters
--scraper.filter.deny.tagsINSIGHTS_SCRAPER_FILTER_DENY_TAGS(empty)Never scrape servers carrying these exact tags

The scraper optionally accepts its own NATS connection via --scraper.nats.* flags, falling back to the indexer NATS and then the top-level NATS connection.

Server filter. By default every discovered server is scraped. The --scraper.filter.* lists restrict the scrape set by exact match on server name, cluster name, or tag. Deny takes precedence over allow, and when any allow list is set a server must match it to be scraped. Excluded servers receive no monitoring requests at all. Only the unavoidable discovery PING and the account-scoped ACCSTATZ broadcast reach them, and their replies to those are dropped before storage.

indexer.*: Indexer​

Controls how scraped data is processed and stored in DuckDB.

FlagEnvDefaultDescription
--indexerINSIGHTS_INDEXERtrueEnable or disable the indexer
--indexer.stream-latestINSIGHTS_INDEXER_STREAM_LATESTfalseStart consuming from the latest message
--indexer.stream-epochINSIGHTS_INDEXER_STREAM_EPOCH0Start consuming from a specific epoch number
--indexer.stream-filtersINSIGHTS_INDEXER_STREAM_FILTERS(empty)Comma-separated list of endpoints to process (e.g., varz,jsz,connz)
--indexer.stream-intervalINSIGHTS_INDEXER_STREAM_INTERVAL0sDownsample interval: skip epochs closer together than this

web.*: Web Server​

Controls the built-in web UI and HTTP server.

FlagEnvDefaultDescription
--webINSIGHTS_WEBtrueEnable or disable the web server
--web.hostnameINSIGHTS_WEB_HOSTNAME127.0.0.1Bind hostname (0.0.0.0 for all interfaces)
--web.portINSIGHTS_WEB_PORT8080Bind port
--web.session-seedINSIGHTS_WEB_SESSION_SEEDinsightsSeed for secure session cookies
--web.tlsINSIGHTS_WEB_TLSfalseEnable TLS (HTTPS). HTTP/2 is automatically available via ALPN
--web.tls-certINSIGHTS_WEB_TLS_CERT(empty)Path to TLS certificate (PEM). Required when --web.tls is set
--web.tls-keyINSIGHTS_WEB_TLS_KEY(empty)Path to TLS private key (PEM). Required when --web.tls is set
--web.tls-ca-certINSIGHTS_WEB_TLS_CA_CERT(empty)Path to TLS CA certificate for verifying client certificates
--web.external-urlINSIGHTS_WEB_EXTERNAL_URL(empty)Public base URL of this instance (e.g. https://insights.example.com); used to build links in notification alert payloads

TLS behavior: TLS is disabled by default. When enabled (--web.tls), you must supply your own certificate and key (--web.tls-cert / --web.tls-key); enabling TLS without them fails at startup. Insights does not generate a self-signed certificate.

Session seed: The default value "insights" preserves sessions across restarts but should be changed to a unique secret for production deployments.

sink.*: Embedded Sink​

Controls the embedded NATS server used for storing scraped data as a JetStream stream.

FlagEnvDefaultDescription
--sink.embedINSIGHTS_SINK_EMBEDtrueUse the embedded NATS server
--sink.config-fileINSIGHTS_SINK_CONFIG_FILE(empty)NATS server config file for the embedded server. The file must exist; it is parsed first and Insights applies its own settings on top
--sink.hostINSIGHTS_SINK_HOST127.0.0.1Bind host for the embedded server
--sink.portINSIGHTS_SINK_PORT0Bind port (0 = random)
--sink.streamINSIGHTS_SINK_STREAMscrapeJetStream stream name. insights-collector derives scrape_<system.id> from the system id when this is left at the default, so a central node mirroring the collector lands on the same name
--sink.batch-sizeINSIGHTS_SINK_BATCH_SIZE500Batch size for sink operations
--sink.retentionINSIGHTS_SINK_RETENTION24hHow long to keep scraped data in the sink stream (0 = unlimited). Enforced by pruning whole epochs, not by the stream's max_age, since a message-level limit would leave the indexer a scrape truncated mid-epoch
--sink.replicasINSIGHTS_SINK_REPLICAS1Stream replica count. Requires a clustered sink; rejected with --sink.embed
--sink.storageINSIGHTS_SINK_STORAGEfileStream storage class: file or memory

Set --sink.embed=false to use an external NATS cluster with JetStream instead of the embedded server. See the deployment guide for external sink topologies.

simulator.*: Simulator​

The built-in simulator starts real in-process NATS clusters with traffic workloads, allowing you to explore Insights with zero external dependencies.

FlagEnvDefaultDescription
--simulatorINSIGHTS_SIMULATORfalseEnable the embedded simulator
--simulator.profileINSIGHTS_SIMULATOR_PROFILEjs-smallSimulator profile

Available profiles control the size and topology of the simulated deployment:

Profile FamilyVariantsDescription
core-small, medium, largeCore NATS servers
js-small, medium, largeNATS with JetStream
super-small, medium, largeSuper-cluster topology
leaf-small, medium, largeLeaf node topology
super-leaf-small, medium, largeSuper-cluster with leaf nodes

prometheus.*: Prometheus Metrics​

Controls the Prometheus-compatible /metrics endpoint. See the Metrics reference for the full list of exported metrics.

FlagEnvDefaultDescription
--prometheusINSIGHTS_PROMETHEUStrueEnable the metrics endpoint
--prometheus.hostnameINSIGHTS_PROMETHEUS_HOSTNAME127.0.0.1Bind hostname
--prometheus.portINSIGHTS_PROMETHEUS_PORT9091Bind port
--prometheus.aggregateINSIGHTS_PROMETHEUS_AGGREGATEfalseServe every node's metrics from this endpoint, not just this node's
--prometheus.timeoutINSIGHTS_PROMETHEUS_TIMEOUT2sBudget for one aggregated collection. Ignored unless aggregating

By default /metrics serves only the metrics of the node serving it. aggregate makes that one endpoint answer for the whole deployment: each scrape discovers the nodes over $INS.ping and asks each one for its snapshot. Enable it on exactly one node. Scraping two aggregators reports every series twice, once per endpoint, and a sum() over them double-counts. insights prometheus serves the same thing as a standalone process for when the scrape target should not be a full node.

updater.*: Version Checker​

Periodically checks GitHub for a newer release and notifies via a log message and a badge in the web UI. Does not download or replace the binary. The release repository is compiled into the binary, so there is no URL or channel to configure. See Version Updates.

FlagEnvDefaultDescription
--updaterINSIGHTS_UPDATERtrueEnable version checking
--updater.intervalINSIGHTS_UPDATER_INTERVAL1hInterval between update checks

telemetry.*: Product Telemetry​

Trial builds send a small usage pulse on this interval, the first at startup. Other builds contain no reporter, and these settings parse but do nothing there. There is no destination setting: where a pulse goes is fixed when the binary is built. See Telemetry for every field a pulse carries.

FlagEnvDefaultDescription
--telemetryINSIGHTS_TELEMETRYtrueSend product telemetry
--telemetry.intervalINSIGHTS_TELEMETRY_INTERVAL5mInterval between pulses. Must be positive while telemetry is on
--telemetry.printINSIGHTS_TELEMETRY_PRINTfalseLog every pulse, so you can read exactly what leaves the process

insights web takes only the on/off switch: it sends no pulse of its own, and switching it off stops it passing UI usage to the nodes that report it.

check-thresholds​

Per-check threshold overrides. Many checks accept one or more tunable parameters (e.g. a CPU percentage, a lag interval, a byte size) that control when the check produces a finding. Defaults suit most deployments, but production environments often need different thresholds.

Overrides are keyed by check code and parameter name. The parameter names and default values for each check are listed in the Checks Reference; any value shown as a backtick-quoted identifier in the Threshold column (e.g. `cpu_percent`) is tunable here.

Configure overrides in your YAML config file:

check-thresholds:
server-003:
cpu_percent: 80 # flag servers above 80% CPU (default: 90)
stream-002:
lag_percent: 20 # flag replica lag above 20% (default: 10)
stream-022:
max_memory: 500 MiB # memory-backed streams > 500 MiB

Duration parameters accept Go duration strings (e.g. 50ms, 5m, 24h). A parameter that bounds a window measured across scrapes (a persistence or lookback window such as system-009's sustain or system-004's window) must be greater than or equal to the scrape interval, since a shorter window can never span two scrapes; insights serve fails to start with a validation error otherwise on a node that scrapes the system. insights config check does not apply this floor. A duration compared against a value sampled within one scrape, such as an RTT threshold, carries no such floor.

Size parameters accept IEC binary strings (e.g. 64 KiB, 1 MiB, 10 GiB; powers of 1024). A bare number is an exact byte count, so 1 MiB and 1048576 configure the same threshold. Write sizes in IEC units (MiB, GiB), not SI suffixes (MB, GB).

Optimization checks also accept a special lookback parameter that controls the analysis window for range-based checks:

check-thresholds:
account-011:
lookback: 4h

Unknown parameter names and check codes fail startup with an error naming the entry, and insights config check reports the same errors without starting the node. A code written in the uppercase, underscored form (SERVER_003) is reported with its current spelling (server-003); a code that matches no check in either spelling is reported as unknown, so find its replacement with insights checks list. An unknown parameter is reported with the parameter names the check accepts, or with its replacement when it is a renamed one. lookback is accepted only on optimization checks. A retired check code (server-049) is accepted with a warning and its values are ignored.

Threshold overrides are a YAML-only setting; there is no equivalent command-line flag or environment variable. Use --config to load a YAML file that contains your overrides.

disabled-checks​

A list of check codes this instance turns off. Use it for a check that cannot be acted on in your topology: one that is structurally true of your deployment rather than a symptom of anything, where no threshold value would make it meaningful.

disabled-checks:
- account-012

A disabled check keeps running and keeps its history. It is shown everywhere it would otherwise appear (the findings grids, the check catalog, entity pages, the health timeline, insights checks list, insights checks info and insights checks findings), marked disabled, with its real findings. The checks.list, checks.info and checks.findings endpoints, and the MCP tools over them, carry the same fact as disabled: true. What changes is that it is not graded and not delivered:

  • The category and overall health percentages leave it out on both sides. Its findings do not count as firing and its entities do not count as applicable, so a check you have decided not to act on cannot move the score either way. The health timeline's stat cards (current, new, resolved, flapping) leave it out the same way.
  • Nothing it finds becomes a notification. Its findings never enter the findings tracker, so no advisory is published and no webhook or alert is delivered, and nothing is re-sent on the standing-alert cadence. Turning it off does not send a resolve for anything it had firing: the condition is still true, only the delivery stopped. The Notifications page marks a subscription to a disabled check so the silence is not read as health.

Unknown check codes fail startup with an error naming the entry. A code in the uppercase, underscored form (ACCOUNT_012) is reported with its current spelling; any other unknown code is reported as unknown. A retired code is accepted with a warning and has no effect. insights config check runs the same validation without starting the node.

On a node with several systems, a systems: entry's list is unioned with the top-level list: an entry adds codes for its own system and can never re-enable one disabled at the top level.

disabled-checks is a YAML-only setting; there is no equivalent command-line flag or environment variable.

notifications​

Outbound notification endpoints. When a check changes state (fires or resolves), Insights delivers the transition to any endpoint subscribed to that check code. Endpoints are declared under two keys by delivery format:

  • webhook: receives the full Alertmanager-compatible payload envelope.
  • alertmanager: receives a bare alert array compatible with the Alertmanager v2 POST /api/v2/alerts API.

Both endpoint types take the same per-endpoint fields:

FieldDefaultDescription
name(required)Human-readable name; must be unique across all endpoints
url(required)Destination URL; must be http or https
enabledtrueWhether the endpoint is active
auth-type(none)Authentication scheme: basic, bearer, or hmac
auth-user(empty)Username for basic auth
auth-token(empty)Password (basic), token (bearer), or secret (hmac, sent as X-Hub-Signature-256)
subscriptions(empty)Check-code patterns this endpoint receives (e.g. [server-*, stream-002])
ignore(empty)Check-code patterns dropped after a subscription match
systems(empty)Systems this endpoint delivers for; must be systems this node owns. Empty delivers for every system on the node

A pattern is an exact code (server-001), a prefix with a trailing wildcard (server-*), or * for every code. ignore is applied after subscriptions, so it carves exceptions out of a wildcard. A pattern that matches no check code fails startup; an uppercase, underscored pattern (SERVER_*) is reported with its current spelling.

Note systems is the inverse of subscriptions: an empty subscriptions list delivers nothing (subscribing to a check code is explicit), but an empty systems list delivers for every system the node owns (the sensible default on a node serving one or a few operator-named systems). On a node serving several systems, scope an endpoint to a subset by naming them.

notifications:
webhook:
- name: "PagerDuty Relay"
url: "https://example.com/webhook"
enabled: true
auth-type: "bearer"
auth-token: "…"
subscriptions: [server-*, stream-002]
ignore: [server-046]
alertmanager:
- name: "local-am"
url: "http://localhost:9093/api/v2/alerts"
subscriptions: [server-001]

Notifications are a YAML-only setting; there are no equivalent flags or environment variables. Delivery timing is fixed: a 10s request timeout and up to 3 attempts with exponential backoff, or a single attempt when the receiver answers with a 4xx other than 429. A delivery that still fails is retried for that endpoint on a backoff capped at once a minute until it succeeds. Every endpoint is validated at startup: a missing name or URL, a malformed or non-http(s) URL, a duplicate name, an unknown auth-type, a pattern matching no check code, or a systems entry naming a system this node does not own fails startup with a clear error rather than being silently dropped. Alert payload links use --web.external-url when set. The web UI's Notifications page shows the configured endpoints and their delivery logs and can send a synthetic test delivery, but endpoints themselves are managed only through the config file.