XCubes

Price, volume and mix

Revenue is 270 above budget. Is that because you charged more, sold more, or sold more of the expensive products? Price / volume / mix answers it: it splits the variance in a value (revenue, gross margin) between two slices into the part each cause explains.

The two slices are any two items of one dimension: Actual against Budget, or June against last June when the dimension you compare along is time. Below, 0 is the reference slice and 1 the actual one.

What it needs

With a price line, the value is price × quantity cell by cell.

The convention

For each item i, with Q its quantity, P = value ÷ quantity its unit price, and Qt the total quantity of the continuing items:

Effect Per item
Price (P1ᵢ − P0ᵢ) × Q1ᵢ
Volume (Q1t − Q0t) × (Q0ᵢ ÷ Q0t) × P0ᵢ
Mix (Q1ᵢ ÷ Q1t − Q0ᵢ ÷ Q0t) × Q1t × P0ᵢ

Volume + mix = P0ᵢ × (Q1ᵢ − Q0ᵢ), so the three effects add up to P1ᵢ × Q1ᵢ − P0ᵢ × Q0ᵢ, the item's whole variance. They tie per item and in total within the check-row tolerance, half a cent.

A worked example

Product Budget Actual
A 100 @ 10 = 1,000 120 @ 11 = 1,320
U 40 @ 10 = 400 40 @ 10 = 400
C 20 @ 15 = 300 —
D — 10 @ 25 = 250

C was discontinued and D launched, so only A and U continue: Q0t = 140 and Q1t = 160. A's price effect is (11 − 10) × 120 = 120. Volume across A and U is 20 more units at the budget average of 10, so 200, and mix is 0 because A and U have the same budget price. C and D give −50. Altogether 120 + 200 + 0 − 50 = 270 = 1,970 − 1,700.

New and lost items

A product sold in only one slice has no price on the other side, so there is no honest way to give it a price or a mix effect. Its whole change is reported on its own as New / lost, and its quantity stays out of the totals Q0t and Q1t. Otherwise a launch would show up as volume and mix on the products that were there all along.

Edge cases

On a dashboard

A variance widget has a Show setting: Variance table or Price / volume / mix waterfall. The waterfall starts at the reference value, steps through price, volume, mix and new/lost, and lands on the actual value. The caption below it says which level it decomposed at, how many items were new or lost, and any flag. Pick the dimension that holds the quantity and value lines, then the two lines and the level. The widget's page filters and the dashboard's nav bar select the rest of the slice, as in table mode.

With the assistant

get_price_volume_mix returns the same decomposition per item and in total, with the flags and a ties check: "how much of the revenue miss is price?", "is it mix or volume?". add_variance_widget with a pvm block puts the waterfall on a dashboard. Both use the same calculation as the widget, so the numbers agree.