Skip to main content

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 resourceId in your application
  • Traces: OpenTelemetry traces from all components of Mastra
  • Eval Datasets: scores and scoring reasons from eval runs


Diagram showing storage in Mastra

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

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.


id
uuidv4
PRIMARYKEY
NOT NULL
Unique identifier for the message (format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
thread_id
uuidv4
FK → threads.id
NOT NULL
Parent thread reference
resourceId
uuidv4
CAN BE NULL
ID of the resource that owns this message
content
text
NOT NULL
JSON of the message content in V2 format. Example: { format: 2, parts: [...] }
role
text
NOT NULL
Enum of user | assistant
createdAt
timestamp
NOT NULL
Used for thread message ordering

The 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.

format
integer
NOT NULL
Message format version (currently 2)
parts
array (JSON)
NOT NULL
Array of message parts (text, tool-invocation, file, reasoning, etc.). The structure of items in this array varies by type.
experimental_attachments
array (JSON)
CAN BE NULL
Optional array of file attachments
content
text
CAN BE NULL
Optional main text content of the message
toolInvocations
array (JSON)
CAN BE NULL
Optional array summarizing tool calls and results
reasoning
object (JSON)
CAN BE NULL
Optional information about the reasoning process behind the assistant's response
annotations
object (JSON)
CAN BE NULL
Optional additional metadata or annotations

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:

On this page