@use-crux/upstash
Upstash SearchStore and Redis RecordStore adapters for Crux.
Peer dependencies:
@upstash/vector>=1.2.2 forupstashSearchStore()@upstash/rediswhen you useupstashRedisRecordStore()@upstash/qstashwhen you useqstash()from@use-crux/upstash/runtime
import { upstashRedisRecordStore, upstashSearchStore } from "@use-crux/upstash";For setup guidance and usage patterns, see the Storage guide, RecordStore guide, and SearchStore guide.
upstashRedisRecordStore(config)
Create a Storage Beta RecordStore backed by Upstash Redis.
import { Redis } from "@upstash/redis";
import { upstashRedisRecordStore } from "@use-crux/upstash";
const records = upstashRedisRecordStore({
redis: new Redis({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
}),
prefix: "crux:",
});Redis Capabilities
| Capability | Value | Notes |
|---|---|---|
| Record TTL | 'native' | Uses Redis PX expiry for ttlMs. |
| Record filters | 'scan' | Uses cursor SCAN and applies exact top-level scalar filters locally. |
| Watch | true when subscriber is configured | Uses Redis pub/sub and cleans up backend listeners when unsubscribed. |
| Batch | false | The beta adapter does not claim native batch operations. |
list(prefix) is cursor-backed and does not use Redis KEYS.
Redis Config
| Field | Type | Description |
|---|---|---|
redis | RedisRecordClient | Redis client with get, set, del, and scan. |
prefix | string? | Prefix for Redis keys. Defaults to 'crux:'. |
subscriber | RedisSubscriber? | Optional pub/sub connection for watch(). |
scanCount | number? | Redis SCAN count hint. Defaults to 100. |
Use it with a bundle:
import { storage } from "@use-crux/core/storage";
const appStorage = storage({ records, search });upstashSearchStore(config)
Create a Storage Beta SearchStore backed by Upstash Vector.
import { Index } from "@upstash/vector";
import { upstashSearchStore } from "@use-crux/upstash";
const search = upstashSearchStore({
index: new Index({
url: process.env.UPSTASH_VECTOR_REST_URL!,
token: process.env.UPSTASH_VECTOR_REST_TOKEN!,
}),
namespace: "product-docs",
});Search Capabilities
Upstash index mode is deployment configuration, so the adapter defaults conservatively:
| Capability | Default | Notes |
|---|---|---|
| Dense leg | true | Dense vectors are the default Upstash path. |
| Sparse leg | false | Opt in only when the backing index supports sparse vectors. |
| Lexical leg | false | Upstash Vector is not the PostgreSQL lexical implementation. |
| Fusion | ['rrf'] | The adapter performs deterministic RRF across query legs. |
| Filters | 'pre' | Upstash applies supported metadata filters before top-k search. |
| Consistency | 'eventual' | Matches managed vector-index behavior. |
Declare sparse support explicitly:
const search = upstashSearchStore({
index,
namespace: "product-docs",
capabilities: {
legs: { sparse: true },
},
});Unsupported query legs or fusion throw StorageError code unsupported_capability. Unsupported filter values throw StorageError code invalid_filter before querying Upstash.
With Retrieval
Use the beta storage fields:
const docsIndexer = indexer({
id: "docs",
namespace: "product-docs",
records,
search,
dense,
sparse,
});
const docs = retriever({
id: "docs",
namespace: "product-docs",
records,
search,
dense,
sparse,
});
const hits = await docs.retrieve({
query: "enterprise SSO setup",
search: {
dense: true,
sparse: true,
fusion: { strategy: "rrf", k: 60 },
},
limit: 10,
});Filtered retrieval requires a search store with capabilities().filter === 'pre'.
Recommended Wiring
upstashRedisRecordStore()for Redis-backed recordsupstashSearchStore()for Upstash Vector searchstorage({ records, search })to pass a bundle to Crux primitives
Runtime Wake: qstash()
Use qstash() from @use-crux/upstash/runtime as the first-party HTTP wake adapter for serverless Runtime Engine deployments.
import { config } from "@use-crux/core";
import { serverless } from "@use-crux/core/runtime";
import { postgres } from "@use-crux/postgres/runtime";
import { qstash } from "@use-crux/upstash/runtime";
export default config({
runtime: serverless({
store: postgres(),
wake: qstash(),
}),
});QStash publishes small wake envelopes to the configured runtime endpoint and verifies incoming Upstash-Signature headers with the official receiver. Use it with a durable store such as postgres(); @use-crux/upstash/runtime does not ship an Upstash Redis runtime store in v1.
Related
- Guide: Storage
- Guide: Next/Vercel Runtime
- Guide: RecordStore
- Guide: SearchStore
- Reference: Runtime Engine
- Reference: Indexing
- Reference: Retrieval