Convex
The Convex storage implementation provides a serverless storage solution using Convex, a full-stack TypeScript development platform with real-time sync and automatic caching.
Convex storage doesn't support the observability domain. Traces from the MastraStorageExporter can't be persisted to Convex, and Studio's observability features won't work with Convex as your only storage provider. To enable observability, use composite storage to route observability data to a supported provider like ClickHouse.
Convex enforces a 1 MiB maximum record size. This limit can be exceeded when storing messages with base64-encoded attachments such as images. See Handling large attachments for workarounds including uploading attachments to external storage like S3, Cloudflare R2, or Convex file storage.
InstallationInstallation的直接链接
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/convex@latest
pnpm add @mastra/convex@latest
yarn add @mastra/convex@latest
bun add @mastra/convex@latest
Convex setupConvex setup的直接链接
Before using ConvexStore, set up the Convex schema and storage handler in your Convex project.
The schema example below includes the full ConvexStore and ConvexServerCache setup. If you only use ConvexStore, omit mastraCacheTable and mastraCacheListItemsTable; if you use ConvexServerCache, include those tables and create the cache handler.
1. Set up Convex Schema1. Set up Convex Schema的直接链接
In convex/schema.ts:
import { defineSchema } from 'convex/server'
import {
mastraThreadsTable,
mastraMessagesTable,
mastraResourcesTable,
mastraWorkflowSnapshotsTable,
mastraScoresTable,
mastraObservationalMemoryTable,
mastraVectorIndexesTable,
mastraVectorsTable,
mastraCacheTable,
mastraCacheListItemsTable,
mastraDocumentsTable,
} from '@mastra/convex/schema'
export default defineSchema({
mastra_threads: mastraThreadsTable,
mastra_messages: mastraMessagesTable,
mastra_resources: mastraResourcesTable,
mastra_workflow_snapshots: mastraWorkflowSnapshotsTable,
mastra_scorers: mastraScoresTable,
mastra_observational_memory: mastraObservationalMemoryTable,
mastra_vector_indexes: mastraVectorIndexesTable,
mastra_vectors: mastraVectorsTable,
mastra_cache: mastraCacheTable,
mastra_cache_list_items: mastraCacheListItemsTable,
mastra_documents: mastraDocumentsTable,
})
2. Create the Storage Handler2. Create the Storage Handler的直接链接
In convex/mastra/storage.ts:
import { mastraStorage } from '@mastra/convex/server'
export const handle = mastraStorage
If you use ConvexServerCache, create convex/mastra/cache.ts:
import { mastraCache } from '@mastra/convex/server'
export const handle = mastraCache
3. Deploy to Convex3. Deploy to Convex的直接链接
npx convex dev
# or for production
npx convex deploy
UsageUsage的直接链接
import { ConvexServerCache, ConvexStore } from '@mastra/convex'
const storage = new ConvexStore({
id: 'convex-storage',
deploymentUrl: process.env.CONVEX_URL!,
adminAuthToken: process.env.CONVEX_ADMIN_KEY!,
})
const cache = new ConvexServerCache({
deploymentUrl: process.env.CONVEX_URL!,
adminAuthToken: process.env.CONVEX_ADMIN_KEY!,
})
ConvexStore parametersConvexStore parameters的直接链接
deploymentUrl:
adminAuthToken:
storageFunction?:
ConvexServerCache parametersConvexServerCache parameters的直接链接
deploymentUrl:
adminAuthToken:
cacheFunction?:
requestTimeoutMs?:
keyPrefix?:
ttlMs?:
Constructor examplesConstructor examples的直接链接
import { ConvexServerCache, ConvexStore } from '@mastra/convex'
// Basic configuration
const store = new ConvexStore({
id: 'convex-storage',
deploymentUrl: 'https://your-project.convex.cloud',
adminAuthToken: 'your-admin-token',
})
// With custom storage function path
const storeCustom = new ConvexStore({
id: 'convex-storage',
deploymentUrl: 'https://your-project.convex.cloud',
adminAuthToken: 'your-admin-token',
storageFunction: 'custom/path:handler',
})
// Server cache for durable stream replay and response caching
const cache = new ConvexServerCache({
deploymentUrl: 'https://your-project.convex.cloud',
adminAuthToken: 'your-admin-token',
cacheFunction: 'mastra/cache:handle',
})
Server cacheServer cache的直接链接
ConvexServerCache implements Mastra's server cache contract with Convex. Use it when you want durable cache state for features such as resumable durable-agent streams, workflow stream replay, or response caching.
ConvexServerCache stores list entries as separate Convex documents. This avoids growing a stream replay list inside one document and helps stay within Convex's record size limit.
Each scalar cache value and each list item is stored as one Convex row and must stay within Convex's row-size limits. Very large lists are still bounded by Convex query limits when replaying a range.
Cache cleanup and clear() run in bounded batches. A single client call can loop through up to 1,000 Convex mutations, with each mutation handling up to 25 list items. While clear() is cleaning a key, reads for that key can return empty results until cleanup finishes.
For very large cache namespaces, clear incrementally or use narrower prefixes to avoid long-running cleanup operations.
During batched cleanup, cache metadata can temporarily use an internal deleted state. The next cleanup pass removes those rows. Avoid writing new values with the same prefix until clear() finishes.
clear() only removes rows whose stored keyPrefix exactly matches the configured keyPrefix. It doesn't clear nested prefixes by string prefix matching. Each listPush() refreshes the list TTL using the cache's configured ttlMs.
Use a non-empty keyPrefix unless you intentionally want clear() to remove every cache key in the deployment. Expired list rows are reclaimed incrementally during reads and writes. clear() removes all rows for the prefix.
ConvexServerCache works best for durable replay of moderate-frequency events. For high-frequency token streams, prefer batching events or using a lower-latency cache backend.
ConvexServerCache doesn't replace a distributed pub/sub transport. If your app needs live cross-process event delivery, configure a production pub/sub backend separately.
Additional notesAdditional notes的直接链接
Schema ManagementSchema Management的直接链接
The storage implementation uses typed Convex tables for each Mastra domain:
| Domain | Convex Table | Purpose |
|---|---|---|
| Threads | mastra_threads | Conversation threads |
| Messages | mastra_messages | Chat messages |
| Resources | mastra_resources | User working memory |
| Observational Memory | mastra_observational_memory | Observational memory generations |
| Workflows | mastra_workflow_snapshots | Workflow state |
| Scorers | mastra_scorers | Evaluation data |
| Cache | mastra_cache | Cache values, counters, and list metadata |
| Cache Items | mastra_cache_list_items | Cache list entries |
| Fallback | mastra_documents | Unknown tables |
Observational memoryObservational memory的直接链接
ConvexStore supports observational memory. Add mastraObservationalMemoryTable to your Convex schema and redeploy with npx convex deploy to enable it. Existing deployments created before this table was added need the same schema update.
ArchitectureArchitecture的直接链接
All typed tables include:
- An
idfield for Mastra's record ID (distinct from Convex's auto-generated_id) - A
by_record_idindex for efficient lookups by Mastra ID
This design ensures compatibility with Mastra's storage contract while using Convex's automatic indexing and real-time capabilities.
Environment variablesEnvironment variables的直接链接
Set these environment variables for your deployment:
CONVEX_URL: Your Convex deployment URLCONVEX_ADMIN_KEY: Admin authentication token (get from Convex dashboard)