Usage Metering and Billing
1. v0.1 commercial model
Use participant-minute as the primary billable unit.
Example:
Participant A: 30 minutes
Participant B: 30 minutes
Total: 60 participant-minutes
This is independent of the customer's business price for a consultation.
2. Internal precision
Store usage in seconds.
Display and price using a configurable billing rule.
Example initial policy:
raw duration second precision
billing aggregation project-level
commercial display participant-minutes
Whether to round each session or total monthly usage should be a plan setting, not embedded in event handlers.
3. Technical metrics
Store technical usage separately even if v0.1 has one simple commercial price:
participant_seconds
audio_seconds
video_seconds
screen_share_seconds
bytes_in
bytes_out
region
media_node
TURN usage where measurable
This allows future plans such as audio-only, HD, recording, or bandwidth-based pricing without losing historical data.
4. Source of truth
Billing is derived from finalized participant sessions, not directly from customer webhooks.
Pipeline:
Media engine event
|
v
raw event store
|
v
participant session reconciliation
|
v
usage record finalized
|
v
pricing
|
v
usage charge
|
v
wallet ledger
5. Event reconciliation
Workers must handle:
- duplicated joined event
- duplicated left event
- missing left event
- reconnect
- service restart
- out-of-order event
- room force-close
- media-node failure
Each active session has last_seen_at.
A reconciler periodically checks media-engine state and closes stale sessions according to policy.
6. Reconnect grace period
A short disconnect should not create confusing billing gaps.
Suggested configurable concept:
reconnect_grace_seconds
Example behavior:
- participant loses network
- reconnects within grace period
- same logical participant session remains billable according to project policy
The exact policy should be explicit and documented to customers.
7. Plans and prices
Do not hard-code the per-minute price in code (the default is 0.00699 USD per participant-minute, i.e. $6.99 per 1,000).
Use data:
plan
metric
unit_size
unit_price
currency
effective_from
Possible beta plan:
Metric: participant_minute
Price: configurable
Currency: USD
A public launch price is a commercial decision after capacity/load testing.
8. Prepaid first
v0.1 uses prepaid credit.
Advantages:
- simple risk model
- no collection process
- easy beta onboarding
- immediate quota enforcement
- suitable for small teams and startups
Flow:
top-up
|
wallet credit
|
RTC usage
|
usage charge
|
wallet debit
Online top-ups (Stripe Checkout, POST /v1/billing/topups) accept 5.00 to
10,000.00 USD per payment. The maximum is a product limit, well under
Stripe's own Checkout ceiling (999,999.99 USD); larger prepayments are
invoiced and credited by an operator (make prod-credit).
A top-up whose Stripe session was never created (the Stripe call failed
or timed out) stays creating with no provider reference. The payment
reconciler marks it expired with failure_code
provider_session_not_created after 25 hours, past Stripe's 24-hour
Checkout expiry, and emits payment.expired like any other expiry. If a
session did exist and is paid anyway, the Stripe webhook still credits it.
9. Wallet ledger
Every money mutation creates an immutable ledger row.
Example:
+1000.00 topup
-6.00 usage_charge
+6.00 refund
-50.00 adjustment_debit
Never rewrite history.
A correction creates a compensating entry.
10. Balance checks and session grace
The Beta policy is implemented as:
- room creation does not reserve or debit credit
- participant creation requires balance >=
minimum_credit_to_start /v1/connectre-checks the same credit gate- an already-active call is never terminated just because balance reaches zero
- finalized usage is always charged, even when the resulting balance becomes negative
- a negative/exhausted balance blocks the next participant/connect until credit is restored
This avoids losing billable usage while also avoiding an unexpected mid-consultation disconnect.
Project-configurable fields:
participant_minute_price
low_credit_threshold
minimum_credit_to_start
Credit state:
normal
low
exhausted
Transitions emit:
credit.low
credit.exhausted
credit.restored
11. Reservations
v0.1 does not require wallet reservation for every room.
Later, projects may optionally reserve estimated maximum usage before allowing a session.
Keep schema flexible for:
reserved_balance
reservation
reservation_release
12. Charge idempotency
Each finalized usage record can be charged once.
Database unique constraint:
usage_record_id
Charging transaction:
- lock wallet/account row
- ensure usage record has no charge
- take the price, currency and billing_enabled snapshotted on the usage record (records with billing disabled are waived and never charged)
- calculate decimal amount
- debit wallet (session-grace settlement may make balance negative)
- insert usage_charge
- insert immutable wallet ledger debit
- update credit state and queue any credit webhook event
- commit
All inside one database transaction.
13. Pricing precision
Use decimal arithmetic.
Never use binary floating point for USD balances.
Recommended concepts:
NUMERIC for money
integer seconds for usage
UTC timestamps
14. Refunds
Refund references the original charge.
Reasons:
service_incident
duplicate_charge
manual_support
billing_correction
Refund is a new ledger credit.
15. Free credit
Beta onboarding can grant promotional credit.
Use:
type=adjustment_credit
metadata.reason=beta_signup
Do not special-case promotional money outside the ledger.
16. Usage dashboard
Show:
- today participant-minutes
- current month participant-minutes
- audio/video split
- rooms
- estimated charge
- current balance
- low-credit status
- daily chart
17. Billing API guarantees
Usage dashboards may be near-real-time.
Ledger/balance is authoritative.
Clearly distinguish:
estimated usage
finalized usage
charged usage
18. Commercial metrics to watch
Before finalizing public price:
- actual bandwidth per 1,000 participant-minutes
- TURN percentage
- average bitrate
- CPU per concurrent participant
- peak concurrent rooms
- support overhead
- payment gateway fee
- backup/monitoring cost
- spare capacity target
- hardware/network amortization
- VAT/tax treatment
19. Future billing dimensions
Schema should permit:
audio participant-minute
SD video participant-minute
HD video participant-minute
FHD video participant-minute
screen-share minute
recording minute
recording storage GB-month
streaming egress GB
SIP minute
premium support
dedicated region
Do not implement these in v0.1.