https://preview.redd.it/c3hc7t45yf6h1.jpeg?width=3960&format=pjpg&auto=webp&s=696fd9522d064002cb92bb4e6582aeb67d3581ba Took this comment to heart — it's built now, and your framing basically became the spec. The tenant page is split into exactly the two views you described: Billing view — stable 30-day numbers you can explain to a customer. Requests + rows are what actually go to Stripe; egress deliberately stays out of the invoice, because a client-side SDK can't see all egress (storage CDN, realtime) and billing a number you can't fully measure would be dishonest. Debug view — the messy detail: every table / RPC / storage bucket the tenant hit, with error counts and rates (failing retry loops light up red), a 24h hourly window for "what happened at 2pm", and clicking a row filters the chart to just that operation. The whole state lives in the URL, so you can send a teammate a link to the exact spike. Storage buckets turned out to be the one real data gap — the SDK was throwing the bucket name away, so all storage collapsed into one row per HTTP verb. Fixed (bucket name only, never object paths). And your "quietly becomes the cost center" line became its own feature: an hourly job compares each tenant's trailing 24h against its 7-day baseline and emails you when one jumps ≥3× (with absolute floors so tiny tenants don't spam you — max one mail per tenant per day). The email deep-links straight into that tenant's 24h debug view. The screenshot is the real thing: that alert fired off \~360 MB of egress from a tenant that had been quiet for a week. Curious what you'd still want on the debug side — error-rate alerts are next on my list.
This is exactly the split I'm building around, so it's reassuring to hear it framed that way independently. The way I'm structuring it: a billing view — stable, idempotent per-tenant numbers (requests, rows) you'd actually defend on an invoice — and a separate debug/attribution view with the messy detail (which table, endpoint, resource, egress) for "who quietly became the cost center this week." Keeping them apart matters because egress in particular is gold for debugging but too estimate-y to bill on directly. Since you've clearly hit this, three things I'd genuinely like to learn from you: 1. When a tenant does quietly become the cost center today — how do you find out, and how do you dig in right now? Querying logs by hand, guessing, waiting for the Supabase bill? 2. For the debug view: how deep does "messy detail" need to go to actually be useful — table + endpoint is enough, or do you also need it down to the storage bucket / a specific background job? 3. On billing: are you charging customers on usage today, or is this still internal cost attribution? If you bill, what dimension goes on the invoice? Trying to build the two views people would actually open — not just another dashboard.
You hit on a massive pain point for agency owners and devs running multiple smaller projects. The $25 minimum 'base tax' per Supabase project makes it prohibitively expensive to spin up isolated databases for multiple clients, even if their workloads are tiny. The logical workaround would be to consolidate multiple clients into a **single** Supabase project (using separate Postgres schemas or RLS). This would cost only one $25 Pro fee. But developers rarely do this because of a **complete lack of cost attribution**: if you put 10 clients on one database, you have no idea who is causing the egress spikes or database load, making it impossible to bill them fairly or protect your margins. We are actually building usagebill (usagebill.io) to solve this exact dilemma. It's a lightweight wrapper around the Supabase client that tracks requests, egress, and query latency per client/tenant. It allows agencies to safely host multiple clients on a single Supabase instance and automatically generates a clean, line-by-line usage breakdown for each client (and syncs it to Stripe). It saves you from paying the $25 project tax over and over again, without having to rewrite your entire codebase to raw pg queries. Railway is great for hosting containers, but for managed Postgres with Auth/Storage, consolidating and metering is the real hack.
We are doing this for a shared multi-app database. Regarding migrations: we found that having a single, central repo responsible for the database schema (using standard Supabase migrations) is the safest route to avoid migration conflicts and 'schema drift' between apps. Using isolated Drizzle/Prisma schemas for individual app-specific schemas works too, but you need strict CI/CD gates to make sure they don't block each other. However, there is a **hidden operations trap** you should prepare for: **Egress and resource attribution.** When App A, App B, and your background workers all hit the same Supabase database, Supabase will only bill you for the aggregate organization egress. If your database CPU spikes or you get a surprise $300 egress bill, the Supabase dashboard won't tell you *which* app caused it. You are essentially blind. We are launching usagebill (usagebill.io) to solve this. It's a lightweight wrapper around the Supabase client. You can tag the client in each Vercel app (e.g. projectId: 'marketing-site' or projectId: 'admin-dashboard'), and it aggregates requests, egress, and query latency per app. Definitely coordinate your migrations centrally, but make sure you also set up a way to track which app is driving your DB costs!
You hit the nail on the head with **'better observability + analytics'**. The biggest pain point with expensive storage egress isn't just the raw price per GB—it's the **complete lack of cost attribution**. When a SaaS builder gets a surprise $500 egress bill, they are currently blind. They have no way of knowing which specific tenant, user, or bot downloaded the assets. If developers had real-time, per-tenant egress analytics, they could: Attribute the costs directly to the customers who caused them. Implement usage-based billing to pass those egress costs on. Set soft/hard limits per tenant to prevent a single bot-scrape from locking their entire database or bankrupting them. We are actually building usagebill (usagebill.io) to solve this exact gap. It's a lightweight wrapper around the Supabase client that monitors egress bytes and requests per tenant at the SDK layer. If Supabase natively offered per-tenant/per-user egress billing metrics in the dashboard, it would be a game-changer. Until then, developers have to custom-build this telemetry themselves to protect their SaaS margins.
First things first: Yes, definitely contact Supabase support immediately. They are usually very understanding and helpful with test projects. In most cases, they will temporarily lift the restriction or assist you in retrieving a backup of your data so you aren't locked out forever. Getting locked out of your database during development because of an unmonitored egress spike is a nightmare. It usually happens because of a runaway client loop or a bloated query you didn't notice. To prevent this from happening on your next project, you need real-time monitoring and alerts before you hit the limit. We are building usagebill (usagebill.io) for exactly this reason. It's a lightweight wrapper for the Supabase client that tracks egress bytes in real-time. We are launching a free tier for developers, which sends you alerts long before you hit your limits, so you never get surprised by a locked database again. Reach out to support, they should get you sorted out quickly!
This is a classic trap when trying to monitor or audit usage in Supabase. First, database-level connection logs are full of internal noise. The postgres\_exporter, mgmt-api, and dashboard polling generate hundreds of queries per hour even when your app is completely idle. If you ever try to build tenant billing or usage tracking based on database logs, you'll end up charging your users for Supabase's own internal infrastructure housekeeping. Second, that public bucket bot scrape is a nightmare. Supabase only shows egress at the project level, meaning you won't know which tenant (or bot) is burning through your quota until you get the alert. We are actually building usagebill (usagebill.io) to address exactly this. Instead of tracking at the database level, it's a lightweight client-side SDK wrapper that monitors egress, rows, and requests at the application layer. This filters out 100% of the internal Supabase background noise and attributes egress directly to specific tenants or sessions, allowing you to set alerts/limits before a bot drains your quota. Kudos to the Supabase support team for helping you identify the public bucket issue so quickly!