Caching & Performance
Enable caching, choose strategies, and optimize query performance
Enable Caching
Configure the caching layer with Redis or in-memory:
config/cache.ts
import { Stabilize, DBType } from "stabilize-orm";
// Cache-aside strategy (default)const orm = new Stabilize( { type: DBType.SQLite, connectionString: "./data/app.db" }, { enabled: true, ttl: 120, // 2 minutes redisUrl: "redis://localhost:6379", // optional, falls back to in-memory cachePrefix: "myapp:", // key prefix for cache entries strategy: "cache-aside", // check cache first, fall back to DB });
// Write-through strategyconst orm2 = new Stabilize( { type: DBType.Postgres, connectionString: "postgresql://..." }, { enabled: true, ttl: 300, strategy: "write-through", // write to cache on every DB write });Cache-Aside vs Write-Through
examples/cache-strategies.ts
// Cache-aside: Reads check cache first, writes invalidate cache// Best for: Read-heavy workloads with infrequent writesconst user = await userRepo.findOne(1);// First call: DB hit, result cached// Second call: Cache hit, no DB query
await userRepo.update(1, { name: "Updated" });// Cache invalidated, next read goes to DB
// Write-through: Writes update both DB and cache// Best for: Mixed read/write workloadsconst orm = new Stabilize(config, { enabled: true, ttl: 60, strategy: "write-through" });Cache Statistics
examples/cache-stats.ts
// Get cache statisticsconst stats = await orm.getCacheStats();console.log("Cache hits:", stats.hits);console.log("Cache misses:", stats.misses);console.log("Cache keys:", stats.keys);
// Cache hit ratioconst ratio = stats.hits / (stats.hits + stats.misses) * 100;console.log("Cache hit ratio:", ratio.toFixed(1) + "%");Performance Tips
examples/performance.ts
// 1. Use select() to fetch only needed columnsconst users = await userRepo.find() .select("id", "name", "email") .execute(orm.client);
// 2. Use pagination instead of fetching all recordsconst page = await userRepo.paginate(1, 50);
// 3. Use bulk operations for multiple insertsawait userRepo.bulkCreate(users, { batchSize: 500 });
// 4. Use indexes on frequently queried columns// Add index in model definition:// email: { type: DataTypes.STRING, index: "idx_email" }
// 5. Use pluck() for single-column fetchesconst emails = await userRepo.pluck("email");
// 6. Use count() instead of fetching and countingconst count = await userRepo.count({ isActive: true });
// 7. Use exists() instead of count() for presence checksconst hasUsers = await userRepo.exists({ role: "admin" });
// 8. Connection pooling (built-in for Postgres/MySQL)const poolStats = await orm.poolStats();console.log("Pool:", poolStats);