---
title: "Reference: Upstash Storage | Storage"
description: Documentation for the Upstash storage implementation in Mastra.
packages:
  - "@mastra/core"
  - "@mastra/memory"
  - "@mastra/upstash"
---

# Upstash Storage

The Upstash storage implementation provides a serverless-friendly storage solution using Upstash's Redis-compatible key-value store.

:::warning

**Important:** 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.

:::

## Installation

```bash
npm install @mastra/upstash@beta
```

## 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

<PropertiesTable
  content={[
    {
      name: "url",
      type: "string",
      description: "Upstash Redis URL",
      isOptional: false,
    },
    {
      name: "token",
      type: "string",
      description: "Upstash Redis authentication token",
      isOptional: false,
    },
    {
      name: "prefix",
      type: "string",
      description: "Key prefix for all stored items",
      isOptional: true,
      defaultValue: "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 title="src/mastra/agents/example-upstash-agent.ts"
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.1",
  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 title="src/test-upstash-agent.ts"
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);
}
```
