# Smart Tiered Cache

A Redis-compatible caching system with intelligent multi-tier storage that automatically moves data between RAM, SSD (RocksDB), and SQLite based on access patterns.

## Features

- **Redis Protocol Compatible** - Use with any Redis client (`redis-cli`, `ioredis`, `node-redis`, etc.)
- **Three-Tier Storage** - RAM → SSD (RocksDB) → SQLite with automatic data movement
- **Intelligent Tiering** - Hot data stays in RAM, warm data in SSD, cold data in SQLite
- **Configurable Thresholds** - Customize hot/warm/cold access frequency thresholds
- **Multiple Eviction Policies** - LRU, LFU, or hybrid eviction strategies
- **TTL Support** - Key expiration with lazy and background cleanup
- **Data Structures** - Lists, Hashes, and Sets support
- **Persistence** - Automatic snapshots and recovery on restart
- **Monitoring Dashboard** - HTTP API + WebSocket for real-time metrics
- **Zero External Dependencies** - All storage is embedded (no Redis/database server needed)

## Installation

```bash
npm install smart-tiered-cache
```

## Quick Start

### As a Standalone Server

```bash
# Start the cache server
npx smart-tiered-cache

# Or with custom config
CACHE_REDIS_PORT=6380 CACHE_RAM_TIER_MAX_BYTES=2147483648 npx smart-tiered-cache
```

Then connect with any Redis client:

```bash
redis-cli -p 6379
> SET mykey "hello"
OK
> GET mykey
"hello"
```

### As a Library

```typescript
import { start, shutdown } from 'smart-tiered-cache';

// Start the cache
const app = await start({
  configOverrides: {
    redisPort: 6379,
    dashboardPort: 8080,
    ramTierMaxBytes: 1024 * 1024 * 1024, // 1GB RAM
    ssdTierMaxBytes: 10 * 1024 * 1024 * 1024, // 10GB SSD
    hotThreshold: 10,    // 10+ accesses/min → RAM
    warmThreshold: 1,    // 1-10 accesses/min → SSD
    coldThreshold: 0.1,  // <0.1 accesses/min → SQLite
  }
});

// Use the cache engine directly
await app.cacheEngine.set('key', Buffer.from('value'));
const result = await app.cacheEngine.get('key');
console.log(result?.data.toString()); // "value"
console.log(result?.tier); // "ram"

// Graceful shutdown
await shutdown(app);
```

### Programmatic Usage (Without Server)

```typescript
import { CacheEngine, RAMTier, SSDTier, DBTier, AccessTracker, TierManager, EvictionPolicy } from 'smart-tiered-cache';

// Initialize storage tiers
const ramTier = new RAMTier();
await ramTier.open({ capacityBytes: 1024 * 1024 * 1024 }); // 1GB

const ssdTier = new SSDTier();
await ssdTier.open({ capacityBytes: 10 * 1024 * 1024 * 1024, storagePath: './data/ssd' });

const dbTier = new DBTier();
await dbTier.open({ capacityBytes: Number.MAX_SAFE_INTEGER, storagePath: './data/cache.db' });

// Initialize components
const accessTracker = new AccessTracker();
const evictionPolicy = new EvictionPolicy('lru');
const tierManager = new TierManager({
  hotAccessFrequency: 10,
  warmAccessFrequency: 1,
  coldAccessFrequency: 0.1,
});

// Create cache engine
const cache = new CacheEngine(
  { ramTier, ssdTier, dbTier, accessTracker, tierManager, evictionPolicy },
  { trackAccess: true }
);

await cache.start();

// Use the cache
await cache.set('user:123', Buffer.from(JSON.stringify({ name: 'John' })));
const user = await cache.get('user:123');

await cache.shutdown();
```

## Configuration

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `CACHE_REDIS_PORT` | `6379` | Redis protocol port |
| `CACHE_DASHBOARD_PORT` | `8080` | Dashboard HTTP port |
| `CACHE_MAX_CONNECTIONS` | `1000` | Max concurrent connections |
| `CACHE_RAM_TIER_MAX_BYTES` | `1073741824` (1GB) | RAM tier capacity |
| `CACHE_SSD_TIER_MAX_BYTES` | `10737418240` (10GB) | SSD tier capacity |
| `CACHE_HOT_THRESHOLD` | `10` | Accesses/min for hot (RAM) |
| `CACHE_WARM_THRESHOLD` | `1` | Accesses/min for warm (SSD) |
| `CACHE_COLD_THRESHOLD` | `0.1` | Accesses/min for cold (DB) |
| `CACHE_EVICTION_POLICY` | `lru` | `lru`, `lfu`, or `hybrid` |
| `CACHE_TIER_MOVEMENT_INTERVAL_MS` | `5000` | Tier evaluation interval |

### Config File (config.json)

```json
{
  "redisPort": 6379,
  "dashboardPort": 8080,
  "ramTierMaxBytes": 1073741824,
  "ssdTierMaxBytes": 10737418240,
  "hotThreshold": 10,
  "warmThreshold": 1,
  "coldThreshold": 0.1,
  "evictionPolicy": "lru",
  "tierMovementIntervalMs": 5000
}
```

## Supported Redis Commands

### String Operations
- `GET key` - Get value
- `SET key value [EX seconds] [NX|XX]` - Set value with optional TTL
- `DEL key [key ...]` - Delete keys
- `EXISTS key [key ...]` - Check if keys exist
- `MGET key [key ...]` - Get multiple values
- `MSET key value [key value ...]` - Set multiple values
- `INCR key` / `DECR key` - Atomic increment/decrement
- `EXPIRE key seconds` - Set TTL
- `TTL key` - Get remaining TTL

### List Operations
- `LPUSH key value [value ...]` - Push to head
- `RPUSH key value [value ...]` - Push to tail
- `LPOP key` - Pop from head
- `RPOP key` - Pop from tail
- `LRANGE key start stop` - Get range

### Hash Operations
- `HSET key field value` - Set field
- `HGET key field` - Get field
- `HMSET key field value [field value ...]` - Set multiple fields
- `HMGET key field [field ...]` - Get multiple fields
- `HGETALL key` - Get all fields

### Set Operations
- `SADD key member [member ...]` - Add members
- `SREM key member [member ...]` - Remove members
- `SMEMBERS key` - Get all members
- `SISMEMBER key member` - Check membership

## Dashboard API

### Endpoints

| Endpoint | Description |
|----------|-------------|
| `GET /metrics` | Cache metrics (hit rate, ops/sec, tier usage) |
| `GET /keys/hot?n=10` | Top N hottest keys |
| `GET /tiers` | Tier distribution statistics |
| `GET /health` | Health check |
| `GET /suggestions` | Optimization suggestions |
| `GET /cost` | Cost/savings metrics |
| `GET /history?limit=60` | Historical utilization |

### WebSocket

Connect to `ws://localhost:8080` for real-time metrics updates.

## How Tiering Works

1. **New keys start in RAM** (fastest tier)
2. **Background processor runs every 5 seconds** evaluating access patterns
3. **Keys are promoted/demoted based on access frequency:**
   - Hot (≥10 accesses/min) → RAM
   - Warm (≥1 access/min) → SSD (RocksDB)
   - Cold (<0.1 accesses/min) → SQLite
4. **On shutdown**, RAM data is persisted to SSD + snapshot
5. **On startup**, data is restored from snapshot + SSD/DB scan

## Storage Technologies

| Tier | Technology | Use Case |
|------|------------|----------|
| RAM | JavaScript Map | Hot data, sub-millisecond access |
| SSD | RocksDB (classic-level) | Warm data, fast persistent storage |
| DB | SQLite (better-sqlite3) | Cold data, reliable long-term storage |

## License

MIT
# smart-tiered-cache
