AI startups face a billing problem that generic subscription platforms cannot solve. You need to charge for tokens consumed by an LLM call, GPU seconds for a fine-tuning job, and agent runs that span multiple API invocations. You also need to handle sales tax in 50 states, VAT in the EU, dunning logic, and receipts. Building this from scratch takes months and pulls engineers away from the product.
Polar (10,141 stars, trending #13 in Python) is an open-source billing platform designed for AI workloads. It meters usage at the event level, composes pricing models (usage + subscriptions + credits), and acts as merchant of record to handle tax and compliance. The stack is FastAPI + Next.js + Turborepo, and the architecture exposes APIs for real-time metering, pricing queries, and checkout flows.
This article examines the plumbing: how Polar meters high-throughput events without bottlenecks, where the boundary sits between usage tracking and merchant-of-record responsibilities, and how pricing models compose in a way that agents or billing APIs can enforce in real-time.
The Metering Problem for AI Workloads
Traditional SaaS billing tracks seats or flat subscriptions. AI products charge for:
- Tokens: input and output tokens per LLM completion
- Agent runs: multi-step workflows that invoke tools, APIs, and models
- GPU seconds: compute time for training or inference
- Storage: vector embeddings, model weights, or user data
Each event must be recorded with sub-second precision, attributed to the correct customer, and aggregated for billing cycles. If your agent orchestrator runs 10,000 tasks per minute, you cannot afford to block on a synchronous billing API call for every token count.
Polar’s approach is event-driven metering. Your application sends usage events to Polar’s API as they occur. Polar aggregates them asynchronously and exposes real-time metrics for dashboards and enforcement logic.
Architecture: Event Ingestion and Aggregation
Polar separates event ingestion from billing computation. The ingestion layer accepts usage events via REST or webhook, validates them, and writes them to a time-series store. The aggregation layer runs periodic jobs to sum usage, apply pricing rules, and generate invoices.
Event Ingestion Flow
- Application emits event: Your agent orchestrator or LLM proxy sends a POST request to
/v1/usagewith payload:{ customer_id, metric, quantity, timestamp, metadata }. - Validation: Polar checks that the customer exists, the metric is defined in the product configuration, and the timestamp is within an acceptable window (to prevent replay attacks or clock skew issues).
- Write to event store: The event is written to a time-series database (likely PostgreSQL with partitioning or ClickHouse for high-volume scenarios).
- Acknowledge: The API returns 202 Accepted immediately. The event is queued for aggregation.
This design keeps the ingestion path fast. The application does not wait for billing computation. If the event store is temporarily unavailable, the API can buffer events in Redis or a message queue (RabbitMQ, Kafka) and replay them later.
Aggregation and Pricing Computation
Polar runs scheduled jobs (every minute, hour, or day depending on the metric) to:
- Query events: Fetch all events for a customer and metric within the billing period.
- Apply pricing rules: Multiply quantity by unit price. If the product uses tiered pricing (first 1M tokens at $0.01, next 10M at $0.008), the job walks the tiers and computes the total.
- Update usage totals: Store the aggregated usage in a
customer_usagetable. This table powers real-time dashboards and enforcement checks. - Generate line items: At the end of the billing cycle, create invoice line items for each metric.
The aggregation layer is idempotent. If a job runs twice, it produces the same result. This is critical for retries and backfill scenarios.
Composing Pricing Models
Polar supports multiple pricing primitives and lets you combine them in a single product:
- Usage-based: Charge per token, API call, or GPU second.
- Subscriptions: Flat monthly or annual fee.
- Seats: Per-user pricing.
- Credits: Prepaid balance that decrements with usage.
- Trials: Free usage up to a limit, then convert to paid.
- Discounts: Percentage or fixed-amount reductions.
The pricing engine is a rule evaluator. Each product has a JSON configuration that defines metrics, tiers, and modifiers. When an invoice is generated, the engine walks the rules and computes the total.
Example Pricing Configuration
{
"product_id": "ai-agent-platform",
"pricing": {
"subscription": {
"base_fee": 99.00,
"interval": "month"
},
"usage": [
{
"metric": "llm_tokens",
"unit_price": 0.00001,
"tiers": [
{ "up_to": 1000000, "price": 0.00001 },
{ "up_to": 10000000, "price": 0.000008 },
{ "above": 10000000, "price": 0.000005 }
]
},
{
"metric": "agent_runs",
"unit_price": 0.05
}
],
"credits": {
"enabled": true,
"initial_balance": 100.00
}
}
}
This configuration charges a $99 monthly subscription, meters tokens with tiered pricing, charges $0.05 per agent run, and gives customers a $100 credit balance. The billing engine applies credits first, then charges the remaining balance to the payment method.
Real-Time Enforcement
Agents or API gateways need to know if a customer has exceeded their quota before starting a task. Polar exposes a /v1/usage/current endpoint that returns the customer’s current usage and remaining balance.
Your orchestrator can call this endpoint before launching an agent run:
import httpx
async def check_quota(customer_id: str, metric: str, quantity: int) -> bool:
response = await httpx.get(
f"https://api.polar.sh/v1/usage/current",
params={"customer_id": customer_id, "metric": metric},
headers={"Authorization": f"Bearer {POLAR_API_KEY}"}
)
usage = response.json()
return usage["remaining"] >= quantity
If the quota is exhausted, the orchestrator can reject the request or prompt the customer to upgrade.
Merchant of Record: Tax, Receipts, and Dunning
Polar acts as merchant of record, which means it is the legal seller of your product. This shifts tax compliance, receipt generation, and payment failure handling to Polar.
Tax Calculation
When a customer checks out, Polar determines their tax jurisdiction based on IP address, billing address, or VAT ID. It calculates sales tax (US), VAT (EU), or GST (Australia, India) and adds it to the invoice. The tax logic is powered by a third-party service (likely Stripe Tax or Avalara) and updated automatically when rates change.
Your application does not need to track tax rules or file returns. Polar handles remittance and provides you with a net payout.
Dunning and Payment Retries
If a payment fails (expired card, insufficient funds), Polar’s dunning engine retries the charge on a schedule (day 1, day 3, day 7). It sends email notifications to the customer and updates the subscription status. If all retries fail, the subscription is paused or canceled.
Your application receives webhook events for payment failures and subscription changes. You can use these events to disable access or prompt the customer to update their payment method.
Observability and Failure Modes
Polar exposes metrics for event ingestion rate, aggregation latency, and payment success rate. You can integrate these metrics with Datadog, Prometheus, or Grafana.
Common Failure Modes
| Failure Mode | Impact | Mitigation |
|---|---|---|
| Event ingestion lag | Usage not reflected in real-time dashboards | Buffer events in Redis, increase aggregation frequency |
| Clock skew in event timestamps | Events rejected or attributed to wrong billing period | Validate timestamps on ingestion, allow small window |
| Payment gateway downtime | Customers cannot check out or update payment methods | Retry logic, fallback to manual invoicing |
| Tax calculation service outage | Checkouts fail or charge incorrect tax | Cache tax rates, degrade gracefully to estimated tax |
| Aggregation job failure | Invoices not generated on time | Idempotent jobs, alerting on job duration or failure count |
The most critical failure mode is event loss. If the ingestion API drops events, customers are undercharged and you lose revenue. Polar mitigates this with at-least-once delivery guarantees (events are acknowledged only after being written to durable storage) and reconciliation jobs that compare application logs with Polar’s event store.
Deployment Shape
Polar is self-hosted or used as a managed service. The self-hosted stack requires:
- PostgreSQL: Event store and application database
- Redis: Event buffer and cache
- FastAPI backend: Event ingestion, aggregation jobs, and API
- Next.js frontend: Customer portal and admin dashboard
- Stripe or payment gateway: Payment processing
The managed service (polar.sh) handles infrastructure, scaling, and compliance. You integrate via API and webhooks.
For high-throughput AI workloads (millions of events per day), consider:
- Partitioning the event store by customer or time range to keep queries fast.
- Using a message queue (Kafka, RabbitMQ) between ingestion and aggregation to decouple components.
- Caching pricing rules in Redis to avoid repeated database queries.
Technical Verdict
Use Polar if:
- You charge for tokens, agent runs, GPU seconds, or other usage metrics and do not want to build metering infrastructure.
- You need to compose usage billing with subscriptions, credits, or trials.
- You want to offload tax compliance, receipts, and dunning to a merchant of record.
- You prefer open-source software and need to self-host for compliance or cost reasons.
Avoid Polar if:
- Your pricing model is simple (flat subscription or seats only) and you can use Stripe Billing or Chargebee directly.
- You need sub-millisecond latency for quota checks (Polar’s API adds network round-trip time).
- You require custom billing logic that does not fit Polar’s pricing primitives (you will need to fork or extend the codebase).
- You are not ready to handle webhook integration and event-driven architecture in your application.
Polar solves the billing problem for AI products by treating usage as a first-class primitive. The event-driven architecture keeps ingestion fast, the pricing engine composes multiple models, and the merchant-of-record layer handles compliance. If you are building an AI startup and need to charge for what customers actually use, Polar gives you the plumbing without the months of engineering work.
Source Links
- Primary repository: github.com/polarsource/polar
- Documentation: polar.sh/docs
- API reference: polar.sh/docs/api-reference