Skip to content

Alerts

Alerts notify you in Slack or your own webhook when Query Doctor sees a new query, a new index recommendation, or a cost regression in one of your CI runs. You choose which types fire once per project, then add the destinations that receive them.

Alerts fire as each CI run is ingested, so they depend on CI integration. If no CI runs reach the project, no alerts are sent.

Open your project and go to Settings → Alerts. The page has two parts:

  1. Notify me about — a project-wide selection of which alert types fire.
  2. Integrations — the destinations that receive them.

Every integration receives every selected alert type. The selection is project-wide, not per-integration.

Under Notify me about, toggle the alert types you care about. Toggling saves immediately.

Alert typeFires when
new_queryA query Query Doctor hasn’t analysed before for this project shows up in CI.
index_recommendationAn analysed query gains a new index suggestion. Only fires when the suggestion is newly discovered, not on every run that repeats it.
threshold_breachA query’s cost regresses past your CI threshold versus the comparison branch.
schema_driftComing soon. Subscribe now and delivery starts the moment it ships.

If you select nothing, the page shows an “Everything is muted” warning: integrations stay configured but nothing is sent until you select at least one type.

threshold_breach honours the per-repo Minimum query cost and Regression threshold from your CI settings — see CI Integration → Per-repo configuration. Queries cheaper than the minimum, or increases under the threshold, never fire.

Under Integrations, choose Add an integration, pick a destination, and fill in:

  • Name — a display label (e.g. #db-alerts). It only labels the row; it does not route anything.
  • URL — where the alert is delivered.
DestinationURLNotes
Slackhttps://hooks.slack.com/services/…An incoming webhook. See “Slack setup” below.
Webhookany https:// (or http://) URLWe POST a JSON payload for every selected alert.

Discord, Email, and PagerDuty are listed as coming soon.

New integrations are enabled on creation. Each row gives you:

  • Enabled toggle — when off, the destination receives nothing, even for selected alert types.
  • Send test — delivers a sample alert so you can confirm the destination works.
  • Reveal / copy — the URL is masked by default; reveal or copy it.
  • Remove — deletes the integration. There is no in-place URL edit; to change a URL, remove the integration and add a new one.
  1. Go to api.slack.com/apps → your app (or create one) → Incoming WebhooksAdd New Webhook to Workspace.
  2. Pick the channel the alerts should post to, then Allow.
  3. Copy the https://hooks.slack.com/services/… URL and paste it into the integration’s URL field.

A few Slack behaviours to know:

  • The channel is permanently bound to the webhook URL. Modern Slack apps ignore a channel field in the payload, so there is no way to re-route an existing webhook. To move alerts to a different channel, create a new webhook for that channel and replace the integration (remove the old one, add a new one).
  • The avatar and name come from the Slack app, not Query Doctor. Change them in api.slack.com → your app → Basic Information → Display Information (App icon, name, accent color). They apply to every message the app posts; per-message overrides are ignored.

Delivery URLs are validated to prevent server-side request forgery:

  • Only http/https schemes are allowed.
  • Slack integrations are pinned to hooks.slack.com over HTTPS.
  • Private and internal addresses are blocked — loopback, RFC1918, link-local (including the cloud metadata endpoint), CGNAT, and IPv6 equivalents — both as literal URLs and after DNS resolution.

If you add a webhook pointing at an internal address, the integration is rejected and no alert is delivered to it.

  • “Everything is muted” — no alert type is selected. Select at least one under “Notify me about”.
  • Test works but no real alerts arrive — confirm CI runs are reaching the project (CI Integration); alerts only fire on ingested runs. Also check the integration’s Enabled toggle.
  • Slack test rejected — the webhook may have been revoked or the channel archived. Create a fresh webhook and replace the integration.
  • Webhook rejected on save — the URL resolves to a private/internal address (see “Delivery security”).