encore-cache — скилл для Claude Code: Redis-кэш
Сохраняет данные в Redis через типизированные keyspace в Encore.ts. Подходит для TTL, счётчиков, временных токенов и горячих чтений.
npx skills add encoredev/skills --skill encore-cache -a claude-code
npx skills add encoredev/skills --skill cache -a claude-codeЧто делает encore-cache
Скилл описывает работу с Redis через CacheCluster и типизированные keyspace из encore.dev/storage/cache. Он помогает задавать схемы ключей и значений для строк, чисел, структур, списков и множеств. Для счётчиков есть атомарные increment и decrement.
Внутри есть примеры TTL через expireIn, expireDailyAt, neverExpire и keepTTL, а также операций setIfNotExists и replace. get() возвращает undefined при промахе, а конфликты дают ошибки CacheKeyExists и CacheMiss.
В локальной разработке используется Redis в памяти с лимитом около 100 ключей, поэтому нагрузочные тесты на нём запускать нельзя. Для долговечного хранения в инструкции указаны encore-database с Postgres и encore-bucket для объектного хранилища.
Какие задачи решает
- сохранить временный токен с TTL
- считать запросы атомарным счётчиком
- ускорить чтение часто запрашиваемых данных
- собрать типизированный Redis-ключ из нескольких полей
Примеры запросов агенту
- Настрой кэш Redis в Encore.ts для временных токенов с TTL.
- Создай счётчик запросов по
userIdс атомарным увеличением. - Опиши
StructKeyspaceдля профилей пользователей и обработай промах кэша.
Как установить encore-cache
1Через Skills CLI (Vercel)
npx skills add encoredev/skills --skill encore-cache -a claude-codenpx skills add encoredev/skills --skill cache -a claude-code2Вручную: положить файлы
~/.claude/skills/cache/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/cache/
1Через Skills CLI (Vercel)
npx skills add encoredev/skills --skill cache -a codex2Вручную: положить файлы
.agents/skills/cache/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add encoredev/skills --skill cache -a cursor2Вручную: положить файлы
.cursor/skills/cache/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install encoredev/skills cache2Вручную: положить файлы
.github/skills/cache/SKILL.md1Через Skills CLI (Vercel)
npx skills add encoredev/skills --skill cache -a gemini-cli2Командой платформы
gemini skills install https://github.com/encoredev/skills --path encore/cacheВручную: положить файлы
.devin/skills/cache/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add encoredev/skills --skill cache -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Вопросы о encore-cache
Как установить encore-cache в Claude Code?
Выполните npx skills add encoredev/skills --skill encore-cache -a claude-code, затем npx skills add encoredev/skills --skill cache -a claude-code. Проверьте установку по пути ~/.claude/skills/cache/SKILL.md.
Что делает encore-cache?
Скилл помогает настроить типизированный Redis-кэш в Encore.ts: keyspace для разных типов данных, TTL, атомарные счётчики и операции с конфликтами ключей.
Можно ли запускать нагрузочные тесты локально?
Нет. Локальная разработка использует Redis в памяти с лимитом около 100 ключей, поэтому для долговечных данных нужны encore-database или encore-bucket.
Исходный текст
SKILL.md · Apache-2.0
---
name: encore-cache
description: Cache data in Redis from Encore.ts using `CacheCluster` and typed keyspaces from `encore.dev/storage/cache`. Type-safe key/value access with TTLs, atomic increments, and per-keyspace data shapes.
when_to_use: >-
User wants to cache values, store ephemeral state, rate-limit by counter, build a leaderboard, speed up a hot read, or store short-lived tokens. Covers `CacheCluster`, `StringKeyspace`, `IntKeyspace`, `FloatKeyspace`, `StructKeyspace`, list and set keyspaces, TTL helpers (`expireIn`, `expireDailyAt`, `neverExpire`, `keepTTL`), atomic `increment`/`decrement`, `setIfNotExists`, `replace`, eviction policies, and `CacheMiss`/`CacheKeyExists` errors. Trigger phrases: "cache this", "Redis", "key-value store", "rate limit", "TTL", "expire after", "in-memory store", "session token store", "leaderboard counter".
---
# Encore Caching (Redis)
## Instructions
Encore's cache is a typed wrapper around Redis. Declare a `CacheCluster` once, then create `Keyspace` objects for each shape of data you need.
### Cluster
```typescript
import { CacheCluster } from "encore.dev/storage/cache";
const cluster = new CacheCluster("my-cache", {
evictionPolicy: "allkeys-lru",
});
```
Reference a cluster from another service: `const cluster = CacheCluster.named("my-cache");`
Eviction policies: `"allkeys-lru"` (default), `"noeviction"`, `"allkeys-lfu"`, `"allkeys-random"`, `"volatile-lru"`, `"volatile-lfu"`, `"volatile-ttl"`, `"volatile-random"`.
### Keyspace types
Each keyspace has a key shape (used to build the Redis key from `keyPattern`) and a value type.
```typescript
import {
StringKeyspace,
IntKeyspace,
FloatKeyspace,
StructKeyspace,
StringListKeyspace,
NumberListKeyspace,
StringSetKeyspace,
NumberSetKeyspace,
expireIn,
} from "encore.dev/storage/cache";
// Strings
const tokens = new StringKeyspace<{ tokenId: string }>(cluster, {
keyPattern: "token/:tokenId",
defaultExpiry: expireIn(3600 * 1000),
});
await tokens.set({ tokenId: "abc" }, "value");
const val = await tokens.get({ tokenId: "abc" }); // undefined on miss
// Integers (atomic counters)
const counters = new IntKeyspace<{ userId: string }>(cluster, {
keyPattern: "requests/:userId",
defaultExpiry: expireIn(10 * 1000),
});
const count = await counters.increment({ userId: "user123" }, 1);
// Structs (JSON)
interface UserProfile { name: string; email: string; }
const profiles = new StructKeyspace<{ userId: string }, UserProfile>(cluster, {
keyPattern: "profile/:userId",
defaultExpiry: expireIn(3600 * 1000),
});
await profiles.set({ userId: "123" }, { name: "Alice", email: "[email protected]" });
// Lists
const recent = new StringListKeyspace<{ userId: string }>(cluster, {
keyPattern: "recent/:userId",
});
await recent.pushRight({ userId: "user123" }, "item1", "item2");
// Sets
const tags = new StringSetKeyspace<{ articleId: string }>(cluster, {
keyPattern: "tags/:articleId",
});
await tags.add({ articleId: "post1" }, "typescript", "encore");
const has = await tags.contains({ articleId: "post1" }, "typescript");
```
### Multi-field key patterns
```typescript
interface Key { userId: string; resourcePath: string; }
const requests = new IntKeyspace<Key>(cluster, {
keyPattern: "requests/:userId/:resourcePath",
defaultExpiry: expireIn(10 * 1000),
});
```
### Expiry helpers
```typescript
import {
expireIn, // milliseconds
expireInSeconds,
expireInMinutes,
expireInHours,
expireDailyAt, // a specific UTC time each day
neverExpire,
keepTTL, // keep existing TTL when updating
} from "encore.dev/storage/cache";
```
### Write options
```typescript
await keyspace.set(key, value, { expiry: expireInMinutes(30) });
await keyspace.set(key, value, { expiry: keepTTL });
await keyspace.setIfNotExists(key, value); // throws CacheKeyExists if present
await keyspace.replace(key, value); // throws CacheMiss if absent
```
### Errors
```typescript
import { CacheMiss, CacheKeyExists } from "encore.dev/storage/cache";
const value = await keyspace.get(key); // undefined on miss (does not throw)
```
## Guidelines
- Declare `CacheCluster` and keyspaces at package level.
- Pick the most specific keyspace type — `IntKeyspace` for counters gives you atomic `increment`/`decrement` for free.
- `get()` returns `undefined` on miss; `replace()` and `setIfNotExists()` throw on conflict.
- Local development uses an in-memory Redis with a ~100-key cap — don't load-test it.
- For durable storage, use `encore-database` (Postgres) or `encore-bucket` (object storage) instead.
© encoredev · Apache-2.0 · encoredev/skills