How we test the engine
No app can prove its calorie number on a real person, because on a real person nobody knows the true answer. So we built people whose answer we do know, and here is everything that happened.
Why this page exists
Accuracy claims in this category are cheap. An app can say its number is personalised, or adaptive, or that it learns from you, and nothing about those words can be checked by the person reading them. We would rather hand you the test.
The honest problem is that a real person's true energy expenditure is unknown. Measuring it properly needs a metabolic chamber or doubly labelled water, neither of which is going in your kitchen. So an app claiming accuracy against real users is either quoting a study of somebody else's engine or asserting something it cannot possibly have measured.
What we do instead
We simulate people whose expenditure we set ourselves. The simulated person has a true burn rate we chose, a scale that lies to them by a realistic amount, a logging habit that is imperfect in the way real logging is imperfect, and a body that responds to an energy deficit the way bodies do. Then we feed their diary to the same engine that ships in the app and compare what it concluded against the answer we planted.
Because the truth was built in, the error is exactly knowable. That is the whole trick, and it is also the whole limitation: these are not real people, and a simulation is only as good as its assumptions about scale noise, water weight and adherence.
How to read the table
Error is the engine's estimate minus the true expenditure, in kilocalories per day. Negative means the engine read low. Every row is the mean of three independent runs over 168 simulated days.
- Converged is the day after which the error never again leaves plus or minus 100 kcal. Lower is better, and never means it did not settle inside that band at any point in the run.
- Steady error is the average size of the error over the final fortnight, ignoring its direction.
- Steady bias is the same fortnight with the sign kept, so it shows whether the engine read consistently high or consistently low rather than merely scattered.
- Formula error is what a standard textbook equation would have been wrong by on the same person. It is the thing worth beating, and the column that decides whether any of this was worth building.
The results
| Scenario | Converged | Steady error | Steady bias | Formula error |
|---|---|---|---|---|
| Maintenance, weighing daily | day 18 | 17 | −4 | 228 |
| Deficit, weighing 3x a week | day 33 | 28 | +26 | 12 |
| Deficit, weighing weekly | day 33 | 34 | −4 | 22 |
| Metabolism drifting 150 kcal down over 8 weeks | day 132 | 38 | +35 | 212 |
| Two-week holiday, nothing logged | day 65 | 35 | +1 | 109 |
| Cyclical scale noise, plus or minus 0.9 kg | day 28 | 27 | +13 | −200 |
| Drift plus a monthly cycle, cycle logged | day 131 | 47 | +47 | −25 |
| Drift plus a monthly cycle, cycle not logged | day 80 | 35 | +4 | −25 |
| Monthly cycle, no cycle data logged | day 157 | 50 | −50 | −200 |
| Irregular cycle, logged | day 57 | 13 | −8 | −198 |
| Measured body fat on file | day 34 | 25 | −23 | −82 |
| Body fat estimate 5.5 points high | day 34 | 17 | +8 | −218 |
| Body fat estimate 5.5 points low | day 50 | 65 | −65 | 47 |
| Body fat estimate 8 points high, lean user | never | 186 | +186 | −50 |
| Creatine loading, doses logged | day 33 | 31 | +29 | 35 |
| Creatine loading, doses not logged | day 113 | 22 | −18 | 35 |
The row we do worst on
A lean user whose body fat estimate is eight percentage points too high is the engine's worst case by a distance. It never converges inside the hundred kcal band across 168 days, and it settles around 186 kcal a day too high.
The cause is not the body fat figure being wrong in itself. We tested that directly by giving the same scenario a perfect body fat reading, and the error barely moved. What breaks it is a floor in how the engine converts weight change into energy for a very lean person: below a certain point the arithmetic stops being able to separate fat loss from everything else that moves a scale. Tuning that floor to fix this row made several other rows worse, so it stands as a documented limit rather than a bug we have not got round to.
If you are very lean and your body fat figure is a guess rather than a measurement, this is the case where the app is least likely to be right. A proper reading on file is worth more to you than it is to most users.
What the table says about the formula
Compare the last column with the third. On a user weighing daily at maintenance, a textbook equation is out by 228 kcal a day where the engine settles at 17. On a drifting metabolism, 212 against 38. Those are the cases this exists for.
It is not a clean sweep and we are not going to pretend otherwise. On the deficit rows the formula happens to land close, so the engine's advantage there is small or absent. A formula is not always wrong. It is just never able to tell you whether it is right this time, and that is what the margin beside your number is there to say.
How long it takes on a real account
Two different things sharpen at two different rates, and we measured both.
The share of your target that comes from your own measurements rather than the population formula moves in your first week: around 35 per cent for someone weighing daily, 44 per cent at three times a week, and nothing at all in week one for a weekly weigher, because a single reading cannot close a week's worth of evidence. It climbs to the high eighties over three months. It also goes down on weeks whose readings carried little signal, which is why the app shows it as a reading rather than as a progress bar.
The self check, which compares what the app predicted against what the scale actually did, says nothing at all until week six. Its first reading is loose, between 253 and 446 kcal a day depending on how often you weigh. It reaches the tens by about week twelve if you weigh daily, and later if you do not.
We would rather tell you that than imply it is sharp on day one.
Reproducing it
The benchmark is a test in the app's own source tree, not a spreadsheet written for this page. These numbers are read off the same run that guards the engine against regressions, so a change that made the engine worse would fail the build before it ever reached this table.