Expand description
§pgkv - PostgreSQL Key-Value Store
A high-performance, production-grade key-value store backed by PostgreSQL unlogged tables.
§Features
- High Performance: Uses PostgreSQL UNLOGGED tables for maximum write throughput
- Runtime Agnostic: Synchronous API works with any async runtime or none at all
- Minimal Dependencies: Only depends on
postgresandthiserror - Rich API: Comprehensive operations including batch, atomic, TTL, and prefix scanning
- Type Safe: Strong typing with optional serde support for automatic serialization
- Production Ready: Comprehensive error handling, connection pooling support, and transaction safety
- Configurable TTL Cleanup: Choose between automatic, manual, or disabled key expiration cleanup
§Quick Start
use pgkv::{Store, Config};
// Create a store with default configuration
let store = Store::connect("postgresql://umesh@localhost/postgres")?;
// Basic operations
store.set("key", b"value")?;
let value = store.get("key")?;
store.delete("key")?;
// Batch operations
store.set_many(&[("k1", b"v1".as_slice()), ("k2", b"v2")])?;
let values = store.get_many(&["k1", "k2"])?;
// TTL support
use std::time::Duration;
store.set_ex("temp", b"expires", Duration::from_secs(60))?;
// Atomic operations
store.compare_and_swap("counter", Some(b"old"), b"new")?;
store.increment("counter", 1)?;§Why Unlogged Tables?
PostgreSQL UNLOGGED tables provide significantly higher write performance by skipping write-ahead logging (WAL). This makes them ideal for:
- Caching: Data that can be regenerated if lost
- Session storage: Ephemeral user session data
- Rate limiting: Counters and temporary state
- Job queues: Transient task data
Trade-off: Data in UNLOGGED tables is not crash-safe and will be truncated after an unclean shutdown. Use regular tables if you need durability.
§Architecture
The library creates a simple schema:
CREATE UNLOGGED TABLE IF NOT EXISTS {table_name} (
key TEXT PRIMARY KEY,
value BYTEA NOT NULL,
expires_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);§Configuration
use pgkv::{Store, Config, TableType, TtlCleanupStrategy};
let config = Config::new("postgresql://umesh@localhost/postgres")
.table_name("my_cache")
.table_type(TableType::Unlogged)
.auto_create_table(true)
.ttl_cleanup_strategy(TtlCleanupStrategy::OnRead);
let store = Store::with_config(config)?;§TTL Cleanup Strategies
The library provides three strategies for handling expired keys:
use pgkv::{Config, TtlCleanupStrategy};
// Option 1: Automatic cleanup on read (default)
// Expired keys are deleted when accessed
let config = Config::new("postgresql://umesh@localhost/postgres")
.ttl_cleanup_strategy(TtlCleanupStrategy::OnRead);
// Option 2: Manual cleanup - YOU control when cleanup happens
// Call store.cleanup_expired() on your own schedule (cron, background task, etc.)
let config = Config::new("postgresql://umesh@localhost/postgres")
.ttl_cleanup_strategy(TtlCleanupStrategy::Manual);
// Option 3: Disabled - no expiration checking at all
// Use when you don't use TTL features and want maximum performance
let config = Config::new("postgresql://umesh@localhost/postgres")
.ttl_cleanup_strategy(TtlCleanupStrategy::Disabled);Modules§
- prelude
- Prelude module for convenient imports.
Structs§
- Config
- Configuration options for the key-value store.
- Entry
- A full entry with metadata.
- KeyValue
- A key-value pair.
- Scan
Options - Options for scanning keys.
- Stats
- Statistics about the store.
- Store
- The main key-value store backed by PostgreSQL.
- Typed
Store serde - A typed wrapper around
Storethat automatically serializes/deserializes values.
Enums§
- CasResult
- Result of a compare-and-swap operation.
- Error
- Error types that can occur during pgkv operations.
- Table
Type - The type of table to use for storage.
- TtlCleanup
Strategy - Strategy for handling expired keys.
Traits§
- Typed
Store Ext serde - Extension trait for convenient typed access.
Type Aliases§
- Result
- Result type alias for pgkv operations.