Alerts
Usage threshold alerts on storage and connections - warning at 80%, critical at 95%, delivered to the dashboard, your webhooks, and the org billing email.
What gets alerted
CapyDB continuously evaluates two gauges per project against the plan's limits:
| Kind | Observed | Limit |
|---|---|---|
storage | Database size in bytes | Plan storage limit |
connections | Current connections to the database | Plan connection budget |
There is at most one open alert per project and kind. Severity moves in place on the open alert; a resolved alert closes and a future breach opens a new one.
Performance advisories
Alongside the gauges above, CapyDB derives warning-severity advisories from the metrics it
samples for every project. They surface in the dashboard, the API and capydb alerts list only - they
never send email or fire a webhook, because each one is a hint to act on when you are already
looking, not an incident.
| Kind | Opens when | Where to start |
|---|---|---|
cache_hit | The buffer cache hit ratio stays below 90% | Working set outgrowing memory - see Observability |
blocked_queries | Queries sit blocked on locks across the window | Find the blocking transaction and close it |
deadlocks | Deadlocks were detected in the interval | Two transactions taking the same locks in different orders |
vacuum | Dead tuples accumulate faster than autovacuum reclaims them | Often caused by long_transaction below |
long_transaction | A transaction has been open for over 15 minutes | Close it; while it is open, nothing it might still see can be reclaimed |
subtransactions | Backends have overflowed the 64-entry savepoint cache | Reduce nested transactions or EXCEPTION blocks on hot paths |
oom_kill | The database was stopped for exceeding its memory limit | Explains an outage unreachable already reported |
temp_spill | The database sustains writing temporary files | A sort or hash does not fit in work_mem - raise it per statement, not globally |
Advisories are workload-scoped: they close on their own when the condition clears, and when a database scales to zero (its load no longer exists).
Thresholds and hysteresis
| Transition | Threshold |
|---|---|
Opens at warning | usage ≥ 80% |
Opens at / escalates to critical | usage ≥ 95% |
critical downgrades to warning | usage drops below 90% |
| Alert resolves | usage drops below 75% |
The trigger and resolve thresholds are deliberately apart (hysteresis), so usage hovering at exactly 80% cannot flap an alert open and closed on every evaluation sweep.
Notification rules
- A new alert notifies immediately.
- An escalation (
warning→critical) notifies immediately. - An alert that simply stays open re-notifies at most once every 24 hours.
- Resolution sends one
alert.resolvednotification.
Delivery channels
-
Dashboard - open alerts surface on the project, alongside the Observability gauges that triggered them.
-
Webhooks - your org's webhook endpoints receive
alert.triggeredandalert.resolvedevents (standard signed envelope):{ "id": "evt_...", "type": "alert.triggered", "created_at": "2026-06-10T08:00:00.000Z", "data": { "alert_id": "alr_...", "kind": "storage", "severity": "critical", "observed_value": 4928307200, "limit_value": 5368709120, "project_id": "prj_...", "triggered_at": "2026-06-10T08:00:00.000Z" } }alert.resolvedcarries the samedataplusresolved_at. Values are bytes forstorageand a connection count forconnections. -
Email - when your organization has a billing email configured, alert notifications also go there as plain text. No billing email, no email; webhooks and the dashboard still work.
Acknowledging
Acknowledging records that a human has seen the alert - acknowledged_at is set once (first acknowledgement wins) and the dashboard renders it as seen. It is visual only: an acknowledged alert keeps re-notifying on the 24-hour cadence until usage actually drops and it resolves. The way to silence an alert is to fix the usage or raise the limit.
API
# Open alerts plus alerts resolved in the last 30 days
GET /v1/projects/{projectID}/alerts
# Mark one as seen (idempotent)
POST /v1/projects/{projectID}/alerts/{alertID}/acknowledgeBoth are available to any org member. See the Observability API reference for the full ProjectAlert shape.
CLI
capydb alerts list # uses the linked project; --project to target another
capydb alerts ack alr_123abc # acknowledge by id
capydb alerts list --output json # machine-readable, lists always [] not nullWhen an alert fires
- Storage: delete unused data,
VACUUM, or move up a plan. Remember that imports are blocked when the source exceeds the plan limit anyway - the alert is your early warning before that wall. - Connections: app traffic belongs on the pooled URL; hunt for oversized client-side pools and long-idle direct sessions. See Connection pooling.