Skip to main content

File Cache Driver

The File Cache Driver stores cached data as files on disk. Each cache key is a directory containing a cache.json file.

When to Use

  • Local development
  • Need persistence across restarts, but don't want to set up Redis
  • Small to medium-sized cache needs

Best For

  • Caching API responses, config, or data that should survive restarts
  • Environments where Redis is not available

Limitations

  • Slower than memory or Redis for large caches
  • Not suitable for distributed/multi-server setups
  • Manual cleanup of expired files only happens on access

Alternatives

Configuration

src/config/cache.ts
import { env } from "@mongez/dotenv";
import { join } from "path";
import { CacheConfigurations, FileCacheDriver, CACHE_FOR } from "@warlock.js/cache";

const cacheConfigurations: CacheConfigurations = {
drivers: {
file: FileCacheDriver,
},
default: env("CACHE_DRIVER", "file"),
options: {
file: {
globalPrefix: "my-app",
ttl: CACHE_FOR.ONE_DAY,
directory: join(process.cwd(), "storage", "cache"), // Absolute path
fileName: "data.json",
},
},
};

export default cacheConfigurations;

Options

OptionTypeDefaultDescription
directorystring | FunctionstoragePath("cache")Directory for cache files
fileNamestring | Function"cache.json"File name for cache data
globalPrefixstring | FunctionundefinedGlobal prefix for all cache keys
ttlnumber0Default TTL in seconds (0 = no expiration)

Directory Configuration

The directory option should be an absolute path to ensure consistent behavior regardless of where the process is started:

import { join } from "path";

{
directory: join(process.cwd(), "storage", "cache"), // Absolute path
// OR
directory: join(__dirname, "..", "storage", "cache"), // From project root
// OR
directory: "/var/cache/myapp", // Explicit absolute path
// OR
directory: () => join(process.cwd(), "cache", environment()), // Dynamic absolute path
}
tip

Always use absolute paths for the directory option. Relative paths can cause issues depending on where your process is started.

File Name Configuration

{
fileName: "data.json", // Custom file name
// OR
fileName: () => `cache-${Date.now()}.json`, // Dynamic file name
}

Global Prefix

{
globalPrefix: "myapp", // Static prefix
// OR
globalPrefix: () => `app-${environment()}`, // Dynamic prefix
}

TTL Configuration

import { CACHE_FOR } from "@warlock.js/cache";

{
ttl: 0, // No expiration (default)
// OR
ttl: CACHE_FOR.ONE_HOUR, // 1 hour
// OR
ttl: CACHE_FOR.ONE_DAY, // 24 hours
}

Example Usage

Storing and Retrieving Data

import { cache, CACHE_FOR } from "@warlock.js/cache";

await cache.set("settings", { darkMode: true }, CACHE_FOR.ONE_HOUR);
const settings = await cache.get("settings");

File Structure

The file driver creates a directory structure like this:

/var/cache/myapp/           (or your specified directory)
├── myapp.settings/
│ └── cache.json
├── myapp.user.1/
│ └── cache.json
└── myapp.config/
└── cache.json

Each cache entry is stored in its own directory with a JSON file containing the data and metadata.

Expired Cache

  • Expired cache is only removed when accessed.
  • For automatic cleanup, consider a background job or use Redis.

Troubleshooting

  • Cache not persistent? Check your directory path and permissions.
  • Performance issues? For large caches, use Redis or Memory drivers.