Performance & Benchmarks
Relevant source files
The following files were used as context for generating this wiki page:
The chkpt project prioritizes high-performance workspace snapshots through content-addressable deduplication, efficient hashing, and incremental updates. The benchmarking suite is designed to measure the efficiency of the save/restore pipeline, metadata management in SQLite, and the throughput of various hashing and compression algorithms.
Performance is tracked across three primary dimensions: synthetic workloads for stress testing, real-world repository benchmarks for practical application, and isolated component benchmarks for architectural optimization. Key metrics include "Cold Save" (initial checkpoint), "Incremental Save" (updates to existing stores), and "Restore" speeds.
Sources: README.md:16-25, scripts/benchmarks.py:112-255
Benchmark Architecture and Tooling
The project utilizes a multi-tiered benchmarking infrastructure. A Python-based runner (scripts/benchmarks.py) orchestrates complex scenarios, while Rust examples and Criterion-style benches provide granular data on core operations.
Benchmark Scenarios
The system defines multiple scenarios to simulate different workspace characteristics, ranging from small text file collections to large, hardlink-heavy node_modules structures.
| Scenario Category | Description | Key Metric Focus |
|---|---|---|
bench_catalog | SQLite metadata performance with varying manifest sizes and seeded snapshots. | Query latency, bulk upsert speed. |
bench_ops | End-to-end save and restore operations on synthetic directory trees. | E2E wall-clock time, peak RSS. |
save_pipeline | Micro-benchmarks for individual phases: scan, index check, read/hash, and pack write. | Phase-specific bottleneck identification. |
hash_compress | Comparative analysis of algorithms (e.g., BLAKE3 vs XXH3-128). | Throughput (MB/s), compression ratio. |
Sources: scripts/benchmarks.py:92-155, crates/chkpt-core/benches/hash_compress_compare.rs:56-100
Real-World Performance
Real-world repository benchmarks use a shell script to clone popular open-source projects (React, Rust, Linux) and measure chkpt performance on actual source code distributions.
The diagram above illustrates the flow of the real-world benchmarking script which measures wall-clock time for each operation.
Sources: scripts/bench_real_repos.sh:91-170
The Save Pipeline Optimization
The "save pipeline" is the most performance-critical path in the application. Benchmarks in crates/chkpt-core/benches/save_pipeline.rs analyze various optimization strategies to minimize I/O and CPU overhead.
Pipeline Phases
The save operation is broken down into discrete phases for measurement:
- Scan: Walking the workspace filesystem.
- Index Check: Loading the SQLite/binary index and comparing mtimes/inodes to detect changes.
- Read + Hash: Reading file contents and generating XXH3-128 fingerprints.
- Compress + Pack: LZ4 compression of new blobs and writing to pack files.
- Build Tree: Constructing the Merkle tree representing the directory structure.
- Index Flush: Persisting the updated file index to disk.
Sources: crates/chkpt-core/benches/save_pipeline.rs:114-315
I/O and Hashing Variants
Benchmarks compare several strategies for the "Read + Hash" phase, which is typically the primary bottleneck:
| Variant | Strategy | Performance Impact |
|---|---|---|
| Baseline | Standard std::fs read in path order. | Reference point. |
| Inode-sorted | Reading files in order of their disk inode to minimize head seek. | Significant reduction in mechanical/SSD seek latency. |
| mmap hybrid | Using Memory Mapping for files ≥64KB and standard I/O for smaller files. | Optimized memory usage and throughput for larger blobs. |
| openat cache | Using openat with a cached directory file descriptor. | Reduced syscall overhead for deeply nested structures. |
Sources: crates/chkpt-core/benches/save_pipeline.rs:165-225
Algorithm Comparison: Hashing and Compression
chkpt uses a specific combination of XXH3-128 for hashing and LZ4 for compression. This decision is backed by comparative benchmarks that measure the trade-offs between speed and storage efficiency.
The sequence shows the comparative benchmarking flow used to justify the selection of XXH3 and LZ4.
Sources: crates/chkpt-core/benches/hash_compress_compare.rs:135-215
Performance Metrics Summary
On a modern workstation (M2 Pro), the system achieves the following throughputs for standard source code:
- XXH3-128 Hashing: Faster than BLAKE3 across all file size buckets (small, medium, large).
- LZ4 Compression: Provides a high-speed "Full Pipeline" (Read → Hash → Compress) that is significantly faster than Zstd-based alternatives while maintaining acceptable compression ratios (e.g., 2.9x for the Linux kernel).
Sources: README.md:19-25, crates/chkpt-core/benches/hash_compress_compare.rs:218-240
Metadata Catalog Performance
The bench_catalog.rs example measures the SQLite-backed metadata store. It simulates high-load scenarios involving tens of thousands of manifest entries and hundreds of snapshots.
Catalog Operations Measured:
- Bulk Upsert: Inserting large batches of blob locations (pack/offset mapping).
- Snapshot Insertion: Persisting a new snapshot manifest with thousands of file entries.
- Prefix Resolution: Resolving short snapshot IDs (e.g.,
chkpt restore abc). - Manifest Loading: Retrieving the full file list for a specific snapshot.
Sources: crates/chkpt-core/examples/bench_catalog.rs:115-145
Data Structure for Catalog Benchmarking
struct Metrics {
open_ms: f64,
bulk_upsert_ms: f64,
insert_snapshot_ms: f64,
latest_snapshot_ms: f64,
resolve_prefix_ms: f64,
list_snapshots_ms: f64,
snapshot_manifest_ms: f64,
blob_lookup_ms: f64,
}
Sources: crates/chkpt-core/examples/bench_catalog.rs:31-41
Conclusion
The benchmark suite demonstrates that chkpt is optimized for speed, particularly in incremental scenarios. By using inode-sorting and multi-threaded XXH3/LZ4 pipelines, chkpt can process workspaces with nearly 100,000 files in under 3 seconds for cold saves and under 0.5 seconds for incremental updates on modern hardware.
Sources: README.md:20-25, crates/chkpt-core/benches/save_pipeline.rs:320-350