Bitemporal Model
TensorDB is a bitemporal database. Every fact exists in two independent time dimensions:
- System time (
commit_ts) — when the database recorded the fact - Business time (
valid_from/valid_to) — when the fact was true in the real world
Bitemporal Data Model
Every fact in TensorDB lives in two time dimensions: system time (when it was recorded)
and business time (when it was true in the real world).
System Time (commit_ts)
v1 written
ts=100
ts=100
v2 correction
ts=200
ts=200
v3 update
ts=350
ts=350
v4 latest
ts=500
ts=500
AS OF 250
ts=0 ts=250 ts=500
AS OF 250 returns v2 — the latest version visible at commit timestamp 250.
Business Time (valid_from → valid_to)
Rate 3.5%
Jan–Mar 2024
Jan–Mar 2024
Rate 4.0%
Apr–Jun 2024
Apr–Jun 2024
Rate 4.25%
Jul–Dec 2024
Jul–Dec 2024
VALID AT May 2024
Jan 2024 Jul 2024 Dec 2024
VALID AT 1715000000 (May 2024) returns Rate 4.0% — the fact valid at that business time.
Combined: AS OF + VALID AT
Combine both dimensions:
This returns the rate that was known at system time 200 and was valid in May 2024.
SELECT rate FROM policies AS OF 200 VALID AT 1715000000 This returns the rate that was known at system time 200 and was valid in May 2024.
Why Bitemporal?
Consider an insurance rate that changes quarterly. On April 1st, the rate changes from 3.5% to 4.0%. But you might not record this change until April 3rd.
- System time: April 3rd (when you wrote it)
- Business time: April 1st to June 30th (when the rate was actually valid)
Without bitemporality, you can’t distinguish between “what we knew then” and “what was actually true.”
System Time: AS OF
AS OF queries the database as it was at a specific commit timestamp:
-- What did the database look like at commit 500?SELECT * FROM accounts AS OF 500;This is time travel — you see exactly what a reader would have seen at that point in time, even if newer data has been written since.
Use Cases
- Audit trails: Prove what was known at a specific time
- Debugging: Reproduce exact application state
- Regulatory compliance: Answer “what did you know, and when?”
Business Time: VALID AT
VALID AT queries which facts were valid at a specific business timestamp:
-- What rate was in effect on June 15, 2024?SELECT rate FROM policies VALID AT 1718409600;Writing with Business Time
use tensordb::Value;
// Record a rate valid from Jan 1 to Jun 30, 2024db.put_temporal( "policy/POL-001/rate", Value::Real(3.5), 1704067200, // valid_from: Jan 1, 2024 1719705600, // valid_to: Jun 30, 2024)?;
// Record a new rate valid from Jul 1 to Dec 31, 2024db.put_temporal( "policy/POL-001/rate", Value::Real(4.25), 1719705600, // valid_from: Jul 1, 2024 1735689600, // valid_to: Dec 31, 2024)?;Combined Queries
The real power is combining both dimensions:
-- What rate was known at commit 200, that was valid on June 15?SELECT rate FROM policies AS OF 200 VALID AT 1718409600;This answers: “Based on what the system knew at time 200, what rate was valid in June?”
Key Properties
| Property | Description |
|---|---|
| All versions preserved | Compaction never drops temporal versions |
| System time is monotonic | commit_ts always increases within a shard |
| Business time is arbitrary | valid_from / valid_to can be any timestamp |
| Default business time | If not specified, valid_from = now, valid_to = infinity |