The simplest binary time series store. No DB. No Server. Just mmap. Built for append-only local data.
Project description
⏱️ Chronostore
Chronostore is a fast, binary time series storage engine for local workloads. No server. No database. Just append-only daily files backed by memory-mapping or LMDB, with zero-copy NumPy reads and schema control.
📦 Installation
pip install chronostore
⚙️ Features
- 🔌 Pandas-compatible: Read and write directly from DataFrames or lists of dicts
- ⚡ Fast reads: Zero-copy access via NumPy with optional memory-mapping or LMDB backend
- 🧠 Schema-defined layout: Define your own typed schema for precise control over storage format
- 📅 Daily partitioning: Each day's data is saved to a single compact binary file for fast lookups
- 🔄 Append-only design: Ideal for logs, metrics, sensor data, or financial data
- 🧱 Pluggable backends: Choose between FlatFile (mmap) and LMDB
- 🚫 No server or database required: Pure Python. Runs anywhere (no setup, no infra)
⚠️ Limitations
- Not designed for concurrent writes
- No built-in indexing or compression
- Best suited for SSD/NVMe; HDD can be slow for large date ranges
📂 Data Layout (flatfile backend)
data/
└── TableName/
├── 2025-06-13/
│ └── data.bin
└── 2025-06-14/
└── data.bin
Each data.bin is an append-only binary file containing rows packed according to the user schema (e.g., int64, float64, etc).
The list of format characters is available here.
🧪 Example Usage
from chronostore import TimeSeriesEngine, TableSchema, ColumnSchema
from chronostore.backend import FlatFileBackend, LmdbBackend
schema = TableSchema(columns=[
ColumnSchema("timestamp", "q"), # int64
ColumnSchema("value", "d"), # float64
])
# Choose your backend
backend = FlatFileBackend(schema, "./data_folder") # Memory-mapped files
# backend = LmdbBackend(schema, "./data_folder") # Alternatively: LMDB-backed
# Create engine
engine = TimeSeriesEngine(backend=backend)
# Append data
engine.append("Sensor1", "2025-06-14", {"timestamp": 1234567890, "value": 42.0})
engine.append("Sensor1", "2025-06-14", {"timestamp": 1234567891, "value": 43.0})
engine.flush()
# Read the last 5 rows from that day
recent = engine.read("Sensor1", "2025-06-14", start=-5)
print(recent)
📓 Explore in Notebooks:
Practical examples that mirror real workloads:
🚀 Benchmarks
Benchmarked on 10M rows of 4-column float64 data
| Format | Append all | Read all | Filter (> threshold) | Disk usage |
|---|---|---|---|---|
| CSV | 58.6s | 7.84s | ❌ | 595MB |
| Parquet | 2.03s | 0.44s | 0.30s | 277MB |
| DuckDB | 3.33s | 0.81s | 0.42s | 203MB |
| Chronostore (flatfile backend) | 0.43s | 0.24s | 0.40s | 305MB |
| Chronostore (lmdb backend) | 0.58s | 0.52s | 0.57s | 305MB |
📈 Use Cases
- Time series storage for sensor or IoT data
- Event logs or telemetry storage
- Custom domain-specific timeseries archiving
🧠 Why Not Use a DB?
Chronostore is ideal when:
- You need max speed with minimal overhead
- You know your schema in advance
- You want total control over layout and access patterns
- You want to learn low-level I/O, memory mapping, and binary formats
| Feature | Chronostore | CSV | Parquet | DuckDB |
|---|---|---|---|---|
| Server required | ❌ | ❌ | ❌ | ❌ |
| Schema enforced | ✅ | ❌ | ✅ | ✅ |
| Compression | ❌ | ❌ | ✅ | ✅ |
| Append-only | ✅ | ✅ | ❌ | ❌ |
| Memory mapped | ✅ | ❌ | ❌ | ⚠️ internal only |
📜 License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chronostore-0.1.0.tar.gz.
File metadata
- Download URL: chronostore-0.1.0.tar.gz
- Upload date:
- Size: 5.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57d0e4012551cedc7cb1fc3a321224a21447f065f73c1a4b33dc2e3d679af094
|
|
| MD5 |
4e21d0ca9bd5571e59e6f632e3aaef78
|
|
| BLAKE2b-256 |
2b4523062f519b3b3e9976e68cb6e53b113f8232fa8feef373a6ff4f7f7667fa
|
File details
Details for the file chronostore-0.1.0-py3-none-any.whl.
File metadata
- Download URL: chronostore-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f33d7b2fa67a6be7423dd248f9a67e7bed46f802f51d4f07becb5c12d4c123d1
|
|
| MD5 |
6c5026d9000d02b584d1f7aa8a14b2ba
|
|
| BLAKE2b-256 |
81b567f845b66b9058591f959126cb812b1184aef70f056dd353e96e48d4fc94
|