Files
thoughts/infrastructure/DB_PERFORMANCE_NOTES.md
T
denshooter 0d4b69713d Fix Supabase linter performance findings
- add covering indexes for flagged foreign keys
- optimize RLS policies to use select auth.uid()
- consolidate posts update policies into one permissive rule
- document linter findings and decisions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-24 12:00:43 +00:00

1.8 KiB

Database performance notes (Supabase linter)

This project had two performance-related linter groups:

  1. RLS auth function evaluation
  2. Unindexed foreign keys

What was changed

  1. Added migration infrastructure/migrations/002_perf_linter_fixes.sql.
  2. Updated infrastructure/migrations/001_schema.sql to keep fresh setups aligned with the same fixes.

RLS changes

The affected policies now use:

  • (select auth.uid()) instead of auth.uid()

This avoids repeated per-row evaluation in RLS plans for these policies:

  • profiles_update
  • posts_select
  • posts_insert
  • posts_update_own
  • resonances_insert
  • resonances_delete
  • whispers_select
  • whispers_insert
  • follows_insert
  • follows_delete
  • reports_insert
  • reports_select_own

Also, duplicate permissive update policies on public.posts were consolidated by removing posts_softdelete and keeping a single posts_update_own.

FK index changes

Added covering indexes:

  • idx_follows_following_id on public.follows(following_id)
  • idx_reports_reporter_id on public.reports(reporter_id)
  • idx_resonances_user_id on public.resonances(user_id)
  • idx_whispers_from_user_id on public.whispers(from_user_id)
  • idx_whispers_post_id on public.whispers(post_id)

About "unused index" findings

unused_index is based on pg_stat_user_indexes.idx_scan, which can read as zero after restarts or during low traffic.
In this environment, PostgreSQL was recently restarted, so these were not dropped automatically.

Suggested review query:

select
  schemaname,
  relname as table_name,
  indexrelname as index_name,
  idx_scan
from pg_stat_user_indexes
where schemaname = 'public'
order by idx_scan asc, indexrelname;

Drop an index only after observing sustained zero usage over representative production traffic.