Skip to main content

Overview

Opportunity Sizing answers the question people actually ask about a metric: not “where does this number vary?” but “how do I improve it, and by how much?” It lives in the World Model Graph — the Globe icon in the icon rail (a surface distinct from the Context Graph and the Metric Tree). Open a measure on the graph and Oxygen scans your data for segments that underperform a benchmark, puts a dollar figure on each gap, and then lets you drill that gap into its underlying drivers until you reach something specific enough to act on. The result is a ranked list of addressable upside — “mobile orders run $218.50/order below in-store; closing that gap is worth +$264.6k” — where every number is backed by a statistical test and every child in the breakdown provably sums back to its parent.
Opportunity Sizing operates on the semantic layer. It reads your existing measures, dimensions, and the relationships between views — you don’t define opportunities anywhere. The quality of the sizing depends directly on how well your model is defined (see What your model needs).

The core idea: size on rates, not totals

An opportunity has two ingredients — a gap and a volume:
The single most important design decision is that Oxygen compares per-unit rates, never raw totals. If you compared raw sums, a segment sitting below another would mostly reflect that it is smaller — fewer rows, a smaller market — not that it underperforms. Comparing revenue-per-check instead of revenue makes the comparison about performance, so “smaller” never reads as “worse.” Then multiplying the per-unit gap back by the segment’s real volume turns it into an honest, addressable dollar figure.
Oxygen refuses to guess rather than emit a misleading number. If a measure is an additive total (like a sum) but its view declares no count measure to form a rate, the panel returns an empty result that explains why — it will not silently fall back to comparing totals. This is deliberate: a size-confounded number that looks precise is worse than no number.

Picking the benchmark

The benchmark is the bar every segment is measured against. Oxygen picks it from the data automatically: Crucially, the benchmark is defined as a population filter (dim = best_peer or dim IN (segments at or above p75)), not as a bare number. That’s what lets the drill query the benchmark population later, rather than just comparing against a fixed scalar.

Three sizing modes

How a segment gets weighted into a dollar figure depends on what the measure supports: Only rows responses carry a directly addressable upside and get ranked in the Opportunities list. The other bases still power the drill breakdown.

Trustworthy numbers: the evidence gate

Any tool can find a “top lever” in any dataset — including one where the dimension is provably unrelated to the measure. Opportunity Sizing is deliberately rigged against itself and corrects for the two ways a naive scan fools itself.
The benchmark is the maximum (or P75) of the same segments being tested against it. Draw a handful of values from pure noise and the largest one naturally sits well above the mean — so a fixed threshold “discovers” a leader in literally any dimension. Oxygen raises the bar by exactly that expected amount, so noise doesn’t clear it.
A full scan makes on the order of a hundred comparisons once related entities are followed. At a naive 5% per test, five spurious levers per scan is the expected yield. Oxygen applies a Šidák correction across the whole scan family, so 20 dimensions × 5 segments needs a much higher bar of evidence than any single dimension would imply on its own.
The test itself is Welch’s t-test (not pooled variance), because the benchmark is routinely the thinner of the two populations, and a pooled estimate would understate the error exactly where it matters most. With a two-row benchmark, the effective degrees of freedom collapse and the gap has to be genuinely large to survive.

Three outcomes, kept distinct

Oxygen never blurs “proven” with “plausible”: The third row is the honest one. gated: false does not mean the gap is fake — it means nobody could prove it real, and the panel never presents it as proven upside. The skip reason also distinguishes “everything I found was noise” from “everything already matches the benchmark,” because those are different answers and you’re entitled to know which one you got.

Drill: decomposing the gap into drivers

Finding a gap is half the job. Drill decomposes that gap recursively — alternating two kinds of split — until it reaches a driver specific enough to act on:
  • Component splits come from the measure’s own formula (revenueentrée revenue + add-on revenue).
  • Dimension splits cut by an attribute (add-on revenue → by category).
The flow is recursive and domain-free: decompose a per-unit gap through structure until you hit something specific.

Two rules make the math honest

1

The denominator never changes

When the numerator is split by a dimension, the denominator is not filtered with it. sides/order means sides revenue ÷ all of that segment’s orders — not ÷ sides count. Change the denominator and the children stop summing to the parent.
2

The benchmark is inherited, never re-picked

Every level compares the same two populations chosen at the root. If each child picked its own best peer, the children would stop summing to the parent and every percentage would be fiction.

Why those rules matter

Given both rules, the decomposition becomes an arithmetic identity, not a fresh comparison at each level:
This is what earns a child the right to say “91% of the parent gap.” It is not an estimated or heuristic ranking — it is arithmetic, and the children provably sum back to the parent at every level.

What a drill looks like

The last split (sides/order = attach_rate × price_per_side) answers “fewer sides, or cheaper sides?” — the volume-vs-value question — inside the decomposition, with no extra machinery.

At each level, the drill:

  1. Enumerates candidates — component edges from the measure’s formula, plus every dimension not already consumed higher up.
  2. Computes each child’s gap and its share of the parent gap.
  3. Ranks by concentration (which child holds the most of the gap).
  4. Shows all children with their shares — not just the winner. Siblings stay visible, so “follow the max” is a reading aid, not a hidden selection.
  5. Recurses into the largest child.
  6. Stops when the next split fails the evidence gate, can’t be evidenced, has no candidates left, or hits max depth.
Every level renders its stop reason, and a level that couldn’t be evidence-checked is shown as ungated — never as proven. The statistical error budget is also split across depth, so an N-level drill doesn’t quietly spend the full 5% error at every line.

How to use it

1

Open the World Model Graph

Click the Globe icon in the icon rail to open the graph of your semantic layer.
2

Select a measure

Click a measure node. Oxygen scans its segments on mount and, if it finds addressable upside, reveals an Opportunities section — addressable upside · and where it comes from.
3

Read the ranked segments

Each row shows the segment, its per-unit rate versus the benchmark (543.9 → 762.4 per order), the dollar upside, and a proportion bar. Use the copy button on a row to drop a ready-made investigation question into chat.
4

Drill into a gap

Expand a segment to decompose its gap. The drill runs on expand only — never on mount — because it issues recursive queries against your warehouse. Follow the highlighted child down until the stop reason tells you there’s nothing left to prove.

What your model needs

Opportunity Sizing is only as good as the semantic model underneath it. To get the most out of it:
  • Declare a count measure on the view. Without a count denominator, a sum measure can’t be put on a per-unit basis, and Oxygen will refuse to size it rather than compare totals.
  • Model your metrics compositionally. A measure defined as a sum or difference of same-view measures (net_revenue = entrée_revenue + add_on_revenue) gives the drill component edges to follow. Mirror trees work too — a gross_profit tree that parallels revenue lets you drill margin the same way you drill revenue.
  • Keep dimensions meaningful to benchmark across. A dimension where being “higher” is a matter of arithmetic rather than performance (for example, party size — a 6-top spends more than a 2-top by definition) will dominate the ranking without telling you anything. Prefer dimensions where a gap reflects something you can change.
  • Point it at measures where higher is better. Both benchmark bases are top-end rates, so a segment below the benchmark is always read as upside. That’s right for revenue, margin, or conversion and backwards for a cost — a cost sum with a count on its view would rank the cheapest segment as the biggest opportunity. Size the revenue or profit side and let the drill walk into the cost components, rather than rooting a scan on a cost measure.

Current scope

Opportunity Sizing is honest about what it can and can’t do — and about why it can’t. What it refuses, it refuses by design: sizing those shapes would break the arithmetic identity the drill depends on. There is no “not yet” bucket — a shape either sizes today or is a permanent boundary, never a quietly deferred promise. Works today
  • sum roots with a count on their view
  • Additive same-view composites (a + b − c), including nested ones (a composite whose child is itself a same-view composite — it flattens transitively)
  • Homogeneous +/ and ×/÷ expressions
  • Dimension splits and cross-grain numerators
By design — Oxygen refuses these rather than emit a number that looks precise but isn’t. They break the sum-to-parent identity, so no future work will “fix” them without a different model: Comparing a revenue drill against a margin drill side-by-side works today — it’s two drills you read together. Ranking add-on leaves by profit rather than revenue changes which leaf wins, so a true single-pass co-ranking (“big revenue gap, thin margin”) is a presentation improvement, not an engine limitation — the engine already sizes each measure on its own.

In one paragraph

Oxygen sizes an opportunity as (per-unit rate gap vs a benchmark segment) × volume — per-unit rather than raw totals, so “smaller” never reads as “worse.” The drill then decomposes that gap recursively, alternating splits from the measure’s own formula with splits by dimension, holding the denominator and the benchmark fixed the whole way down. Those two constraints turn the decomposition into an arithmetic identity, which is what lets a child legitimately claim “91% of the parent gap” and makes children provably sum back to the parent. It stops when the evidence gate can no longer prove the next split — and it always tells you why it stopped.

Measures

Define the measures and composite metrics that Opportunity Sizing decomposes

Dimensions

The attributes the drill splits a gap by

The Metric Tree

How measures compose, and the driver edges the drill follows

World Model

How the semantic model, metric tree, and entity graph fit together