What does bitemporal mean?
Bitemporal data records two times for every fact: when it was true in the world, and when your system learned it. Why the second one is what lets you prove what you knew.
A bitemporal record carries two independent timelines for every fact:
- Valid time — when the fact was true in the world. This customer's renewal date was 14 March.
- Transaction time — when your system came to believe it. We learned that on 2 April, and corrected it on 19 June.
Most systems keep neither, and store only the current value. Some keep valid time, usually as valid_from and valid_to columns. Keeping both is what "bitemporal" means, and it is the difference between a record you can query and a record you can defend.
Why the second timeline is the one that matters
Valid time answers what was true in March? That is useful and fairly commonly implemented.
Transaction time answers a different question: what did we think in March? Those are not the same, and the gap between them is where every interesting dispute lives.
Say an assistant told somebody in March that a contract renewed in September, and the real date was July. With no history, you can only see today's value and the answer looks like a straightforward mistake. With valid time alone, you can see the date was always July, which makes it look worse. With transaction time, you can see that the CRM said September until somebody corrected it in May — so the assistant answered correctly from the evidence it had, and the fault was in the source record.
One of those is a product failure. One is a data-entry failure. They are indistinguishable afterwards unless something wrote down when each belief arrived.
Why AI makes this urgent
This used to be a specialist concern of finance and insurance systems, where regulators ask what you knew and when. AI has made it general, for a simple reason: assistants now produce answers that people act on, at a volume no one reviews.
When somebody asks in October why a decision was made in July, the only honest answer comes from a store that can reconstruct July's beliefs. A memory layer that overwrites can tell you what is true now and nothing else — which means it cannot distinguish "the model was wrong" from "the facts changed", and the burden of that ambiguity always lands on the product. We have written about what it takes to prove what an AI knew.
How it is usually implemented
Append, never update. A correction writes a new row that supersedes the old one, rather than overwriting. Nothing is destroyed, so nothing has to be reconstructed from backups or an audit table that was bolted on later.
Two time ranges per fact, one for each timeline, with open-ended values for "still true" and "still believed".
As-of queries. Every read takes an optional pair of timestamps. Give it none and you get today's belief about today. Give it a transaction time and you get what the system believed then.
The cost is real and worth stating: storage grows monotonically, every query carries two more predicates, indexes get wider, and the surface area for bugs is larger because there are more ways for two ranges to disagree. It is much easier to design in than to retrofit, because retrofitting means inventing transaction times for history that never recorded them.
Related ideas it is often confused with
- Slowly changing dimensions (type 2) are the data-warehouse version, usually valid-time only.
- Event sourcing keeps the events rather than the state, from which both timelines can be derived — a different route to the same ability.
- Audit logs record that something changed. A bitemporal store lets you query the past, which an audit log of diffs does not.
- Soft deletes are the thinnest possible version: one flag, no timeline.
Memtro's memory is bitemporal by design: facts carry sources and validity dates, corrections supersede rather than overwrite, and the whole graph can be read as it stood on any date — so you can follow how a fact changed and ask what the company believed in July.