What changed, and when
A reference that never records a revision is a reference nobody is maintaining. This is the log: dataset versions, model changes, corrections and the work behind them.
By Merey Tleugazin Revised 2026-09-18
A reference that never records a revision is a reference nobody is maintaining. This is the log. It carries four kinds of entry — a dataset revision, a change to the model, a correction, and a change to the site itself — and the corrections are in it rather than folded quietly into the others, because a changelog is only worth keeping if the embarrassing lines are in it.
What gets an entry, and what does not
A correction is logged whenever something published here was factually wrong: a caffeine value, a serving size, a mis-stated guideline, a formula that produced the wrong number, a documented interface that disagreed with itself. The entry says what was wrong, how long it was wrong for where we know, and what changed so that the same class of error is caught next time rather than merely fixed. We do not retroactively edit a correction into a general improvement.
A dataset revision is a new version of the published caffeine data, stamped with a date. The footer of every page on this site prints the version you are reading, so a figure you quoted last month can be traced back to the exact file it came from. A manufacturer reformulating a drink is a dataset revision, not a correction — the old figure was right for the old formulation.
A model change would move every time-based figure on this site at once, because there is one copy of the arithmetic and everything imports it. It would be announced as such. None has happened: the half-life has been 5.7 hours and the sleep threshold 100 mg since this site was built.
Site changes — a new section, a rebuilt page, a new way to read the data — are logged when they change what is available to a reader, and not when they change how a stylesheet is organised.
What "updated" means on a page
Guides carry a published date and, where they have been revised, an updated date. Neither is decorative and neither is refreshed to make a page look recent. Re-dating unchanged content to simulate freshness is a documented way to be demoted by search engines, and more to the point it is a lie told to the reader about how old the thing they are reading is. A guide's updated date moves when its text or its figures move.
Pages that render live from the dataset — the drink pages, the tables, the calculators — inherit the dataset version rather than a per-page date, because that is the honest answer to "how current is this number".
How to be told when something changes
There is no email list and no feed, and we would rather say so than build one nobody maintains. What exists instead is machine-readable and stable. The published dataset carries its version in the file itself, so a script that reuses it can compare the version string it stored last time. The open API exposes a status endpoint that reports the current dataset version and the counts behind it, which is the cheapest way to notice that a figure you depend on has moved. And this page is the human version of the same thing, in reverse date order, with no pagination to click through.
If you are quoting a figure from this site somewhere it will outlive your reading of it — in a paper, in an app, in a table of your own — quote the dataset version alongside it. That is what the version string is for, and it is the difference between a citation that can be checked in five years and one that cannot.
The log
-
Site
Covers on the guides, and this masthead
The guides now open with a wide photograph instead of a breadcrumb, and the home page FAQ was rearranged from a narrow centred column into a spread. Six pages were added — methodology, sources, editorial standards, this log, the glossary and the accessibility statement — because a site that publishes health-adjacent numbers should be answerable for them in prose, not only in a byline. The photographs are generated on our own machine with an open-weights model; nothing about a reader reaches an image service.
-
Correction
The public dataset carried an internal note as its description
The downloadable dataset at /data/ was a file copied by hand out of the app, and the copy included the app team's own engineering note — a reference to an internal document and the sentence that the values still needed a final source-verification pass. That text was published as the dataset's public description and was linked from the structured data on every page. It is generated from the same loader the pages read now, so there is no second copy to drift. The milligram values themselves were not affected.
-
Correction
A worked example in the API documentation disagreed with the API
The field table on /api/ showed an example row that had been typed by hand, and it no longer matched the endpoint it documented. It is read from the dataset now. This is the same defect as a hand-kept price: correct on the day it was written, wrong afterwards, and wrong in the one place where being wrong is most expensive.
-
Model
One copy of the arithmetic, and 57 tests over it
Four separate implementations of the decay formula existed on this site, each individually correct, and one of them had the 5.7-hour half-life written into it as a number. A change to the model would have moved every figure on the site except that one table, and nothing compared them. The pharmacokinetics now live in a single module that the browser calculators, the pages, the public API and the machine interface all import, and 57 test vectors are pinned to numbers the site's own prose prints — so the test fails when the engine and the page stop agreeing, not merely when the engine changes.
-
Correction
A refusal that had silently stopped refusing
The machine interface is meant to decline medical questions rather than answer them. Its filter was written as a single pattern with word boundaries at both ends, which meant it never matched the word "pregnant" — the boundary demanded the word end immediately after "pregnan". The refusal did not error; it simply stopped firing, and a pregnancy question was answered with a confident milligram figure, which is the exact failure the refusal exists to prevent, arriving in the shape of a correct answer. The pattern is split and the test suite now asks questions that contain both a subject and a reason to refuse.
-
Site
The data published as an API, and readable by machines
Six datasets went up at /api/v1/ under CC BY 4.0, keyless and open to cross-origin requests, alongside a plain-language page describing every field. Each page also serves a markdown twin for agents that would otherwise parse the HTML. The keyword research this site is planned with is deliberately not published — it is worth money, it helps no reader, and a build gate fails if any of its field names appears in a public file.
-
Site
Advertising
Display advertising was enabled to fund the reference. What that changed and what it did not is set out in the editorial standards: ad placement has no input into the dataset, the ranking of drinks or the wording of a guide, and no advertiser has ever been shown a page before publication.
-
Correction
Every translated page linked to itself twice
Two components localised a path that their callers had already localised, so links on the non-English pages pointed at addresses such as /de/de/guides/. It affected 1,563 of the 1,914 pages built at the time and Google had already recorded 131 of the resulting addresses as not found. The path helper ignores a locale prefix that is already there now, the server redirects the doubled shape, and the pre-deploy check counts doubled hrefs in the built output.
-
Site
Rebuilt, and a floor under every page
The site was rebuilt around the decay curve rather than around a drinks table, and translated into twelve languages. A build gate was added that counts the prose on every indexable page and fails under 1,500 words, with tables and charts excluded from the count on purpose — so a thin page cannot be fixed by adding a diagram. The same gate asserts how many pages were built, because a page that fails to render is logged and then skipped, and a partial build otherwise looks exactly like a complete one.
-
Dataset
Dataset 2026-05-28 — 87 drinks
The first published version of the dataset: 87 drinks across eight categories, each with a serving volume, a caffeine figure in milligrams and, where the division is meaningful, a concentration per 100 ml. Forty-six of the rows have no per-100 ml figure and that field is empty rather than computed, because a shot, a pill and a scoop are units rather than volumes.
CoffeeLog · iOS
Track this automatically with CoffeeLog
This site answers the question once. CoffeeLog answers it every day — logging what you drink, showing caffeine fade in real time, and telling you the last cup you can have before it reaches your sleep.