MastraStorage
MastraStorage provides a unified interface for managing:
- Suspended Workflows: the serialized state of suspended workflows (so they can be resumed later)
- Memory: threads and messages per
resourceIdin your application - Traces: OpenTelemetry traces from all components of Mastra
- Eval Datasets: scores and scoring reasons from eval runs

Mastra provides different storage providers, but you can treat them as interchangeable. Eg, you could use libsql in development but postgres in production, and your code will work the same both ways.
Configuration
Mastra can be configured with a default storage option:
import { Mastra } from "@mastra/core";
import { LibSQLStore } from "@mastra/libsql";
const mastra = new Mastra({
storage: new LibSQLStore({
id: 'mastra-storage',
url: "file:./mastra.db",
}),
});
If you do not specify any storage configuration, Mastra will not persist data across application restarts or deployments. For any
deployment beyond local testing you should provide your own storage
configuration either on Mastra or directly within new Memory().
Data Schema
- Messages
- Threads
- Resources
- Workflows
- Evals
- Traces
Stores conversation messages and their metadata. Each message belongs to a thread and contains the actual content along with metadata about the sender role and message type.
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx){ format: 2, parts: [...] }user | assistantThe message content column contains a JSON object conforming to the MastraMessageContentV2 type, which is designed to align closely with the AI SDK UIMessage message shape.
type.Groups related messages together and associates them with a resource. Contains metadata about the conversation.
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx){
"category": "support",
"priority": 1
}Stores user-specific data for resource-scoped working memory. Each resource represents a user or entity, allowing working memory to persist across all conversation threads for that user.
{
"preferences": {
"language": "en",
"timezone": "UTC"
},
"tags": [
"premium",
"beta-user"
]
}When suspend is called on a workflow, its state is saved in the following format. When resume is called, that state is rehydrated.
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx){
"value": {
"currentState": "running"
},
"context": {
"stepResults": {},
"attempts": {},
"triggerData": {}
},
"activePaths": [],
"runId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": 1648176000000
}Stores eval results from running metrics against agent outputs.
{
"score": 0.95,
"details": {
"reason": "Response accurately reflects source material",
"citations": [
"page 1",
"page 3"
]
}
}xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)Captures OpenTelemetry traces for monitoring and debugging.
workflow.myWorkflow.execute, http.request, database.query)@mastra/core, express, pg)INTERNAL (0, within process), CLIENT (1, outgoing calls), SERVER (2, incoming calls), PRODUCER (3, async job creation), CONSUMER (4, async job processing)code (UNSET=0, ERROR=1, OK=2) and optional message. Example:{
"code": 1,
"message": "HTTP request failed with status 500"
}{
"droppedAttributesCount": 2,
"droppedEventsCount": 1,
"instrumentationLibrary": "@opentelemetry/instrumentation-http"
}Querying Messages
Messages are stored in the MastraDBMessage format, which provides a consistent structure across the entire Mastra system:
// Get messages for a thread with pagination
const result = await mastra
.getStorage()
.listMessages({
threadId: "your-thread-id",
page: 0,
perPage: 50
});
console.log(result.messages); // MastraDBMessage[]
console.log(result.total); // Total count
console.log(result.hasMore); // Whether more pages exist
// Get messages by their IDs
const messages = await mastra
.getStorage()
.listMessagesById({ messageIds: messageIdArr });
All message queries return MastraDBMessage[] format. If you need to convert messages to AI SDK formats for UI rendering, use the conversion utilities from @mastra/ai-sdk/ui:
import { toAISdkV5Messages } from '@mastra/ai-sdk/ui';
const result = await mastra
.getStorage()
.listMessages({ threadId: "your-thread-id" });
// Convert to AI SDK v5 UIMessage format for UI rendering
const uiMessages = toAISdkV5Messages(result.messages);
Storage Providers
Mastra supports the following providers:
- For local development, check out LibSQL Storage
- For production, check out PostgreSQL Storage
- For serverless deployments, check out Upstash Storage
- For document-based storage, check out MongoDB Storage