Skip to content

Usage & metering

PandaStack meters usage across seven billable dimensions and bills them through Stripe. Free plans never pay usage — the free plan is excluded from every billable dimension. Paid plans (pro, premium) are billed; enterprise is a flat contract.

There are seven billable dimensions, split into dollar-plan-gated meters (cost-operator computes a dollar amount) and overage meters (a flat per-unit price applied only past the plan allowance).

DimensionKindRateBilled forAllowance (free / pro / premium / ent)
container_costdollar-plan-gatedcost-operator dollars (Stripe 1¢/unit)pro, premiumn/a
database_costdollar-plan-gatedcost-operator dollarspro, premiumn/a
function_costdollar-plan-gatedcost-operator dollars (folds in GB-seconds)pro, premiumn/a
monitor_costdollar-plan-gated~$1/mo per monitorpro, premiumn/a
cronjob_costdollar-plan-gatedtier $/hr for run podspro, premiumn/a
build_minutesoverage$0.005/min ($5 per 1000)pro, premium (past allowance)300 / 1000 / 2500 / unlimited
bandwidth_mboverage$0.00015/MB ($0.15/GB)pro, premium (past allowance)100 GB / 500 GB / 1 TB / unlimited

isBillableForPlan returns false for free, so a free org is never charged usage on any dimension.

Container, database, function, monitor, and cronjob costs are computed as dollars by the cost-operator, which multiplies resource-hours by the tier rate. The data flow is:

cost-operator → BigQuery hourly_costs (tier-multiplied DOLLARS)
→ meter-sync (sums per window, emits INTEGER CENTS)
→ Stripe (price = 1 cent per emitted unit)

Because the Stripe price is exactly 1 cent per emitted unit (unitAmountDecimalCents = "1"), Stripe bills exactly the dollar amount the cost-operator computed — there are no per-tier Stripe price objects. Dollar-meters are billed for pro and premium; free is never charged; enterprise is a flat contract.

  • Functions are billed via function_cost — the cost-operator folds GB-seconds into that dollar figure. Functions are not billed as a separate invocation or GB-second meter.
  • Monitors are roughly $1/mo per monitor.
  • Cronjobs are billed at the instance tier’s $/hr for their run pods.

Build minutes and bandwidth are allowance-based overage dimensions. A flat per-unit price is applied only to usage past the plan’s monthly allowance, measured over the org’s Stripe billing period (not the calendar month). Enterprise (allowance -1) is never overage-billed.

User-locked overage rates (as of 2026-07-04):

DimensionRateStripe unit_amount_decimal
Build minutes$0.005/min ($5 per 1000 min)0.5
Bandwidth$0.15/GB = $0.00015/MB0.015

Overage example: a pro org that uses 1200 build minutes pays $0.005 × (1200 − 1000) = $1.00 for the 200 minutes past its 1000-minute allowance.

See Plans & limits for each plan’s allowances.

Some dimensions are rolled up for the dashboard Usage card but are never billed:

DimensionNotes
analytics_eventsrollup only
cronjob_runsread live from Postgres for the current month (dashboard); billing uses cronjob_cost
fn_invocationsread live from Postgres for the current month (dashboard); billing uses function_cost
fn_gb_secondsrollup only; folded into function_cost for billing

Function memory has a canonical marketing rate of $0.000167 per GB-second and an invocation rate of $0.000002, but these are display/marketing figures only — functions are billed through function_cost, not as separate meters.

Bandwidth is both metered (overage) and hard-enforced as a monthly quota at the gateway:

  • When an org exceeds its monthly bandwidth allowance, its sites are paused (Organizations.bandwidth_exceeded is set by a reconcile loop).
  • The dashboard shows a “bandwidth limit reached — upgrade to restore” banner.
  • Upgrading instantly unblocks the org’s sites.

Per-plan bandwidth allowances: free 100 GB, pro 500 GB, premium 1000 GB (1 TB), enterprise unlimited.

Billing status is exposed as { plan, cardVerified, hasStripeCustomer }. The Stripe customer id itself is never returned to the client.

A verified card is required to use the platform beyond a small allowlist. The card hard-wall enforces this on every non-allowlisted request:

  • An organization without a verified card (card_verified unset) receives 402 on org routes, except the allowlisted routes.
  • Once a card is verified, the wall lifts.

This is the same 402 semantics described in the Authentication page. It is distinct from 402 quota_exceeded (which comes from plan limits) — the card wall is a payment-verification gate.

To make sure you are never billed against a different allowance than the dashboard shows, a boot-time assertion ties the plan matrix to the billing rates: the API refuses to start if PLAN_LIMITS build-minute or bandwidth allowances drift from BILLING_RATES. See Boot-time consistency guard.