@mastra/core
Version:
Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.
160 lines (113 loc) • 4.36 kB
Markdown
# Upstash storage
The Upstash storage implementation provides a serverless-friendly storage solution using Upstash's Redis-compatible key-value store.
> **Pricing:** When using Mastra with Upstash, the pay-as-you-go model can result in unexpectedly high costs due to the high volume of Redis commands generated during agent conversations. We strongly recommend using a **fixed pricing plan** for predictable costs. See [Upstash pricing](https://upstash.com/pricing/redis) for details and [GitHub issue #5850](https://github.com/mastra-ai/mastra/issues/5850) for context.
> **Observability Not Supported:** Upstash storage **doesn't support the observability domain**. Traces from the `MastraStorageExporter` can't be persisted to Upstash, and [Studio's](https://mastra.ai/docs/studio/overview) observability features won't work with Upstash as your only storage provider. To enable observability, use [composite storage](https://mastra.ai/reference/storage/composite) to route observability data to a supported provider like ClickHouse.
## Installation
**npm**:
```bash
npm install @mastra/upstash@latest
```
**pnpm**:
```bash
pnpm add @mastra/upstash@latest
```
**Yarn**:
```bash
yarn add @mastra/upstash@latest
```
**Bun**:
```bash
bun add @mastra/upstash@latest
```
## Usage
```typescript
import { UpstashStore } from '@mastra/upstash'
const storage = new UpstashStore({
id: 'upstash-storage',
url: process.env.UPSTASH_URL,
token: process.env.UPSTASH_TOKEN,
})
```
## Parameters
**url** (`string`): Upstash Redis URL
**token** (`string`): Upstash Redis authentication token
**prefix** (`string`): Key prefix for all stored items (Default: `mastra:`)
## Additional notes
### Key Structure
The Upstash storage implementation uses a key-value structure:
- Thread keys: `{prefix}thread:{threadId}`
- Message keys: `{prefix}message:{messageId}`
- Metadata keys: `{prefix}metadata:{entityId}`
### Serverless Benefits
Upstash storage is particularly well-suited for serverless deployments:
- No connection management needed
- Pay-per-request pricing
- Global replication options
- Edge-compatible
### Data Persistence
Upstash provides:
- Automatic data persistence
- Point-in-time recovery
- Cross-region replication options
### Performance Considerations
For optimal performance:
- Use appropriate key prefixes to organize data
- Monitor Redis memory usage
- Consider data expiration policies if needed
## Usage example
### Adding memory to an agent
To add Upstash memory to an agent use the `Memory` class and create a new `storage` key using `UpstashStore` and a new `vector` key using `UpstashVector`. The configuration can point to either a remote service or a local setup.
```typescript
import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'
import { UpstashStore } from '@mastra/upstash'
export const upstashAgent = new Agent({
id: 'upstash-agent',
name: 'Upstash Agent',
instructions:
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
model: 'openai/gpt-5.4',
memory: new Memory({
storage: new UpstashStore({
id: 'upstash-agent-storage',
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
}),
options: {
generateTitle: true, // Explicitly enable automatic title generation
},
}),
})
```
### Using the agent
Use `memoryOptions` to scope recall for this request. Set `lastMessages: 5` to limit recency-based recall, and use `semanticRecall` to fetch the `topK: 3` most relevant messages, including `messageRange: 2` neighboring messages for context around each match.
```typescript
import 'dotenv/config'
import { mastra } from './mastra'
const threadId = '123'
const resourceId = 'user-456'
const agent = mastra.getAgent('upstashAgent')
const message = await agent.stream('My name is Mastra', {
memory: {
thread: threadId,
resource: resourceId,
},
})
await message.textStream.pipeTo(new WritableStream())
const stream = await agent.stream("What's my name?", {
memory: {
thread: threadId,
resource: resourceId,
},
memoryOptions: {
lastMessages: 5,
semanticRecall: {
topK: 3,
messageRange: 2,
},
},
})
for await (const chunk of stream.textStream) {
process.stdout.write(chunk)
}
```