Appearance
supabase
Coming soon
This plugin is not released yet. The agent side lives on the unmerged supabase-plugin branch of the plugins package. The server rules and the dashboard card are on the matching frontend branch.
The supabase plugin watches Supabase Cloud projects. Per project it reports whether the project is paused, the health of each Supabase service, and disk, memory, connections and database size. It runs on any agent, because it only makes HTTPS calls.
Set it up
Each project can use one or both of two sources. Each source has its own credential.
| Source | Credential | Gives |
|---|---|---|
Management API, api.supabase.com/v1 | A personal access token. It covers every project in the account that made it. | Project status, the only place "paused" shows up. Region and Postgres version. Health for each service. |
The project's metrics endpoint, https://<PROJECT_REF>.supabase.co/customer/v1/privileged/metrics | The project's secret API key, sent as basic auth with user service_role. | Disk, memory, connections and database size. |
Either one alone works. A project with neither reports an error.
- Find each project's ref. It is the subdomain in
https://<PROJECT_REF>.supabase.co. - Create a personal access token in each Supabase account that owns a project, and copy each project's secret key if you want the figures.
- Add a
supabaseblock to the agent config and addsupabaseto thepluginsarray.
json
{
"plugins": ["supabase"],
"supabase": {
"refreshInterval": 60000,
"accessToken": "sbp_<DEFAULT_ACCOUNT_TOKEN>",
"diskWarnPct": 80,
"diskCritPct": 90,
"connWarnPct": 85,
"projects": [
{ "ref": "<PROJECT_REF>", "name": "portal" },
{
"ref": "<OTHER_PROJECT_REF>",
"name": "calendar",
"accessToken": "sbp_<OTHER_ACCOUNT_TOKEN>",
"serviceKey": "sb_secret_<SECRET_KEY>"
}
]
}
}The top-level accessToken is the default. A project in a different Supabase account needs its own accessToken, since one token only covers its own account.
| Option | Default | What it does |
|---|---|---|
projects | required | List of projects. Each has ref, and optionally name, accessToken and serviceKey. Entries without ref are skipped. |
projects[].name | project name from the API, else ref | Card title. |
accessToken | none | Default personal access token. |
services | auth, db, pooler, realtime, rest, storage | Services asked of the health endpoint. Drop one a project does not use. |
diskWarnPct | 80 | Disk use, in percent, that warns. |
diskCritPct | 90 | Disk use, in percent, that is an error. |
connWarnPct | 85 | Connections in use, as a percent of max_connections, that warns. |
requestTimeout | 10000 | Milliseconds per HTTP request. |
refreshInterval | 60000 | Milliseconds between polls. |
What it reports
One report per project per interval, keyed supabase-<ref>. Projects are polled one after another, and the first poll runs on start.
ref,nameandreachable.projectStatus, such asACTIVE_HEALTHYorINACTIVE, plusregionandpgVersion.services[], each withname,healthy,statusanderror.metrics, from the Prometheus endpoint.diskPct,diskUsedBytesanddiskTotalBytesread the/datavolume, or/when there is no/data. AlsomemPct,load1,connections,maxConnectionsanddbSizeBytes. A series that is missing reports null, not 0.errors[], one entry per configured source that failed while another answered.diskWarnPct,diskCritPctandconnWarnPct, the thresholds from the agent config. The server judges with these.
If every source fails, the report is { reachable: false, error }.
When it alerts
The server checks these in order and stops at the first match.
| Condition | Severity | Reason text |
|---|---|---|
error set, or reachable is false | error | <name>: <error> |
projectStatus is INACTIVE | error | <name>: project is paused |
projectStatus is a transient state | warning | <name>: project <status> |
projectStatus is any other value besides ACTIVE_HEALTHY | error | <name>: project <status> |
The db service is unhealthy and not COMING_UP | error | <name>: database unhealthy, <error> |
diskPct at or above diskCritPct | error | <name>: disk <n>% full |
| Any service unhealthy | warning | <name>: <services> unhealthy |
diskPct at or above diskWarnPct | warning | <name>: disk <n>% full |
Connections at or above connWarnPct of the maximum | warning | <name>: <n> of <max> connections in use |
errors[] is not empty | warning | <name>: <first error> |
The transient states are COMING_UP, RESTORING, UPGRADING, RESTARTING, RESIZING, PAUSING, GOING_DOWN and UNKNOWN.
A new problem does not notify on the first bad report. The server waits for a second consecutive bad report. A report that comes back online resolves the alert.
On the dashboard
One card per project, titled with the project name and labelled Supabase · <region>. Each reading shows only when it was measured.
| Reading | Source | Warn | Crit |
|---|---|---|---|
| PROJECT | projectStatus. ACTIVE_HEALTHY reads ACTIVE, INACTIVE reads PAUSED | any other state | PAUSED |
| DISK | metrics.diskPct | diskWarnPct | diskCritPct |
| CONNS | connections / maxConnections | connWarnPct | none |
| DB SIZE | metrics.dbSizeBytes | none | none |
| MEM | metrics.memPct | none | none |
| POSTGRES | pgVersion, major and minor | none | none |
Below that, one row per service. Healthy is green, COMING_UP is amber, anything else is red. When the report is unreachable, the card shows only API UNREACHABLE. The card links to the project in the Supabase dashboard.
Gotchas
- The branch's commit message says the health and project response fields, and the metric series names, were written from memory. They have not been run against a live project.
- The dashboard and the server do not color everything the same way. An unhealthy service other than
dbis red on the card but only a warning on the server. A project state outside the transient list is amber on the card but an error on the server. load1,diskUsedBytesanddiskTotalBytesare reported but not shown.memPctis shown but never judged.- A partial report, where one source failed, does not show which source failed on the card. The reason text carries the first error.