Skip to main content
Cache is a fast key-value store co-located with each FastEdge POP (Point of Presence). It is intended for transient, request-time state — counters, memoized computations, idempotency tokens — and is available to every FastEdge application on a paid plan at runtime without needing to be created or linked in advance.
Cache does not need to be created or linked to your application. It is available at runtime by importing the cache module from the SDK.

Behavior and limits

Cache data lives inside a single POP. Writes are not replicated to other POPs, and a value written in one location is not visible from another. Within a POP, reads and writes are strongly consistent. Entries are evictable and carry no durability guarantee. A value may disappear before its expiration if the POP is under memory pressure. Cache is not a substitute for persistent storage. Integer values can be incremented and decremented atomically within a POP, making Cache a natural fit for rate limiting and fixed-window throttling. The incr function accepts a signed delta — a positive value increments, a negative value decrements. The JavaScript SDK provides a getOrSet operation: if the key exists, its value is returned immediately; if not, a provided callback computes the value, stores it, and returns it. This is useful for read-through caching where computation is expensive. purge removes all cache keys visible to the application; purgePrefix removes all keys whose names begin with a given string. Both return the number of keys deleted. Because Cache is shared across all applications for an account at a POP, these operations affect every key visible to your account at that POP, not only those written by the calling application.

Cache vs Edge Storage

Cache and Edge Storage solve different problems. Use this table to decide which one fits your workload.
CacheEdge Storage
ScopeSingle POPGlobally replicated to all POPs
ConsistencyStrong (within a POP)Eventual (1–2 seconds globally)
DurabilityTransient, evictableDurable, backed by a central database
ProvisioningNone — available at runtime on paid plansCreated in the Customer Portal and linked to your application
Writes from the APINo (runtime only)Yes
Atomic countersYes (incr; decr JS only)No
Typical workloadsRate limits, response memoization, idempotency keys, per-request deduplicationConfiguration, feature flags, lookup tables, blocklists, sorted sets, Bloom Filters
A common pattern is to use both together: store the source of truth in Edge Storage and use Cache to memoize derived results or enforce per-POP rate limits.

Available operations

OperationDescription
getFetch a cached value by key. Returns None/null on a miss.
setWrite or overwrite a value with an optional TTL.
deleteRemove a key from the cache.
existsCheck whether a key is present without fetching its value.
incrAtomically increment (or decrement) an integer counter.
decrDecrement a counter. JavaScript SDK only.
expireSet or update the TTL of an existing key. Returns false if the key no longer exists.
getOrSetFetch a value, or compute and store it if missing. JavaScript SDK only.
purgeDelete all cache keys visible to the application at the current POP.
purgePrefixDelete all keys whose names begin with a given prefix.
In the JavaScript SDK, expiration is specified per write as { ttl: seconds }, { ttlMs: milliseconds }, or { expiresAt: unixTimestamp }. In the Rust SDK, TTL is always in milliseconds (Option<u64>). Entries with no expiration remain until evicted.

SDK examples

The following examples cover the most common Cache patterns. For the full API reference, see the JavaScript SDK and Rust SDK documentation.

Read and write a value

import { Cache } from 'fastedge::cache';

await Cache.set('config:feature-x', 'enabled', { ttl: 300 }); // 5-minute TTL

const value = await Cache.get('config:feature-x');
if (value === null) {
  // cache miss — compute and store
}

await Cache.delete('config:feature-x');

Rate limiting with an atomic counter

import { Cache } from 'fastedge::cache';

const ip = event.client.address ?? 'unknown';
const key = `rl:${ip}`;

const count = await Cache.incr(key);
if (count === 1) {
  // First request in the window — set a 60-second TTL
  await Cache.expire(key, { ttl: 60 });
}

if (count > 100) {
  return new Response('Too Many Requests', { status: 429 });
}