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:
- Notify me about — a project-wide selection of which alert types fire.
- Integrations — the destinations that receive them.
Every integration receives every selected alert type. The selection is project-wide, not per-integration.
1. Pick what to be notified about
Section titled “1. Pick what to be notified about”Under Notify me about, toggle the alert types you care about. Toggling saves immediately.
| Alert type | Fires when |
|---|---|
new_query | A query Query Doctor hasn’t analysed before for this project shows up in CI. |
index_recommendation | An analysed query gains a new index suggestion. Only fires when the suggestion is newly discovered, not on every run that repeats it. |
threshold_breach | A query’s cost regresses past your CI threshold versus the comparison branch. |
schema_drift | Coming 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.
2. Add an integration
Section titled “2. Add an integration”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.
| Destination | URL | Notes |
|---|---|---|
| Slack | https://hooks.slack.com/services/… | An incoming webhook. See “Slack setup” below. |
| Webhook | any https:// (or http://) URL | We 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.
Slack setup
Section titled “Slack setup”- Go to api.slack.com/apps → your app (or create one) → Incoming Webhooks → Add New Webhook to Workspace.
- Pick the channel the alerts should post to, then Allow.
- 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
channelfield 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 security
Section titled “Delivery security”Delivery URLs are validated to prevent server-side request forgery:
- Only
http/httpsschemes are allowed. - Slack integrations are pinned to
hooks.slack.comover 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.
Troubleshooting
Section titled “Troubleshooting”- “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”).