An animated tour of a free, offline fill-up log

Fuel mileage calculator, explained — how fuelbook turns fill-ups into honest tank-to-tank km/L

Everyone argues about real vs claimed mileage. fuelbook settles it with the one method that actually works for manual logging — full-to-full — and refuses to invent a number when the method can't produce one. This page shows you exactly how, with a worked example you can check by hand.

The problem: nobody agrees on "real mileage"

Three numbers get shouted in every mileage argument — and all three are wrong in a different way.

The brochure figure

Measured in lab conditions. Your commute has traffic, pillion riders, and a luggage rack. Real logs routinely land well below it — but by how much, for your vehicle? Nobody's brochure knows.

The one-tank guess

"I got 55 this tank!" Every pump's auto-cutoff stops at a slightly different level, so what counts as full wobbles a few percent. Any single tank's figure is part measurement, part luck.

The spreadsheet drift

DIY sheets quietly divide by the wrong litres — counting the first fill's fuel, dropping partial top-ups, or mixing time windows. The formula looks right and the answer is confidently wrong.

The fix: the full-to-full method, animated

A full tank is the only repeatable reference point you have without instruments. So mileage is only measured between two FULL fills: kilometres travelled ÷ litres it took to refill. Watch the worked example build itself:

F 12,000 5 Jan · 9.00 L F 12,410 18 Jan · 9.84 L P 12,600 2 Feb · 4.50 L F 12,810 14 Feb · 5.50 L P 12,980 25 Feb 410 km ÷ 9.84 L = 41.67 km/L 400 km ÷ (4.50 + 5.50) L = 40.00 km/L excluded untilthe next FULL
Worked example — invented demo prices, checkable by hand. F = full fill, P = partial top-up.

A segment runs between consecutive FULL fills. The litres of every fill after the previous FULL through this FULL go in the denominator — so the first FULL's 9.00 L is a starting line, never counted.

Partial top-ups fold into the segment they belong to — and the segment is honestly labelled includes partial. Segment two above: 400 km ÷ (4.50 + 5.50) L.

Entries after the last FULL are excluded, with the reason on screen. The 25 Feb partial can't be measured yet — it joins the math at your next full fill. Lifetime stays 40.83 km/L (810 km ÷ 19.84 L) either way.

No reference points, no number. One full fill, or a log of only partials? fuelbook shows your spend totals and says "need two full fills to compute" — it never invents a mileage.

One point per tank — and a trend you can act on

Single tanks wobble with pump cutoffs, so fuelbook plots every tank against a trailing-3-tank average and tells you to trust the lifetime line over any one point.

44 40 36 trailing-3 avg 41.57 37.2 — more than 10% below your average
Worked example. The dip triggers a neutral prompt: "below your average — check tyre pressure, service due, or fuel quality." A prompt to look, never a mechanical diagnosis.

True cost per km — fuel alone understates it

fuelbook computes both figures over the same first-FULL-to-last-FULL window, so they cover exactly the same 810 km. Expenses dated outside the window are flagged waiting for next full fill, never silently mixed in.

Fuel only
2.58/km

₹2,093.20 fuel ÷ 810 km

All-in
4.07/km

(₹2,093.20 fuel + ₹1,200 service) ÷ the same 810 km · a ₹4,000 insurance premium dated after the last FULL waits, flagged, for the next full fill

Worked example. That gap — ₹1.49 per km here — is what bike-vs-cab-vs-metro decisions actually turn on.

Privacy you don't have to trust — the browser enforces it

Most apps promise not to send your data anywhere. fuelbook makes the promise unnecessary: its Content-Security-Policy sets connect-src 'none', so your browser itself blocks every network send. There is no server, no account, no analytics — and nothing to opt out of.

your log connect-src 'none' the internet
Blocked at the browser, by policy — not filtered by a server you have to believe in.

The actual policy line the app ships:

Content-Security-Policy: default-src 'self'; connect-src 'none'; …
  • No network path exists. connect-src 'none' means fetch, XHR and WebSockets are refused by the browser before they leave the page.
  • No third-party anything. No CDN scripts, no external fonts, no analytics beacons — the policy forbids them all.
  • Your log lives in localStorage, in your browser, full stop. Clearing site data erases it; the built-in CSV export is your backup.

What's in the app

Fill-up log

Date, odometer, litres, amount — price/litre auto-derived (₹105.00/L in the example). FULL/PARTIAL toggle, edit, delete, validation that rejects backwards odometers.

Dashboard

Lifetime km/L, best and worst tank, fuel and all-in cost/km, this-month spend, total km — every card states its window.

Trend chart

One point per tank, trailing-3 average, and a neutral prompt when a tank dips more than 10% below it.

Expense log

Service, insurance, tyres, other — feeding the all-in figure over the same honest window.

Units & currency

km+L (km/L and L/100km — 41.67 km/L is 2.40 L/100km) or mi+gal (mpg). Free-text currency symbol, ₹ default.

Sample log

One tap loads clearly-invented demo entries under a persistent SAMPLE banner, so the payoff is visible before your own second full fill.

CSV export & print

RFC-4180 CSV of fills and expenses — your backup and handoff — plus a printable one-page summary.

Method card

The full-to-full rule and its limits, stated in plain words inside the app itself.

What fuelbook honestly won't do

Start your log at the next full fill

Free, offline, no account. Two full fills from now, you'll have a number nobody can argue with.

Open fuelbook

Source code (MIT) · runs entirely in your browser