Trigger.dev bills its cloud customers per millisecond of compute. To do that, OpenMeter — the self-hostable metering engine Trigger.dev runs underneath it — has to ingest, batch, and aggregate every usage event in near real time, at a rate its own engineering blog describes tuning for "as big as 100,000 records per second." That's the kind of precision a real usage-based billing product needs. It's also two entire stateful services — Kafka and ClickHouse — that a self-hosted PaaS would be signing up to run on its own owned hardware, for a billing question most of its tenants aren't actually asking yet.
Here's the concrete trade, priced out: what standing up OpenMeter's own stack costs on Hetzner hardware, against what it costs to bill tenants on the coarser signals bex already computes for its own capacity planning.
The two numbers, side by side
| Self-hosted OpenMeter | Billing on signals bex already has | |
|---|---|---|
| New stateful services | Kafka (event streaming) + ClickHouse (aggregation) + Postgres (billing/subscription metadata via Ent ORM) | Zero — reuses the scheduler's container-seconds counter and the proxy's egress-byte counter |
| Minimum hardware | One box sized for ClickHouse (CPX41, 8 vCPU/16GB, €32.99/mo post-June-2026 Hetzner repricing) + a second for a Kafka broker (CPX22, 2 vCPU/4GB, €7.99/mo), plus Postgres if not already running one | $0 marginal — the counters already exist for bex's own resource-planning dashboards |
| Ops surface added | Kafka Connect sink monitoring (exactly-once delivery), dead-letter-queue reprocessing, materialized-view schema migrations, a second replicated datastore to back up | None — same backup/monitoring surface bex already runs |
| Billing granularity | Sub-second, per-event, tiered/graduated pricing with real-time quota enforcement | Per-minute or per-hour buckets — coarse, but accurate to what a git-push tenant's bill actually depends on |
| Precision earns its keep when… | Charging per-millisecond compute (Trigger.dev) or per-token inference | Charging for "your app ran for N container-hours and moved M GB" — which is what most PaaS tenants are actually billed on today |
The bottom-line number: roughly €41/month minimum in new hardware (before accounting for replication, backups, or the second Postgres most self-hosters would want dedicated rather than shared with a control plane) to get OpenMeter's precision — against $0 in new infrastructure to bill on counters a Cluster-API-based PaaS already has running for its own scheduling decisions.
What OpenMeter actually buys, and who's already paying for it
OpenMeter isn't solving an imaginary problem. It's Apache-2.0-licensed, ingests usage events in CloudEvents format, computes tiered and graduated pricing, and enforces per-feature quotas with real-time balance tracking — and it's already in production at Trigger.dev doing exactly the job it was built for: metering compute by the millisecond so a background-jobs platform can bill customers for precisely the CPU time their functions consumed, no more, no less.
Under the hood, that precision comes from a genuinely well-engineered pipeline. Events land in Kafka, get pre-aggregated into one-minute tumbling windows, and flow into ClickHouse via Kafka Connect's ClickHouse sink, which OpenMeter's own engineering explicitly chose because it "guarantees exactly-once delivery between Kafka topics and ClickHouse tables" — a detail that matters enormously when a duplicated or dropped event turns into an incorrect invoice line. ClickHouse's AggregatingMergeTree engine backs the materialized views that make querying "how much did tenant X use last hour" fast even at millions of events. None of that is over-engineering for the problem it's aimed at. It's the right architecture for per-millisecond, per-token billing.
What it actually costs to stand up yourself
The catch is that none of those guarantees are free to operate, and "just deploy the Helm chart" undersells what's on the other side of it. OpenMeter's own Kubernetes docs note that Kafka and ClickHouse get deployed alongside the application chart — which means a self-hoster now owns two more stateful services with their own failure modes, on top of whatever Cluster-API-managed Postgres and ingress stack the PaaS already runs.
Sizing those two services conservatively on Hetzner, post the June 15, 2026 repricing that pushed CPX-line shared-vCPU boxes up 2.4-2.75x in the EU: a single ClickHouse node handling a self-hosted PaaS's tenant volume (nowhere near Trigger.dev's scale) fits comfortably on a CPX41 — 8 vCPU, 16GB RAM — at €32.99/month. A single Kafka broker for a fleet this size fits on a CPX22 — 2 vCPU, 4GB RAM — at €7.99/month. That's €40.98/month in raw compute for a non-replicated, single-node version of each service — the version you'd run for evaluation, not the one you'd trust with actual invoices. A production-safe setup wants at least a second replica of each for failover, plus a dedicated Postgres instance for OpenMeter's own subscription and entitlement metadata rather than sharing the PaaS's existing database — pushing the realistic floor closer to €100-150/month before any of the ongoing ops work.
And the ops work is the part a monthly hardware number doesn't capture. Kafka Connect's dead-letter-queue pattern for failed records needs someone watching it and reprocessing what lands there. ClickHouse's materialized views need schema migrations coordinated with the ingestion pipeline. Two more stateful services means two more things in the backup rotation, two more things that page someone at 3am, two more version upgrades to track for CVEs. None of that is a criticism of OpenMeter's design — it's a genuinely well-built system for the job it targets. It's a statement about what "the job it targets" costs to run when your actual billing granularity doesn't need it.
The bolt-on alternative bex already has for free
A Cluster-API-managed fleet already tracks two numbers for reasons that have nothing to do with billing: how many container-seconds each tenant's workload actually ran (the scheduler needs this for capacity planning and bin-packing), and how many bytes crossed the tenant's egress path (the proxy layer needs this to catch abuse and plan bandwidth). Those two counters, rolled up into per-tenant tiers — say, included container-hours and included GB per plan, with a per-unit overage rate past that — cover the billing model every hosted PaaS this blog has looked at actually ships: Render, Railway, and Fly.io all bill on some combination of compute-time and bandwidth, not per-millisecond or per-token precision.
Building that bolt-on version costs approximately nothing in new infrastructure, because the counters already exist and the aggregation window that matters (hourly or daily, for an invoice) is orders of magnitude coarser than the one-minute tumbling windows OpenMeter computes for a use case that needs sub-second accuracy. Where OpenMeter earns a Kafka topic and a ClickHouse table per event, a coarse-grained bolt-on can get away with periodically summing counters bex's own control plane already increments — no separate event-streaming pipeline required.
Concretely, a tier could read: 100 included container-hours and 50GB of included egress per month on the Starter plan, with overage priced per container-hour and per GB past that — computed by a cron job that sums the scheduler's per-tenant counters once an hour and writes a running total to the same Postgres instance the control plane already uses. That's the entire "billing engine": one query, one table, one existing database. It can't tell a tenant apart by which specific API call they made in a given second, and it doesn't need to — nothing about a git-push deploy's cost structure depends on that granularity.
Where the extra precision actually pays for itself
The honest dividing line isn't "usage-based billing is overkill" — it's whether the thing being billed varies faster than an hourly rollup can capture. Trigger.dev needs per-millisecond precision because its customers' bills genuinely hinge on exact function-execution time, where a coarse hourly bucket would either overcharge a burst of tiny invocations or undercharge one that ran long. An AI-agent sandbox platform charging per-token or per-inference-second has the identical shape of problem — cost varies within the same hour by an order of magnitude depending on what model call happened when.
A git-push PaaS's typical tenant doesn't have that shape. Their container runs for hours or days at a time, and their bandwidth use trends smoothly across a billing period — an hourly rollup of container-seconds and egress bytes captures essentially the same signal a sub-second Kafka pipeline would, because the underlying usage pattern doesn't have the sub-hour volatility that makes coarse buckets lossy. The right trigger for adopting OpenMeter's stack isn't "we want more accurate billing" in the abstract — it's "we're about to ship a product where usage genuinely swings within the hour," at which point paying for Kafka and ClickHouse buys real accuracy instead of infrastructure for a granularity problem the tenant base doesn't have yet.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. It bills on the same container-time and bandwidth signals its own scheduler already tracks, so there's no second metering stack to run before you can see what a tenant owes. Star the repo on GitHub or deploy your first app today.



