Demo, all content is generated
Question

How do I know what each user actually costs me? (OpenAI + Supabase + Vercel + Resend)

Solved · 343 views · asked by fin_ops · edited

Launching paid plans next month. I want to know if a heavy user costs me more than they pay. Monthly bills: OpenAI ~$60, Supabase $25, Vercel $20, Resend $20. 400 users.

Averaging is easy but useless, the AI part is probably 90% from 10% of users. How do people track this per user?

What I’ve tried

Looked at OpenAI usage dashboard, it shows totals per day/model but not per my users.

Comment
Is every AI call going through your own server? If yes this is easy. grace_mw · edited
yes, all through a Next.js route fin_ops · edited

2 answers

Marked as helpful by the asker
grace_mw · edited

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.

Comment
Did it. Top user is $4.10/month, median is $0.06. Much less scary than I thought. fin_ops · edited
Also pass a user identifier on OpenAI requests, helps with abuse monitoring on their side. nomvula_b · edited
clara_w · edited

If you don't want to build the table: an LLM observability tool (Langfuse, Helicone) can tag calls by user id and show cost per user. But the table above is 30 minutes and you own the data.

Comment
prefer my own table for now, but will keep in mind fin_ops · edited