Skip to main content

Overview

Threads are the primary way to organize conversations in Mastra’s memory system. Each thread represents a conversation session and can contain multiple messages, metadata, and working memory state.

Type Definition

interface StorageThreadType {
  id: string;
  title: string;
  resourceId: string;
  createdAt: Date;
  updatedAt: Date;
  metadata?: Record<string, unknown>;
}

Properties

id
string
Unique identifier for the thread
title
string
Title of the conversation thread
resourceId
string
Resource ID (e.g., user ID) associated with this thread for multi-tenant scenarios
createdAt
Date
Timestamp when the thread was created
updatedAt
Date
Timestamp when the thread was last updated
metadata
Record<string, unknown> | undefined
Optional metadata for storing additional thread information

Creating Threads

Using Memory.createThread

const thread = await memory.createThread({
  resourceId: 'user-123',
  title: 'Customer Support Conversation',
  metadata: {
    category: 'support',
    priority: 'high',
    tags: ['billing', 'refund']
  }
});

Manual Thread Creation

const thread: StorageThreadType = {
  id: 'thread-456',
  title: 'New Conversation',
  resourceId: 'user-123',
  createdAt: new Date(),
  updatedAt: new Date(),
  metadata: {
    source: 'web',
    language: 'en'
  }
};

await memory.saveThread({ thread });

Using Threads with Agents

Basic Usage

import { Agent } from '@mastra/core/agent';
import { Memory } from '@mastra/memory';

const memory = new Memory({
  name: 'conversation-memory'
});

const agent = new Agent({
  id: 'assistant',
  name: 'Assistant',
  instructions: 'You are a helpful assistant',
  model: 'openai/gpt-5',
  memory
});

// Generate with memory
const response = await agent.generate('Hello', {
  memory: {
    thread: 'thread-123',
    resource: 'user-456'
  }
});

Creating Thread on First Message

const thread = await memory.createThread({
  resourceId: 'user-123',
  title: 'Untitled',
  metadata: {
    channel: 'chat-widget'
  }
});

const response = await agent.generate('Hello', {
  memory: {
    thread: thread.id,
    resource: 'user-123'
  }
});

Listing Threads

List All Threads for a Resource

const { threads, total } = await memory.listThreads({
  filter: {
    resourceId: 'user-123'
  }
});

Filter by Metadata

const { threads } = await memory.listThreads({
  filter: {
    resourceId: 'user-123',
    metadata: {
      category: 'support',
      priority: 'high'
    }
  }
});

Pagination

const { threads, total, hasMore } = await memory.listThreads({
  filter: {
    resourceId: 'user-123'
  },
  page: 0,
  perPage: 20,
  orderBy: {
    field: 'updatedAt',
    direction: 'DESC'
  }
});

Retrieving Threads

Get Thread by ID

const thread = await memory.getThreadById({
  threadId: 'thread-123'
});

if (thread) {
  console.log('Thread title:', thread.title);
  console.log('Created:', thread.createdAt);
  console.log('Metadata:', thread.metadata);
}

Updating Threads

Update Thread Title

const thread = await memory.getThreadById({ threadId: 'thread-123' });

if (thread) {
  thread.title = 'Updated Conversation Title';
  thread.updatedAt = new Date();
  await memory.saveThread({ thread });
}

Update Thread Metadata

const thread = await memory.getThreadById({ threadId: 'thread-123' });

if (thread) {
  thread.metadata = {
    ...thread.metadata,
    status: 'resolved',
    resolvedAt: new Date().toISOString()
  };
  thread.updatedAt = new Date();
  await memory.saveThread({ thread });
}

Deleting Threads

await memory.deleteThread('thread-123');

Thread Metadata Patterns

Categorization

const thread = await memory.createThread({
  resourceId: 'user-123',
  title: 'Product Question',
  metadata: {
    category: 'product-inquiry',
    subcategory: 'features',
    tags: ['pricing', 'enterprise']
  }
});

Session Information

const thread = await memory.createThread({
  resourceId: 'user-123',
  title: 'Support Session',
  metadata: {
    sessionId: 'sess_abc123',
    channel: 'live-chat',
    agent: 'bot',
    browser: 'Chrome',
    ipAddress: '192.168.1.1'
  }
});

Conversation State

const thread = await memory.createThread({
  resourceId: 'user-123',
  title: 'Onboarding',
  metadata: {
    stage: 'setup',
    progress: 0.4,
    completedSteps: ['profile', 'preferences'],
    currentStep: 'integrations'
  }
});

Multi-language Support

const thread = await memory.createThread({
  resourceId: 'user-123',
  title: 'Customer Support',
  metadata: {
    language: 'es',
    translationEnabled: true,
    originalLanguage: 'en'
  }
});

Working with Messages

Save Messages to Thread

import type { MastraDBMessage } from '@mastra/core/agent';

const messages: MastraDBMessage[] = [
  {
    id: 'msg-1',
    threadId: 'thread-123',
    role: 'user',
    content: [{ type: 'text', text: 'Hello' }],
    type: 'text',
    createdAt: new Date(),
    resourceId: 'user-123'
  },
  {
    id: 'msg-2',
    threadId: 'thread-123',
    role: 'assistant',
    content: [{ type: 'text', text: 'Hi! How can I help?' }],
    type: 'text',
    createdAt: new Date(),
    resourceId: 'user-123'
  }
];

await memory.saveMessages({ messages });

Recall Messages from Thread

const { messages } = await memory.recall({
  threadId: 'thread-123',
  resourceId: 'user-123'
});

Cloning Threads

Some memory implementations support cloning threads with optional message filtering:
// Clone a thread with all messages
const { thread: clonedThread, clonedMessages } = await storage.cloneThread({
  sourceThreadId: 'thread-123',
  newThreadId: 'thread-456',
  resourceId: 'user-789',
  title: 'Cloned Conversation'
});

// Clone with message limit
const { thread, clonedMessages } = await storage.cloneThread({
  sourceThreadId: 'thread-123',
  options: {
    messageLimit: 10 // Only copy last 10 messages
  }
});

// Clone with date filter
const { thread, clonedMessages } = await storage.cloneThread({
  sourceThreadId: 'thread-123',
  options: {
    messageFilter: {
      startDate: new Date('2024-01-01'),
      endDate: new Date('2024-02-01')
    }
  }
});

Example: Complete Thread Lifecycle

import { Agent } from '@mastra/core/agent';
import { Memory } from '@mastra/memory';
import { LibSQLStore } from '@mastra/libsql';

const storage = new LibSQLStore({ id: 'storage', url: ':memory:' });
const memory = new Memory({
  name: 'memory',
  storage
});

const agent = new Agent({
  id: 'assistant',
  name: 'Assistant',
  instructions: 'You are a helpful assistant',
  model: 'openai/gpt-5',
  memory
});

// 1. Create a new thread
const thread = await memory.createThread({
  resourceId: 'user-123',
  title: 'Customer Support',
  metadata: {
    category: 'support',
    priority: 'normal'
  }
});

// 2. Have a conversation
const response1 = await agent.generate('Hello', {
  memory: {
    thread: thread.id,
    resource: 'user-123'
  }
});

const response2 = await agent.generate('I need help with my account', {
  memory: {
    thread: thread.id,
    resource: 'user-123'
  }
});

// 3. Update thread metadata
thread.metadata = {
  ...thread.metadata,
  status: 'in-progress',
  lastMessageAt: new Date().toISOString()
};
thread.updatedAt = new Date();
await memory.saveThread({ thread });

// 4. List all threads for the user
const { threads, total } = await memory.listThreads({
  filter: {
    resourceId: 'user-123'
  },
  orderBy: {
    field: 'updatedAt',
    direction: 'DESC'
  }
});

// 5. Recall conversation history
const { messages } = await memory.recall({
  threadId: thread.id,
  resourceId: 'user-123'
});

console.log(`Thread has ${messages.length} messages`);