Skip to main content

Segment MTU vs event-volume cost comparison

The endpoint POST /api/v1/cdp/mtu-cost-comparison re-prices your traffic two ways at once: what your current monthly tracked users (MTUs) cost on Segment’s MTU model, and what the same month costs on Orbit’s event-volume pricing. The response is a side-by-side estimate with monthly and annual deltas — a number you can carry into a budget review. Use it when you are mid-evaluation or mid-migration and need a concrete comparison to move a decision, not a pricing page screenshot.

Why the calculator exists

Segment bills on monthly tracked users. One identified user counts against your plan regardless of how many — or how few — events they emit, and crossing an MTU tier ceiling steps your whole plan price up in one jump. The result is two recurring complaints: surprise invoices when anonymous traffic becomes identified, and pricing that only exists inside a negotiated contract. Orbit’s CDP bills on event volume instead. A spike of anonymous traffic does not inflate a user meter; the price follows the events you actually send, on the published event-volume tier table. Two things to understand before you quote the comparison:
  • It is a comparison, not a discount promise. The response tells you what the same traffic costs under each pricing model. It does not guarantee a saving — heavy event volume per tracked user can flip the result the other way, and orbit_is_cheaper will say so.
  • The MTU price comes from you. Orbit never asserts a competitor’s contracted price as fact. The default tier table is drawn from Segment’s public list pricing; once you have a real quote, you pass it in and the comparison re-prices against your actual numbers.

What the caller supplies

Send three fields in the request body: Pull both counts from your existing instrumentation: Segment usage reports give you the MTU count, and your workspace’s event counts give you monthly_events. Because the computation is pure — no account consumption, no data passed to any provider, nothing sent — you can run as many what-if shapes as you need. Role gate: owner, admin, developer, or billing roles can call it.
Omit mtu_tiers and the response is priced against the public-list default table, with used_default_tiers: true stamped on the Segment side so a reviewer knows which numbers entered the math.

Reading the response

The response echoes your inputs, then carries three blocks: segment, orbit, and comparison.

segment — the MTU side

orbit — the event-volume side

monthly_usd and annual_usd are the same shape as the Segment side. Three fields mark it as billing-grade rather than an estimate:
  • billed_cents — the integer cents the same event volume would bill at, computed by exactly the same calculation the cost-forecast dashboard shows on your account. If the numbers disagree, one of them is stale; they cannot drift independently.
  • tier_index — which band of the event-volume tier table your volume sits in.
  • pricing_version — version stamp for the event tier table. When pricing changes, this changes; re-run comparisons you cached.

comparison — the deltas

  • monthly_savings_usd and annual_savings_usd — Segment minus Orbit. Positive means Orbit is cheaper for your traffic shape; negative means it is not.
  • savings_pct — savings as a percentage of the Segment bill, or null when the Segment side prices at $0 (the free tier gives no denominator).
  • orbit_is_cheaper — the boolean summary; treat it as the headline, not the verdict.
  • events_per_mtu — back at the top level: your average events per tracked user. This is the transparency headline — it tells you how much of your event traffic the MTU model ignores. A shape with 10,000 MTUs and 12 million events is billed identically to one with 10,000 MTUs and 120,000 events on the MTU side; only the event-volume side prices the difference.

Setting the MTU table to the quote you actually have

The default table is a starting point, not a claim about your contract. Substitute your real quote into mtu_tiers — it replaces the whole table, so quote the response’s basis honestly:
Rules the table must follow — break one and the call returns 422 with a VALIDATION_ERROR that names the offending row:
  • Only the last band may be unbounded. The top band’s up_to_mtus must be null, and no earlier band’s may be. An earlier null is rejected.
  • Ceilings strictly increase. Each bounded up_to_mtus must be higher than the previous one.
  • Prices are finite and non-negative.
  • One to fifty bands — enough for any real quote.
A 422 on this endpoint is always an input problem, never a server problem. Read error.details — it names the field row and the rule.

Why the Orbit number cannot drift from your dashboard

The event-volume side is not a parallel pricing model. It reuses the same shared pricing table and the same billed-cents calculation that the billing overview and cost-forecast surface run — one authoritative set of bands, referenced by this endpoint rather than re-implemented. Two consequences worth leaning on in a review:
  • The calculator agrees with the dashboard by construction. If a billing change ships, the comparison, the forecast, and the invoice move together. Do not build a second price table in a spreadsheet and check it against this response — if your spreadsheet disagrees, the spreadsheet is wrong.
  • Version fields expose staleness. Cache pricing_version and model_version; when either changes, drop the cached comparison and re-run.

Worked example: small business

A retail app sends 750k events a month from 8,500 identified users — mostly browse and cart traffic.
Reading the result:
  • Segment side: 8,500 MTUs lands in the Team band (up to 10,000 MTUs, 120/mo).‘nextcliffatmtus‘is10,000and‘mtusuntilnextcliff‘is1,500—andthenextcliffisbrutal:‘nextcliffincreaseusd‘is∗∗120/mo). `next_cliff_at_mtus` is 10,000 and `mtus_until_next_cliff` is 1,500 — and the next cliff is brutal: `next_cliff_increase_usd` is **880/mo**, a 733% price step for the next 1,501st identified user.
  • Orbit side: 750k events bills $250/mo on the event table (the first 100,000 events per month are free; each further million bills at the second tier’s per-million rate, rounded per ceil-per-million).
  • Comparison: monthly_savings_usd is −$130/mo, savings_pct is −108.3%, orbit_is_cheaper is false. The comparison says what it says — high events-per-tracked-user means the MTU model actually wins. This is exactly why the endpoint exists: answer the comparison honestly, whatever direction the arrow points.
  • events_per_mtu ≈ 88.24 — a shape where the event bill outruns the MTU bill is a strong flavor of traffic.
  • The cliff verdict still holds. Even on the losing side, the Segment bill has headroom of 1,500 MTUs before an $880/mo step — and the event bill on Orbit stays smooth with growth.

Worked example: enterprise with a negotiated quote

An enterprise runs a $3,900/mo negotiated MTU contract (you — replace this example’s table with the real quote, as above) over 250,000 MTUs and 12.5M events per month, calling with mtu_tiers set as in the previous section:
  • Segment side: priced from your table at $3,900/mo, used_default_tiers is false, so nothing depends on our public-list defaults.
  • Orbit side: 12.5M events bills exactly $2,500/mo — the first 100k events free, then the per-million rates descend through the tier table (the first 10M events bill at the second and third tiers’ rates and the remainder at cheaper tiers — the geometric effect of descending per-million pricing).
  • Comparison: monthly_savings_usd is 1,400∗∗,‘annualsavingsusd‘is∗∗1,400**, `annual_savings_usd` is **16,800, savings_pct ≈ 35.9%.
Present both figures honestly: the annual number is the one finance plans around, and the “response basis” (which MTU table priced the Segment side) belongs in the same slide as the delta.

Production checklist

  • Treat the response as a pointer, not a claim. Before you present a comparison, state the basis: default table or real quote. Keep used_default_tiers visible in whatever slide or doc the number lands in.
  • Anchor example tier tables publicly. Every example table above is documented public list pricing — never a customer’s real quote. Do not paste an actual contract into docs, tickets, or examples; pass it in at request time instead.
  • Handle 422 as an input error. When the MTU table is malformed, re-render the offending row, not a generic failure.
  • Re-run on version change. pricing_version or model_version changed → drop cached comparisons and re-run. Do not quote stale comparisons at renewal time.
  • Use the delta honestly. A negative saving is an answer too. The calculator is a comparison tool — quote orbit_is_cheaper as the headline it is, whatever direction it points.