super_cache

A production-grade, mobile-first LRU caching engine for Flutter and Dart.

Zero external dependencies. Batteries-included observability, TTL, memory pressure handling, and Clean Architecture integration out of the box.


Features

Feature Details
O(1) LRU HashMap + manual doubly-linked list — correct and fast
TTL Absolute or sliding; lazy expiration + background sweep
Capacity Count-based (maxEntries) and bytes-based (maxBytes)
Observability CacheMetrics snapshot and metricsStream broadcast
Layered cache CacheOrchestrator L1→L2→L3 with automatic promotion
Repository pattern CacheRepositoryMixin with stampede protection
Memory pressure MemoryCachePressureWatcher (iOS/Android)
Debug UI CacheDebugOverlay widget

Installation

dependencies:
  super_cache: ^1.0.0

For Flutter-specific features (memory pressure, debug overlay):

import 'package:super_cache/super_cache_flutter.dart';

For pure-Dart environments (tests, CLI):

import 'package:super_cache/super_cache.dart';

Quick start

In-memory LRU cache

import 'package:super_cache/super_cache.dart';

final cache = MemoryCache<String, User>(
  maxEntries: 200,
  defaultTTL: const Duration(minutes: 5),
);

cache.put('user_1', user);
final user = cache.get('user_1'); // null if expired or evicted
cache.dispose();

Layered cache (L1 memory + L3 disk)

import 'package:super_cache/super_cache.dart';
import 'package:super_cache_disk/super_cache_disk.dart';

final cache = CacheOrchestrator<String, Product>(
  l1: MemoryCache(maxEntries: 100),
  l3: DiskCache(
    directory: cacheDir,
    codec: JsonCacheCodec(
      fromJson: Product.fromJson,
      toJson: (p) => p.toJson(),
    ),
  ),
);

await (cache.l3 as DiskCache).initialize();
await cache.put('p_1', product);
final p = await cache.get('p_1'); // L1 hit on second access

Repository mixin

class UserRepository with CacheRepositoryMixin<String, User> {
  @override
  Cache<String, User> get cache => _cache;
  final _cache = MemoryCache<String, User>(maxEntries: 200);

  Future<User?> getUser(String id) => fetchWithCache(
    id,
    policy: const CacheAside(ttl: Duration(minutes: 5)),
    onMiss: () => _api.fetchUser(id),
  );
}

Concurrent calls for the same key while the cache is cold trigger only one onMiss invocation — the second caller awaits the same Future.


Cache policies

Policy Description
CacheAside Check cache; on miss call onMiss, store result. Default.
WriteThrough Every write goes to both cache and source simultaneously.
RefreshAhead Serve current (potentially stale) value while refreshing in background after refreshAfter elapses.

TTL modes

// Absolute TTL (default): entry expires X seconds after put()
final cache = MemoryCache<String, String>(
  defaultTTL: const Duration(minutes: 10),
);

// Sliding TTL: TTL resets on every successful get()
final sliding = MemoryCache<String, String>(
  defaultTTL: const Duration(minutes: 10),
  ttlMode: TTLMode.sliding,
);

Observability

// One-shot snapshot
final m = cache.metrics;
print('Hit rate: ${(m.hitRate * 100).toStringAsFixed(1)}%');
print('Entries: ${m.currentEntries} / ${m.hits + m.misses} requests');

// Live stream (emits on every sweep interval)
cache.metricsStream.listen((m) {
  debugPrint('$m');
});

Memory pressure (Flutter)

import 'package:super_cache/super_cache_flutter.dart';

final cache = MemoryCache<String, Uint8List>(maxEntries: 500);
final watcher = MemoryCachePressureWatcher(cache: cache);
// WidgetsBinding registers automatically — no extra setup needed.
// Dispose when done:
watcher.dispose();

On moderate memory pressure: evicts the least-recently-used 20% of entries. On critical pressure: evicts 50%.


Packages in this family

Package Purpose
super_cache Core LRU engine (this package)
super_cache_secure AES-256-GCM encrypted in-memory cache
super_cache_disk Persistent file-based cache with SHA-256 integrity
super_cache_testing FakeCache + ManualClock for unit tests

Libraries

super_cache
super_cache — Production-grade mobile-first caching engine for Flutter.
super_cache_flutter
Flutter-specific extensions for super_cache.