Demo, all content is generated
Question

Supabase keeps emailing that I'm depleting my Disk IO budget, app has 40 users

Open · 541 views · asked by frankie_r · edited

I get "Your project is depleting its Disk IO Budget" emails every few days. The app is a small habit tracker. The dashboard sometimes feels slow in the afternoon. Is the fix to buy a bigger compute? That's +$50 or so, which is more than I make from it.

What I’ve tried

Restarted the project. Looked at the Disk IO graph, it spikes to 100% for like an hour every day.

Comment
Does anything run every day at that hour? Cron job, edge function, some sync? postgres_pete · edited

3 answers

postgres_pete · edited

Don't buy compute before looking. On Micro/Small the IO budget is small, and one bad query pattern can burn it with 40 users.

  1. Dashboard > Database > Query Performance: sort by total time. The top 3 are usually the whole story.
  2. Look for sequential scans on growing tables, e.g. select * from checkins where user_id = ... without an index on user_id:
    create index on checkins (user_id, created_at desc);
  3. Look for polling. Lovable-generated dashboards sometimes refetch every second, or subscribe to realtime on a whole table.

A daily 1-hour spike smells like a scheduled job doing a full table pass.

Comment
That'll be it. Make it incremental: only recompute users with new checkins since the last run. postgres_pete · edited
There's a pg_cron job that recalculates streaks for everyone at 14:00. that's the hour. looking at it frankie_r · edited
Did that, the spike is gone. Graph is flat now. frankie_r · edited
jb_supa · edited

Also check that RLS policies call auth.uid() wrapped as (select auth.uid()). Unwrapped it's evaluated per row, which makes every query scan a lot more than needed.

Comment
Yes, literally. Postgres then evaluates it once per query instead of per row. jb_supa · edited
what does wrapped mean here? like literally (select auth.uid())? frankie_r · edited
mariam_k · edited

I had this and it was the realtime thing, turned off realtime on tables that didn't need it and the emails stopped.

Comment