Observability for Supabase Applications: What Should You Actually Monitor?
The five signals worth watching in Supabase — CPU, connections, slow queries, error rate, response time — and when to add Grafana or Datadog.

Supabase observability means knowing what your app is doing before your users tell you. Supabase gives you a database, an API, login, file storage and background functions on day one — which is fast to build on, but means that when something slows down, you have six places to look and no obvious starting point. This guide covers the five signals worth watching, what each one actually costs you when it goes wrong, and how to set them up without buying a monitoring platform first.
Quick Answer
Watch five things: database CPU, database connections, slow queries, API error rate, and API response time. Supabase shows all five in the dashboard already, at no extra cost. Add an outside tool like Grafana or Datadog only when you need to keep logs longer than your plan allows, or you want to be paged at night.
What Observability Means
Observability is being able to answer "why is this slow or broken?" using information you're already collecting.
Three kinds of information do the work:
- Logs — a record of things that happened. One line per request, error or login.
- Metrics — numbers over time. How busy the database is. How many people are connected.
- Traces — one user's journey, followed across every service it touched.
Monitoring tells you something is wrong. Observability tells you what and where. You want both, and Supabase gives you most of it for free.
The Problem: The Thing That Breaks Isn't the Thing You Wrote
Most teams launch on Supabase with no monitoring at all. It works fine — until it doesn't, and the failure is rarely in the application code.
Four patterns we see over and over on client projects:
- The app slows down as it succeeds. A query that was instant at 40,000 rows crawls at 4 million. Nobody changed anything. The table just grew.
- The database runs out of connections. Modern hosting spins up new copies of your app under load, each opening its own connections, until the database refuses new ones and every request fails at once.
- A security rule quietly costs you speed. Supabase's row-level security decides who can see what. Written one way it runs once per request. Written another way it runs once per row, and a 12ms query becomes 900ms.
- The storage bill jumps. A public file bucket gets linked from elsewhere and you pay for the traffic.
None of these throw an error. The request succeeds — it's just slow, or expensive. And on the free plan, logs are kept for one day, so by the time a customer complains the evidence is already gone.
The business version: slow pages cost conversions, outages cost trust, and surprise usage bills cost margin. All three are cheaper to catch early than to explain later.
The Solution: Watch Each Layer, Not Just the App
When someone clicks a button in your app, the request passes through several Supabase services before it reaches your data. Each one keeps its own record.
A "slow app" can start at any of those steps. Watching only your own code tells you a request took 900ms. Watching each layer tells you which 900ms.

What You Should Actually Monitor
Five signals. Thresholds are starting points — adjust once you know your own normal.

| Signal | What it tells you | What happens if you ignore it | Watch for |
|---|---|---|---|
| Database CPU | How hard your database is working | Everything slows down, then times out | Above 80% for 5 minutes |
| Database connections | How close you are to the limit | Every request fails at once | Above 80% of the limit |
| Slow queries | Which requests cost the most time | Gradual, unexplained slowdown | Anything above 200ms |
| API error rate | How many requests are failing | Users hit errors before you know | Above 1% of requests |
| API response time | How slow it feels to a real user | Silent drop in conversions | Above 500ms |
If you only set up one of these, make it the database. In our experience most Supabase production issues come back to a query, a missing index, or connections — not the application code.
What You Can Safely Ignore
Rarely said out loud, and it matters more than the list above:
- Most of the metrics available to you. Supabase can expose around 200 database measurements. Putting them all on a dashboard creates noise, not insight.
- Traffic counts. More requests isn't a problem. Slower requests is.
- Detailed debug logs in production. They cost money at volume and bury the useful lines.
Alert fatigue kills monitoring faster than missing data does. Five alerts people act on beat fifty that everyone mutes.
Prerequisites
- A Supabase project — the free plan covers most of this
- Access to the Supabase dashboard
- Someone comfortable running a SQL query, for two of the steps below
Step-by-Step: Setting This Up
Step 1: Get Your Baseline
Open Dashboard → Reports. You'll see database CPU, memory and API request volume. Set the range to 7 days and take a screenshot.
That's your baseline. You can't say "CPU is high" until you know what normal looks like for your app. This single step is the highest-value thing in this guide and it takes five minutes.
Step 2: Run the Advisors
Open Dashboard → Advisors. Supabase scans your setup and reports two lists:
- Security — tables that are readable by anyone, and similar exposures
- Performance — missing indexes, unused indexes, and inefficient security rules
Fix the security list before anything else. A table without access rules is a data breach waiting for someone to find your project URL.
One performance fix pays for the visit. If your security rules call auth.uid() directly, wrapping it in brackets makes Postgres check it once instead of once per row:
-- Slow: checked once per row
create policy "users read own orders" on orders
for select using (auth.uid() = user_id);
-- Fast: checked once, then compared
create policy "users read own orders" on orders
for select using ((select auth.uid()) = user_id);On a table with 500,000 rows, that one change has taken queries from seconds to milliseconds. It's the cheapest performance win available on Supabase. See our Supabase authentication guide for Next.js for how these rules are structured in the first place.

Step 3: Find the Queries Costing You the Most
Open the SQL Editor and run this:
select
calls,
round(mean_exec_time::numeric, 2) as avg_ms,
round(total_exec_time::numeric, 2) as total_ms,
query
from pg_stat_statements
order by total_exec_time desc
limit 20;This ranks every query by the total time it has consumed since the database started.
The important part: sort by total time, not average time. A 2-second query that runs twice a day doesn't matter. A 40ms query running 200,000 times a day is your problem — and it never shows up on a "slowest queries" list. That distinction is what separates a useful hour of tuning from a wasted one.
Prefer clicking to typing? Dashboard → Query Performance shows the same information. Our PostgreSQL performance tuning guide covers what to do with the results.

Step 4: Learn to Search Your Logs
Open Dashboard → Logs → Logs Explorer. This is where you go after something breaks.

The one query worth saving — every failing request in the last window:
select
timestamp,
toInt32OrZero(log_attributes['response.status_code']) as status,
log_attributes['request.path'] as path
from logs
where source = 'edge_logs'
and toInt32OrZero(log_attributes['response.status_code']) >= 400
order by timestamp desc
limit 100;Two limits to plan around: results cap at 1,000 rows, and logs are kept for 1 day on Free, 7 on Pro, 28 on Team, 90 on Enterprise. The Logs Explorer is for investigating an incident this week, not reviewing last quarter.
Worth knowing: Supabase moved the Logs Explorer to a new query engine in June 2026. Older tutorials use a cross join unnest(metadata) pattern that no longer works. If a copied query returns an error, this is almost always why.
Step 5: Decide Where the Alerts Go
Supabase shows you problems. It won't wake you up for them. When that matters, Log Drains (Project Settings → Log Drains, available on Pro and above) forwards your logs to a tool that will — Datadog, Grafana, Sentry, S3 and several others are supported.
Start with a small alert list. Anything longer gets ignored:
| Alert | When | Action |
|---|---|---|
| Database CPU above 80% for 5 min | Sustained load | Wake someone |
| Connections above 80% of limit | About to fail | Wake someone |
| Disk above 85% | Database goes read-only when full | Wake someone |
| API errors above 1% | Users are hitting failures | Wake someone |
| Response time above 500ms for 10 min | Getting slow | Check in the morning |
Everything else belongs on a dashboard someone reviews weekly. If an alert fires and nobody changes anything, delete the alert.
One expensive mistake to avoid: never point a log drain at one of your own Supabase functions. Each forwarded log creates a new log, which gets forwarded, forever. You pay for every loop.
Common Problems
"My log queries return an error or nothing"
Two likely causes. Either you copied a pre-June-2026 query using the old cross join unnest(metadata) syntax, or you're searching outside your plan's retention window — a free-plan search for yesterday correctly returns nothing.
"Connections keep climbing until the app dies"
Your app is opening a new database connection per request instead of reusing one. Create the Supabase client once when your app starts, not inside each request handler, and connect through Supabase's connection pooler rather than directly to the database.
"The dashboard says the query is fast, but the app feels slow"
The database timing doesn't include network travel time, the security-rule check on the rows returned, or converting the result to JSON. Test as a real logged-in user rather than as an admin — the security-rule cost only appears when the rules actually apply.
"We got a surprise bill"
Usually file storage traffic or log volume, not the database. Check egress in the dashboard's usage view, make public buckets private where you can, and stop logging routine health checks.
Best Practices
- Baseline before you alert. Any threshold from a blog post — this one included — is a guess about your workload. Watch for a week first.
- Rank slow queries by total time, not average time. Total time is what actually saturates your database.
- Fix the Advisors security list before adding features. It's free, it takes minutes, and it's the highest-risk item on this page.
- Alert on what users feel; investigate with the rest. Page on errors and slowness. Keep CPU graphs for the diagnosis, not the alarm.
- Keep secret keys on the server. Supabase's secret key bypasses all your access rules. It must never reach a browser, a mobile app, or a public repository.
- Never log passwords, tokens or personal data. Logs get forwarded to other tools, and they're far harder to clean up afterwards.
- Review the dashboard weekly for 10 minutes. Most incidents are visible as a trend days before they become an outage.
Native Supabase Tools vs an External Platform
| Feature | Supabase built-in | External (Grafana, Datadog, Sentry) |
|---|---|---|
| Cost | Included | Per user, host or gigabyte |
| Setup | Minutes | Hours to days |
| Log retention | 1–90 days by plan | As long as you pay for |
| Wakes you at night | No | Yes |
| Custom dashboards | Fixed reports | Unlimited |
| Covers non-Supabase services | No | Yes |
When Is Built-In Enough?
Stay with Supabase's own tools when:
- Supabase is effectively your whole backend
- The team is small and nobody is formally on call
- A one-week window is enough to investigate incidents
- You're early and watching every cost
Bring in an external platform when:
- You have compliance rules about keeping logs
- You need someone paged at 3am
- Supabase is one service among several
- Downtime has a real, countable revenue cost
Start with the built-in tools and move when something specific blocks an investigation — not before. Building a monitoring stack for problems you don't have yet is a common way to lose a quarter. If you're also sorting out hosting and environments, our Next.js production deployment guide covers the adjacent decisions.
Frequently Asked Questions
Does Supabase have built-in monitoring?
Yes. Every project includes Reports for database and API metrics, a Logs Explorer for searching what happened, Security and Performance Advisors, and a Query Performance report. All are included at no extra cost.
How long does Supabase keep logs?
One day on Free, 7 days on Pro, 28 days on Team, and 90 days on Enterprise. To keep them longer, forward them elsewhere using Log Drains, available on Pro and above.
What should I monitor first in Supabase?
Database CPU and database connections. Most Supabase production incidents trace back to one of those two, and both are visible in the dashboard without any setup.
Can I connect Supabase to Grafana or Datadog?
Yes. Supabase exposes a metrics endpoint that standard monitoring tools can read, and Log Drains can forward logs to Datadog, Grafana, Sentry, S3 and others. Supabase publishes a ready-made Grafana dashboard on GitHub.
Do I need a paid monitoring tool?
Not at the start. The built-in tools cover most needs. Pay for an external platform when you need alerting that reaches a person, or log retention longer than your plan allows.
Why did my Logs Explorer query stop working?
Supabase changed the Logs Explorer query engine in June 2026. Queries written before that using cross join unnest(metadata) no longer run. Use the bracket syntax shown in step 4 instead.
Conclusion
Most Supabase problems come from the database, not the code — a slow query, a missing index, or connections running out. You don't need a monitoring platform to catch any of them. Reports gives you a baseline, Advisors finds the security and performance issues, Query Performance shows what's costing you time, and the Logs Explorer tells you what happened. That's an hour of setup, once. Add an external tool the day you need someone woken up at 3am, or the day a one-week log window stops being enough to answer the question.
Building on Supabase? We design and ship production Supabase applications — database and security design, web and mobile front ends, and the monitoring that keeps them supportable once real users arrive. Talk to our team or read more about our backend development services.
Sources
- Supabase Logging documentation
- Supabase Metrics API
- Supabase Log Drains
- PostgreSQL: pg_stat_statements
- supabase/supabase-grafana

Aarav Sharma
Lead Software Engineer
Aarav leads product engineering at Matlab Infotech, where he has shipped mobile and web platforms across healthcare, fintech, and SaaS. He writes about pragmatic engineering and shipping fast without cutting corners.


