hitbox-feoxdb
Persistent cache backend for the Hitbox caching framework.
This crate provides [FeOxDbBackend], a disk-based cache backend powered by
FeOxDB, a pure Rust embedded database.
It offers data persistence across restarts and native per-key TTL support.
Overview
- Persistence: Cache data survives application restarts
- Per-key TTL: Each entry can have its own expiration time
- Pure Rust: No external dependencies or system libraries required
- In-memory mode: Optional ephemeral storage for testing
Quickstart
use FeOxDbBackend;
// Create a persistent backend
let backend = builder
.path
.build
.expect;
// Or use in-memory mode for testing
let test_backend = in_memory
.expect;
Storage Modes
FeOxDbBackend supports two storage modes:
| Mode | Method | Use case |
|---|---|---|
| Persistent | builder().path(...) |
Production, data survives restarts |
| In-memory | in_memory() |
Testing, temporary caching |
When using persistent mode with a directory path, the database file is
automatically created as cache.db within that directory.
Configuration
| Option | Default | Description |
|---|---|---|
path |
None (in-memory) | Database file path |
max_file_size |
1 GB | Maximum disk storage capacity |
max_memory |
1 GB | Maximum RAM usage |
key_format |
Bitcode |
Cache key serialization format |
value_format |
JsonFormat |
Value serialization format |
compressor |
PassthroughCompressor |
Compression strategy |
label |
"feoxdb" |
Backend label for multi-tier composition |
Resource Limits
FeOxDB allows configuring resource limits for both disk and memory usage:
-
max_file_size: Controls the maximum size of the database file on disk. The file is pre-allocated at this size. When full, writes fail withOutOfSpace. Only applies to persistent mode. -
max_memory: Controls RAM usage for in-memory data structures.- In memory-only mode: This is the total storage capacity
- In persistent mode: This limits the in-memory cache for disk data
When exceeded, writes fail with
OutOfMemory. FeOxDB does not automatically evict entries from the main store (unlike Moka's LRU eviction).
use FeOxDbBackend;
let backend = builder
.path
.max_file_size // 10 GB disk limit
.max_memory // 512 MB RAM limit
.build
.expect;
Serialization Formats
The value_format option controls how cached data is serialized. Available formats
are provided by hitbox_backend::format:
| Format | Speed | Size | Human-readable | Use case |
|---|---|---|---|---|
JsonFormat |
Slow | Large | Partial* | Debugging, interoperability |
BincodeFormat |
Fast | Compact | No | General purpose (recommended) |
RonFormat |
Medium | Medium | Yes | Config files, debugging |
RkyvFormat |
Fastest | Compact | No | Zero-copy, max performance |
* JSON serializes binary data as byte arrays [104, 101, ...], not readable strings.
Note: RkyvFormat requires enabling the rkyv_format feature on hitbox-backend.
Compression Strategies
The compressor option controls whether cached data is compressed. Available
compressors are provided by [hitbox_backend]:
| Compressor | Ratio | Speed | Feature flag |
|---|---|---|---|
PassthroughCompressor |
None | Fastest | — |
GzipCompressor |
Good | Medium | gzip |
ZstdCompressor |
Best | Fast | zstd |
For disk-based caches, compression is often recommended since it reduces I/O operations and disk usage, which can improve performance.
TTL Handling
FeOxDB natively supports per-key TTL. When writing a cache entry with an
expiration time, the TTL is computed and passed to FeOxDB's insert_with_ttl.
Expired entries are automatically cleaned up by the database.
As a safety measure, the backend also checks expiration during reads to handle edge cases where cleanup hasn't occurred yet.
When to Use This Backend
Use FeOxDbBackend when you need:
- Persistence: Cache data must survive application restarts
- Single-instance: Data doesn't need to be shared across processes
- Simplicity: No external services to manage (unlike Redis)
- Large datasets: Data that doesn't fit in memory
Consider other backends when you need:
- Distributed caching: Use
hitbox-redisinstead - Maximum speed: Use
hitbox-mokafor pure in-memory caching - Memory-bounded cache: Use
hitbox-mokawith LRU eviction
Multi-Tier Composition
FeOxDbBackend works well as an L2 cache behind a fast in-memory cache:
use Compose;
use MokaBackend;
use FeOxDbBackend;
// Fast in-memory cache (L1) backed by disk (L2)
let l1 = builder.build;
let l2 = builder
.path
.build?;
let backend = l1.compose;
Thread Safety
FeOxDbBackend is Clone, Send, and Sync. Cloned instances share the
same underlying database connection via Arc<FeoxStore>. All database
operations are performed in blocking tasks to avoid blocking the async runtime.