Stores
Without stores, each event in a flow is processed in isolation: no shared state, no caching, no persisted data between requests. Stores add a shared memory layer that any component in your flow (transformers, destinations) can read from and write to.
A common example: serving the walker.js script from your own infrastructure. The file lives in a store (S3 or filesystem), and a transformer reads it on each request: no hardcoded paths, no rebuilds needed to swap the file.
When stores are active
Stores are initialized before any other component in the flow. Once running, they're available to transformers and destinations via $store.storeId wiring. A transformer might cache a processed result; a destination might check a store before making an external API call.
Flow startup order:
1. Stores ← initialized first
2. Transformers ← can reference stores via $store.id
3. Destinations ← can reference stores via $store.id
4. Sources ← start pushing events
Choosing a store
| Store | Platform | Persistence | Speed | Best for |
|---|---|---|---|---|
| Filesystem | Server only | Disk (survives restarts) | Fast (local I/O) | Local dev, Docker with baked-in assets |
| S3 | Server only | Cloud (always available) | Network I/O | Managed deployments, shared assets, hot-swap |
| GCS | Server only | Cloud (always available) | Network I/O | Cloud Run / GKE deployments, GCP-native |
| Sheets | Server only | Cloud (Google Sheets) | Slow (HTTP, rate-limited) | Demos, prototypes with a spreadsheet UI |
For ephemeral, in-process caching, use the built-in cache tier on any of the stores above, no separate package needed.
To read from or write to a store from a step without wiring $store and writing $code:, use the declarative state block on a source, transformer, or destination.
Wiring stores to components
Components reference stores via $store.storeId in their env configuration. The collector resolves this at startup and passes the live store instance to the component.
- Integrated
- Bundled
Common patterns
Stores are rarely used alone. They work together with transformers to enable analytics use cases that aren't possible with stateless event processing.
| Pattern | Store | Transformer | What it enables |
|---|---|---|---|
| Self-hosted tag delivery | S3 or Filesystem | File | Serve walker.js and tracking pixels from your own infrastructure |
| Cookie-free user identification | Built-in cache tier | Fingerprint | Store session hashes server-side, identify users without cookies or PII |
| Response caching | Built-in cache tier | Cache | Deduplicate identical requests, reduce load on downstream analytics APIs |
| Quota-friendly Sheets lookups | Sheets + cache tier | Any transformer | Memoize slow API reads, absorb rate limits via TTL |
| Local development | Filesystem | File | Serve assets from disk during development, no S3 credentials needed |
Available stores
Filesystem
Local filesystem store for server flows. Reads and writes files relative to a base path with path traversal protection. Good for local development and Docker deployments with baked-in assets.
S3
S3-compatible object storage. Works with AWS S3, Cloudflare R2, Scaleway, DigitalOcean Spaces, Backblaze B2, MinIO, and any S3-compatible provider. The recommended store for managed cloud deployments.
GCS
Google Cloud Storage with zero runtime dependencies. Built-in auth supports Application Default Credentials (ADC) on Cloud Run / GKE and explicit service account JSON for non-GCP environments. The recommended store for GCP-native deployments.
Sheets
Google Sheets store with zero runtime dependencies. Row-per-key storage using the Sheets v4 REST API. Designed for demos and small prototypes where the spreadsheet is the operator-facing UI. Rate-limited; pair with the cache tier for any non-trivial throughput.
Caching on stores
Wrap any of the stores above with a read-through, write-through cache tier by setting cache on the store declaration. The default tier uses the collector's built-in in-memory LRU. Compose multi-tier chains via cache.store.
Configuration
These fields are available on every store, regardless of package. They wrap the
package-specific settings field, which is documented on each store's page.
| Property | Type | Description | More |
|---|---|---|---|
settings | Store.Settings | Implementation-specific configuration | |
env | Store.Env | Environment dependencies (platform-specific) | |
id | string | Store instance identifier (defaults to store key) | |
logger | Logger.Config | ||
setup | boolean | object | One-time setup options applied during store registration (boolean enables defaults, object configures specifics) |