Caching in CommandKit
CommandKit provides a powerful caching system that helps you optimize your bot's performance by storing frequently accessed data in memory. This guide will show you how to use caching effectively in your bot.
Installation
First, install the cache package:
npm install @commandkit/cache
Setup
Add the cache plugin to your CommandKit configuration:
import { cache } from '@commandkit/cache';
export default defineConfig({
plugins: [cache()],
});
Optional: Custom Cache Provider
You can set up a custom cache provider (like Redis) for distributed caching:
import { setCacheProvider } from '@commandkit/cache';
import { RedisCache } from '@commandkit/redis';
setCacheProvider(
new RedisCache({
// Redis configuration options
}),
);
Why Use Caching?
Caching is useful when you want to:
- Reduce API calls to external services
- Speed up frequently accessed data
- Minimize database queries
- Store computed results for reuse
Basic Usage
The simplest way to use caching is with the "use cache"
directive:
async function fetchUserData(userId: string) {
'use cache';
// This expensive operation will only run once for each unique userId
const userData = await db.users.findOne(userId);
return userData;
}
When you call this function multiple times with the same userId
, it will only perform the database query once and return the cached result for subsequent calls.
How Caching Works
CommandKit's caching system works by:
-
Generating a Cache Key: Each cached function call generates a unique key based on:
- The function's identity
- The arguments passed to the function
- A build ID for stability
-
Storing Results: When a function is called:
- If the result isn't cached, the function executes and stores its result
- If the result is cached, it's returned immediately without executing the function
-
Automatic Cleanup: The cache system automatically:
- Removes stale entries
- Manages memory usage
- Handles cache invalidation
Cache Configuration
You can configure caching behavior using the cacheTag
and cacheLife
functions:
async function fetchUserData(userId: string) {
'use cache';
// Configure cache behavior
cacheTag(`user:${userId}`);
cacheLife('1h');
const userData = await db.users.findOne(userId);
return userData;
}
Best Practices
-
Choose What to Cache:
- Cache expensive operations (API calls, database queries)
- Cache data that doesn't change frequently
- Don't cache sensitive or frequently changing data
-
Set Appropriate TTL:
- Use shorter TTL for frequently changing data
- Use longer TTL for static data
- Consider your data's update frequency
-
Use Tags for Revalidation:
- Add meaningful tags to your cache entries
- Group related cache entries with the same tag
- Use tags for targeted cache invalidation
-
Monitor Cache Usage:
- Watch memory usage
- Adjust TTL based on usage patterns
- Clean up stale entries when needed
Example Use Cases
Caching API Responses
async function fetchWeather(city: string) {
'use cache';
cacheTag('weather');
cacheLife('30m');
const response = await fetch(`https://api.weather.com/${city}`);
return response.json();
}
Caching Database Queries
async function getGuildSettings(guildId: string) {
'use cache';
cacheTag(`guild:${guildId}`);
cacheLife('1h');
return await db.guilds.findOne(guildId);
}
Caching Computed Results
async function calculateUserStats(userId: string) {
'use cache';
cacheTag(`user:${userId}`);
cacheTag('stats');
cacheLife('5m');
const user = await db.users.findOne(userId);
return {
level: calculateLevel(user.xp),
rank: await calculateRank(userId),
achievements: await getAchievements(userId),
};
}
Advanced Usage
Custom Cache Provider
You can create a custom cache provider by extending the CacheProvider
class:
import { CacheProvider } from '@commandkit/cache';
class RedisCache extends CacheProvider {
async get<T>(key: string) {
// Implement Redis get
}
async set<T>(key: string, value: T, ttl?: number) {
// Implement Redis set
}
async delete(key: string) {
// Implement Redis delete
}
}
// Use your custom provider
setCacheProvider(new RedisCache());
Cache Cleanup
You can manually clean up stale cache entries:
import { cleanup } from '@commandkit/cache';
// Clean up entries older than 24 hours
await cleanup(24 * 60 * 60 * 1000);
Next Steps
- Learn about cacheTag for tag-based cache management
- Discover cacheLife for controlling cache duration
- Master revalidateTag for cache invalidation