walkeros-create-cmp-so…
A CMP source is a specialized walkerOS source that listens to a consent management platform's events and translates consent…
`Flow.Store.cache` wraps any store with a read-through, write-through cache tier. Reads check the cache first, fall through to the backing on miss, and populate every tier on the unwind. Writes go to the backing first, then to the cache best-effort.
$ npx -y skills add elbwalker/walkerOS --skill walkeros-using-store-cache --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/walkeros-using-store-cacheContext preview
The summary Claude sees to decide when to auto-load this skill.
`Flow.Store.cache` wraps any store with a read-through, write-through cache tier. Reads check the cache first, fall through to the backing on miss, and populate every tier on the unwind. Writes go to the backing first, then to the cache best-effort.
name: walkeros-using-store-cache description: Use when adding read-through caching to a walkerOS store, memoizing a slow API/Sheets backing, composing multi-tier cache chains, or deduplicating concurrent store reads. Covers recipes, TTL choice, error policy, and observability counters.
`Flow.Store.cache` wraps any store with a read-through, write-through cache tier. Reads check the cache first, fall through to the backing on miss, and populate every tier on the unwind. Writes go to the backing first, then to the cache best-effort.
The wrapping is transparent: a transformer wired to `$store.crm` does not know whether reads hit a memory cache, a GCS tier, or the underlying Sheets API.
**Core principle:** the cache is advisory. Backing is the source of truth. Failed cache operations degrade performance, never correctness.
**TTL is owned by the cache layer, not the store.** The store persists structured values; the cache wrapper manages expiry via the per-rule `ttl`. An expired entry is treated as a miss and re-fetched from the backing. Caching works over any structured backing.
A store's byte-native `file` mode (`config.file: true`) is for serving raw assets byte-exact, not for caching. The cache wraps structured stores, so `flow_validate` warns when a store sets both `file: true` and `cache`. Drop one: serve bytes with `file: true` and no cache, or cache a structured store with no `file`.
lookups, product catalog enrichment)
metadata)
built-in tier)
The talk-demo use case. A `sessions` lookup runs on every event but most events in a session share the same key.
{
"stores": {
"sessions": {
"package": "@walkeros/server-store-sheets",
"config": {
"credentials": "$var.sheetsCredentials",
"settings": {
"id": "1AbC...",
"sheet": "Sessions"
}
},
"cache": { "rules": [{ "ttl": 300 }] }
}
},
"transformers": {
"sessionLookup": {
"code": {
"type": "session-lookup",
"push": "$code:async (event, context) => { if (!event.user?.session) return; const session = await context.env.store.get(event.user.session); if (session) return { event: { ...event, data: { ...event.data, session } } }; }"
},
"env": { "store": "$store.sessions" }
}
}
}walkerOS ships no generic lookup transformer, so the consumer here is an inline `code` transformer. Any transformer or destination that reads its `env.store` works the same way.
The first lookup hits Sheets and populates the built-in in-memory tier with a 300-second TTL. The next 300 seconds of identical reads hit memory and skip the Sheets API.
Without the cache: 60 events in 60 seconds = 60 Sheets reads = quota tripped (60 req/min limit) in one minute. With the cache: 60 events in 60 seconds = 1 Sheets read.
Same shape, longer TTL because every read is a network round-trip to the bucket:
{
"stores": {
"users": {
"package": "@walkeros/server-store-gcs",
"config": {
"settings": { "bucket": "my-user-records", "prefix": "users/" }
},
"cache": { "rules": [{ "ttl": 3600 }] }
}
}
}One-hour TTL is reasonable when user records change rarely. Use `flow_validate` to verify the config; use `flow_simulate` with a representative event to confirm the cache hit rate.
Different keys can have different TTLs. Rules evaluate top-down, first match wins. The match context is `{ key, value? }`, not event data:
"cache": {
"rules": [
{ "match": { "key": "key", "operator": "prefix", "value": "session:" }, "ttl": 300 },
{ "match": { "key": "key", "operator": "prefix", "value": "user:" }, "ttl": 3600 },
{ "ttl": 60 }
]
}A rule without `match` always matches. Place it last as a fallback.
When the working set exceeds the memory tier's capacity, or cached values should survive restarts and be shared across instances, add an object storage layer between memory and the cold backing. The consumer still wires to `$store.crm`; the tiers resolve automatically. The cache tier must be fs, S3, GCS, or the built-in memory tier: the Sheets store cannot hold cache entries.
{
"stores": {
"files": {
"package": "@walkeros/server-store-gcs",
"config": {
"settings": { "bucket": "my-cache-bucket", "prefix": "cache/" }
},
"cache": { "rules": [{ "ttl": 300 }] }
},
"crm": {
"package": "@walkeros/server-store-sheets",
"config": { "settings": { "id": "1AbC...", "sheet": "Customers" } },
"cache": {
"store": "files",
"rules": [{ "ttl": 86400 }]
}
}
},
"transformers": {
"crmLookup": {
"code": {
"type": "crm-lookup",
"push": "$code:async (event, context) => { if (!event.user?.id) return; const crm = await context.env.store.get(event.user.id); if (crm) return { event: { ...event, data: { ...event.data, crm } } }; }"
},
"env": { "store": "$store.crm" }
}
}
}Lookup chain on `crm.get(K)`:
1. `crm`'s tier is the `files` store. The `files` wrapper checks its own tier (memory `__cache`) first, then GCS. HIT, return. A GCS HIT also populates memory. 2. On all MISS, call the underlying Sheets store. Each traversed tier pop
From browser to BigQuery and ad platforms - warehouse-native, and ready for AI agents via MCP.
A CMP source is a specialized walkerOS source that listens to a consent management platform's events and translates consent…
Use when creating a new walkerOS destination to send events to a vendor or API (GA4/gtag, Meta/Facebook Pixel, Mixpanel,…
Use when creating a new walkerOS source to capture events (browser source, dataLayer interception, server/HTTP source, webhook…
| Symptom | Likely Cause | Check | | ---------------------------------- | ---------------------------- |…
Read [understanding-mapping](../walkeros-understanding-mapping/SKILL.md) first for core concepts.