Skip to main content

Memory with Postgres

This example demonstrates how to use Mastra's memory system with PostgreSQL as the storage backend.

Prerequisites

This example uses the openai model and requires a PostgreSQL database with the pgvector extension. Make sure to add the following to your .env file:

OPENAI_API_KEY=<your-api-key>
DATABASE_URL=<your-connection-string>

And install the following package:

npm install @mastra/pg

Adding memory to an agent

To add PostgreSQL memory to an agent use the Memory class and create a new storage key using PostgresStore. The connectionString can either be a remote location, or a local database connection.

import { Memory } from "@mastra/memory";
import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";
import { PostgresStore } from "@mastra/pg";

export const pgAgent = new Agent({
name: "pg-agent",
instructions:
"You are an AI agent with the ability to automatically recall memories from previous interactions.",
model: openai("gpt-4o"),
memory: new Memory({
storage: new PostgresStore({
connectionString: process.env.DATABASE_URL!,
}),
options: {
threads: {
generateTitle: true,
},
},
}),
});

Local embeddings with fastembed

Embeddings are numeric vectors used by memory’s semanticRecall to retrieve related messages by meaning (not keywords). This setup uses @mastra/fastembed to generate vector embeddings.

Install fastembed to get started:

npm install @mastra/fastembed

Add the following to your agent:

import { Memory } from "@mastra/memory";
import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";
import { PostgresStore, PgVector } from "@mastra/pg";
import { fastembed } from "@mastra/fastembed";

export const pgAgent = new Agent({
name: "pg-agent",
instructions:
"You are an AI agent with the ability to automatically recall memories from previous interactions.",
model: openai("gpt-4o"),
memory: new Memory({
storage: new PostgresStore({
connectionString: process.env.DATABASE_URL!,
}),
vector: new PgVector({
connectionString: process.env.DATABASE_URL!,
}),
embedder: fastembed,
options: {
lastMessages: 10,
semanticRecall: {
topK: 3,
messageRange: 2,
},
},
}),
});

Usage example

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.

import "dotenv/config";

import { mastra } from "./mastra";

const threadId = "123";
const resourceId = "user-456";

const agent = mastra.getAgent("pgAgent");

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);
}