Partly fixable yourself. An index is one line, finding the right one needs care
What you see. Pages that opened instantly with test data now take seconds, and Supabase shows slow queries or CPU warnings.
Why it happens
AI-built apps are tested on 50 rows and launched on 50,000. Without an index, Postgres scans every row in a table to find a match, so a lookup that was instant grows with your data. Supabase describes an index as a lookup list that finds rows without scanning the whole table.
Row Level Security makes this worse. Every policy runs on every row a query touches, and Supabase notes that an unindexed filter column turns a read into a sequential scan. Policies that call auth.uid() directly, instead of (select auth.uid()), run that function once per row. Add the usual builder habits, such as loading every row instead of a page, fetching related records one by one, and full-size images, and the app feels broken under modest traffic. The good news is that the Supabase Performance Advisor and Index Advisor point at most of this automatically.
Fix it yourself
- In the Supabase dashboard open the Performance Advisor. Look for
unindexed_foreign_keysandauth_rls_initplanfindings. - Open Query Performance, click the slowest query, choose the Indexes tab and enable the Index Advisor. It proposes indexes for that query.
- Create the index in the SQL editor, for example
create index concurrently idx_orders_user_id on orders (user_id). Index columns you filter, join or sort on, and columns your policies use. - Ask your builder to rewrite policies as
(select auth.uid()) = user_idso the user lookup runs once per query, not once per row. - Load 20 to 50 rows per page instead of everything, and resize images before upload. See the checklist items COST-03 and COST-04.
- Re-check the query plan. Supabase advises removing an index that did not reduce the query's cost, because every index slows writes.
When to get an engineer
Hire an engineer when the advisor lists dozens of findings, when the slow part is a server function or an AI call rather than the database, or when adding indexes did not help. Share the Query Performance report, the slow pages, and your user count. A one-off check costs $49–$800 and usually lands the top five fixes. A single fix, such as indexing and rewriting policies for one feature, runs €99–$990 over about two days.
Top-rated companies for Supabase apps
Ranked by our score: published prices, scope of work, AI tools named, timing and a low-risk first step. How we score.
- 1Redlab10.0/10Best for: A full rescue by one team that keeps buildingFree first step · from $490
- 2Vibe Code Rescue (Lev Arakelyan)9.0/10Best for: A one-off check and a cleanupFrom $299
- 3LazyCodeLab9.0/10Best for: A one-off check and a cleanupFrom $399
Check these
Database columns you filter on are indexed
Queries that scan whole tables are fast at 100 rows and slow at 100,000.
Key pages load fast on a phone
Run PageSpeed Insights on the home page and the main app screen, on mobile.
Images are resized and compressed
Uploaded photos served at full size are a common cause of slow pages.
Access rules are on for every table
In Supabase, open Table Editor: every table should show RLS enabled, with at least one policy. In Firebase, your rules should never say allow read, write: if true.
Questions
Should I just pay for bigger Supabase compute?
Try indexes and policy fixes first. They are one-line changes and remove the scans that waste the compute you already have.
Can too many indexes hurt?
Yes. Supabase notes that indexes add write overhead and storage, so index the columns you filter and join on, not every column.
Sources: Supabase docs: Managing Indexes in Postgres; Supabase docs: Query Optimization; Supabase docs: Row Level Security; Supabase docs: Performance and Security Advisors.
