Calculation
A formula is written once and evaluated separately at every coordinate the dataseries covers. What each name in it means is decided by the coordinate being computed — which is why an Axmo model needs no lookups, and why a total is never invented on your behalf.
One formula, every coordinate
A formula in Axmo is written once and evaluated separately at every coordinate the dataseries covers — Dataseries says that much already. This page is about the step in the middle: how each name in the formula becomes a number, once the coordinate is fixed.
Take a Revenue series calculated as:
Quantity * PricePerUnit
Quantity varies by product and by month. PricePerUnit varies by product only. Nothing in the formula says how the two are to be lined up, and nothing needs to.
When Axmo computes Revenue for Shoes in January 2026, that pair of elements is the current context. Each name in the formula is then read at that context, projected onto the dimensions that name actually has: Quantity at Shoes × 2026-01, and PricePerUnit at Shoes. The formula does not change. Only the context moves.
This is why an Axmo model contains no lookups. In a spreadsheet, using a per-product price inside a per-product-per-month calculation means first bringing the price alongside every month — a VLOOKUP down the column, or twelve copies of the same number. Here there is nothing to bring. The price is where it has always been, and the context finds it.
A series is constant over a dimension it does not span
PricePerUnit is not connected to Time, so it holds no value that varies by month. Read at any month, it gives the same number: the one it holds for that product.
That is the whole rule, and it is worth stating in its general form, because everything else on this page follows from it. A series is read at the coordinates it has, and is constant over every dimension it does not span.
| 2026-01 | 2026-02 | 2026-03 | |
|---|---|---|---|
Quantity, Shoes | 10 | 20 | 30 |
PricePerUnit, Shoes | 50 | 50 | 50 |
Revenue, Shoes | 500 | 1 000 | 1 500 |
One precision, because the natural picture is slightly wrong. The price is not copied into each month, and there is no monthly price stored anywhere in the model. PricePerUnit holds one number per product, and that number is read three times. The constancy you see in the middle row is a property of how the context is projected onto the series — not of a value that has been duplicated.
Totals are declared, never invented
The rule does not change at a total. A series read at a coordinate of a dimension it does not span gives the same value there too — at a quarter, and at the year.
A headcount is the clearest case. Connect it to Department and to nothing else, and give Sales twelve people. Put that series in a report whose rows are months, and every month reads 12. Ask for the quarter: 12. Ask for the year: 12. Twelve months of it added together would be 144, which is not a number about anything.
Axmo will not produce that 144, and the reason is worth saying plainly: it does not know what kind of quantity your series holds. Adding up is right for a flow and badly wrong for a stock, and over a dimension the series is not connected to, there is nothing in the model that says which one this is. So nothing is assumed. The engine adds nothing you did not ask for.
Where you do want a figure to vary over Time, or to be totalled across it, you say so: connect the series to Time and choose its roll-up there. That choice belongs to each series, separately for each dimension, and Dataseries covers how to make it.
The same rule governs an expression written directly into an Output Range. It is evaluated at the coordinate it sits on, against each operand's own value there, rather than being built up from the rows beneath it.
Everything a formula touches has to resolve
So far the formula has needed fewer dimensions than the coordinate being computed. The opposite case is the one that stops a model compiling, and it is deliberate.
A series' dimensions are something you declare when you create it. The formula is then checked against that declaration, never the other way round. Axmo will not quietly widen a series because its formula reached for something extra: the shape you declared is the shape you get.
Suppose Target is connected to Time only, while Sales is connected to Currency and Time. Written as:
Sales * 2
the formula will not compile. Sales varies by currency, Target has no currency, and there is no answer to the question which currency's sales. Axmo names the dimension that is unaccounted for and tells you the two things you can do about it. You meet this while you are writing, in the Series Editor's message area, rather than after a calculation.
Both remedies are one edit, and they are not interchangeable — they answer different questions:
Sales[EUR] * 2 one currency's sales, doubled
SUM(Sales[Ccy]) * 2 every currency added up, then doubled
— where Ccy is the currency layer. Over the same data, the first gives 200 in January and 400 in February; the second gives 220 and 440. Both are correct. Only one of them is what you meant, and the model cannot choose for you, which is why it asks.
There is a third case, where neither remedy fits: the calculation genuinely needs two dimensions that no single series carries. The answer there is an intermediate series — a calculated series connected to both dimensions, which does the work at the finer shape, and from which the narrower series reads a total. It is one extra series, and it makes the step that was implicit into something you can look at.
You state relationships; Axmo works out the order
Nothing in a model says what to compute first. You write Profit = Revenue - Total Cost, and elsewhere Margin = Profit / Revenue, and which of those has to run first is a fact about the formulas — not something you should have to maintain, and not something a row order should decide.
Axmo works it out. Before anything is computed it reads every formula, works out what depends on what, and calculates in an order that guarantees each series has its inputs ready. Where a value has been entered above the leaf level and its series has been given a distribution method, it is distributed downwards before anything is rolled up; leaf values are rolled up afterwards, each by its own series' rule. Where no method has been chosen — which is the default — nothing is distributed, and the value stays where you put it. That is the rule from earlier on this page, seen from the other end: downwards as much as upwards, Axmo adds nothing you did not ask for. A series that refers to its own earlier value is computed period by period, in sequence.
There is one thing you cannot ask for, and that is an order which does not exist. Where series depend on one another in a way that has no resolution, Axmo says so rather than picking one — Recurrence rules sets out which self-references it can resolve and which it cannot.
Nothing computes until you ask
Axmo does not recalculate as you type. Nothing runs until you press Update, and that is deliberate: a model is a structure you edit, often several changes at a time, and recomputing between each of them would be work nobody asked for.
Between the change and the press, the panel reads Recalculation needed. That is a claim about freshness, not about correctness. It says Axmo has not verified these numbers since something happened that could affect them — an input changed, the definition was edited, or the workbook was reopened. It does not say the numbers are wrong, and nothing is thrown away: the values stay exactly where they were.
It is also why reopening a workbook shows you the figures it was saved with, rather than an empty sheet. Those are the numbers the last Update produced, and they are still right unless an input moved while Axmo was not running — which is something Axmo cannot observe, and therefore does not claim to have checked.
Next
Dataseries expressions is how a formula is actually written — references, filters, arithmetic, aggregation, conditions and missing values. Dimensional expressions is how you name the coordinates inside one. Recurrence is the case where a series refers to its own earlier values, and the reason the order in section five matters.
![A formula, Quantity * PricePerUnit, above the dimensions each of its two series carries — Quantity over Products and Time, PricePerUnit over Products alone — and a current context of Products = Shoes, Time = 2026-01. Arrows lead from both to the calculation Axmo actually performs: Quantity[Shoes, 2026-01] * PricePerUnit[Shoes].](/_astro/figure-5.2-context-evaluation.DQtXOKtu_Z2cKqH7.webp)