Fixed costs (Supabase, Vercel, Resend) you can just divide, they barely move per user. The variable part is AI, so log it per call.
Every API response includes token usage. Store it:
create table ai_usage (
id bigint generated always as identity primary key,
user_id uuid not null references auth.users,
model text not null,
input_tokens int not null,
output_tokens int not null,
cost_usd numeric(10,6) not null,
created_at timestamptz default now()
);In your server wrapper, after each call: compute cost from usage.prompt_tokens / usage.completion_tokens (or input_tokens/output_tokens depending on SDK) times the model price, insert a row.
Then:
select user_id, sum(cost_usd) as cost_30d
from ai_usage where created_at > now() - interval '30 days'
group by user_id order by cost_30d desc limit 20;That top-20 list will tell you what your plan limits should be. RLS on, no client access.