Configuration

All configuration is supplied through environment variables prefixed with QUERYINSIGHTS_. Only one is strictly required; everything else has a sensible default or unlocks an optional capability.

Never hard-code secrets. Provide API keys and database passwords through a secret manager or your platform's environment configuration — not in source control or shell history.

Core

VariableRequiredDefaultDescription
QUERYINSIGHTS_DB_URLYes—Connection string for the QueryInsights metastore (PostgreSQL).
QUERYINSIGHTS_LISTEN_ADDRESSNo0.0.0.0:2427Address the webhook service listens on.
QUERYINSIGHTS_ENGINE_ADDRESSNolocalhost:50051Engine gRPC address used by the poller, webhook, and dashboard.
QUERYINSIGHTS_DASHBOARD_ADDRESSNo:3001Address the dashboard API listens on.

LLM

VariableRequiredDefaultDescription
QUERYINSIGHTS_OPENAI_API_KEYNo—Enables OpenAI recommendations.
QUERYINSIGHTS_ANTHROPIC_API_KEYNo—Enables Anthropic (Claude) recommendations.
QUERYINSIGHTS_LLM_MODELNogpt-4o-miniChat model for recommendations. Also selects the provider (see below).
QUERYINSIGHTS_LLM_BASE_URLNo—Custom base URL for the LLM client — point it at a gateway such as LiteLLM or Portkey.

How the provider is chosen

The engine picks a backend from the model name:

  • Model name contains claude and QUERYINSIGHTS_ANTHROPIC_API_KEY is set → Anthropic.
  • Model name contains claude but only QUERYINSIGHTS_OPENAI_API_KEY is set → OpenAI-compatible client (use this when a gateway fronts Claude behind an OpenAI-compatible API, e.g. a model name like vertex/claude-opus-4).
  • Otherwise → OpenAI.

If no matching API key is configured, the engine starts without recommendation features; ingestion and the dashboard still work.

Metadata sources

VariableRequiredDefaultDescription
QUERYINSIGHTS_TRINO_URLNo—Trino coordinator URL, used to fetch table DDL for Trino recommendations.
QUERYINSIGHTS_COCKROACH_INSTANCESNo—JSON array of CockroachDB instances to poll and read schema from.
QUERYINSIGHTS_POSTGRES_INSTANCESNo—JSON array of PostgreSQL instances to poll and read schema from.

Recommendation tuning

VariableRequiredDefaultDescription
QUERYINSIGHTS_REC_MAX_ATTEMPTSNo3Failed per-query recommendation attempts before a pattern is permanently skipped.
QUERYINSIGHTS_DDL_MAX_FAILURESNo3Consecutive SHOW CREATE TABLE failures for a table before schema fetching is abandoned.
QUERYINSIGHTS_STATS_CACHE_TTL_SECSNo1800How long rendered table-statistics blocks are cached before re-fetching.
QUERYINSIGHTS_WORKLOAD_INTERVAL_MINNo10080Minutes between periodic workload-insight runs. Set to 0 to disable the ticker.
QUERYINSIGHTS_WORKLOAD_TOP_TABLESNo10Number of hottest tables included in each workload profile.
QUERYINSIGHTS_WORKLOAD_TOP_QUERIES_PER_TABLENo5Top normalized patterns per table included in the workload prompt.

Describing database instances

Webhook (Trino)

VariableDefaultDescription
QUERYINSIGHTS_WEBHOOK_INSTANCEtrinoSource-instance name recorded for Trino events.
QUERYINSIGHTS_WEBHOOK_SAMPLING_RATE1.0Fraction of completed-query events to keep, in (0, 1]. Kept events are weighted by 1/rate.
QUERYINSIGHTS_WEBHOOK_TOKEN(none)When set, requests must send Authorization: Bearer <token>. Configure it in Trino with http-event-listener.connect-http-headers.

Configure Trino's HTTP event listener with http-event-listener.log-completed=true and http-event-listener.log-created=false.

Poller instances

Both QUERYINSIGHTS_COCKROACH_INSTANCES and QUERYINSIGHTS_POSTGRES_INSTANCES take a JSON array of objects with the same shape:

[
  {
    "name": "production",
    "dsn": "postgres://queryinsights:REPLACE_WITH_PASSWORD@db.internal:5432/appdb?sslmode=require",
    "poll_interval_seconds": 60
  }
]
FieldTypeDescription
namestringA label for the instance; shown in the dashboard and stored with every captured query.
dsnstringConnection string. The user in this DSN needs both statement-stats access and schema-read access.
twin_dsnstringPostgreSQL only, optional. Superuser connection to a QueryInsights-managed twin server (same major version). Enables proven workload insights. See Workload Twin.
poll_interval_secondsnumberHow often to read the statistics view. Defaults to 60. Counters are cumulative, so a longer interval loses nothing; it only coarsens timing.
sampling_ratenumberIgnored (accepted for backward compatibility). Statistics views are already aggregated per statement, so there is nothing to sample. See Concepts.

You can configure multiple instances, and both engines at once — the poller starts one goroutine per instance.

The same DSN user is used by the poller (to read statistics) and by the engine (to read table DDL). Follow the least-privilege setup in Onboarding PostgreSQL and Onboarding CockroachDB to create that user safely.

Example

export QUERYINSIGHTS_DB_URL="postgres://queryinsights:REPLACE_WITH_PASSWORD@localhost:5432/metastore?sslmode=disable"
export QUERYINSIGHTS_LLM_MODEL="gpt-4o-mini"
export QUERYINSIGHTS_OPENAI_API_KEY="REPLACE_WITH_OPENAI_API_KEY"

export QUERYINSIGHTS_POSTGRES_INSTANCES='[
  {"name":"prod","dsn":"postgres://queryinsights:REPLACE_WITH_PASSWORD@db.internal:5432/appdb?sslmode=require","poll_interval_seconds":60}
]'

Keep the real values in a secret store and inject them at runtime.