Neon storage
Neon is a managed PostgreSQL service. Mastra connects to Neon through PostgresStore, which uses the Node.js pg driver. Neon doesn't require a separate Mastra storage package.
QuickstartDirect link to Quickstart
Create a Neon project, then copy its pooled connection string into DATABASE_URL.
Install the PostgreSQL storage package:
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/pg@latest
pnpm add @mastra/pg@latest
yarn add @mastra/pg@latest
bun add @mastra/pg@latest
Pass the pooled connection string to PostgresStore:
import { Mastra } from '@mastra/core/mastra'
import { PostgresStore } from '@mastra/pg'
export const mastra = new Mastra({
storage: new PostgresStore({
id: 'neon-storage',
connectionString: process.env.DATABASE_URL!,
}),
})
On startup, Mastra calls storage.init() and creates its tables and indexes in Neon.
Set up Neon with the CLIDirect link to Set up Neon with the CLI
The Neon CLI requires Node.js 20.19 or newer.
Install the Neon CLI:
- npm
- pnpm
- Yarn
- Bun
npm install -g neon
pnpm add -g neon
yarn global add neon
bun add --global neon
From your project directory, link an existing Neon project or create one:
neon link
neon link signs you in and writes project context to .neon. It also pulls the current branch's environment variables. Run neon env pull again whenever you need to refresh them:
neon env pull
The command writes DATABASE_URL and DATABASE_URL_UNPOOLED to .env.local or to .env when that file already exists.
Add neon.tsDirect link to add-neonts
To manage branch settings in the repository, create a neon.ts file:
neon config init
This installs @neon/config and @neon/env and creates a starter config. For example, the following policy expires new non-default branches after seven days:
import { defineConfig } from '@neon/config/v1'
export default defineConfig({
branch: branch => {
if (branch.isDefault) {
return {}
}
if (!branch.exists) {
return { ttl: '7d' }
}
return {}
},
})
Apply the config:
neon deploy
Install Neon agent skillsDirect link to Install Neon agent skills
Install the neon and neon-postgres agent skills from your project directory:
- npm
- pnpm
- Yarn
- Bun
npx skills add neondatabase/agent-skills --skill neon --skill neon-postgres -y
pnpm dlx skills add neondatabase/agent-skills --skill neon --skill neon-postgres -y
yarn dlx skills add neondatabase/agent-skills --skill neon --skill neon-postgres -y
bun x skills add neondatabase/agent-skills --skill neon --skill neon-postgres -y
The skills give compatible coding agents Neon setup instructions and Postgres-specific guidance.
Production connectionsDirect link to Production connections
Neon provides direct and pooled connection strings:
DATABASE_URLuses Neon's pooled endpoint. Use it for normal application traffic.DATABASE_URL_UNPOOLEDconnects directly to Postgres. Use it for administrative tasks or schema changes that run outside the application.
For most applications, use the pooled DATABASE_URL shown in the quickstart and let Mastra initialize the schema at startup. PostgresStore supports initialization through a transaction-pooled connection.
Separate schema initializationDirect link to Separate schema initialization
If the runtime database role shouldn't create tables or indexes, initialize the schema during deployment with the direct connection:
import { PostgresStore } from '@mastra/pg'
const storage = new PostgresStore({
id: 'neon-storage-init',
connectionString: process.env.DATABASE_URL_UNPOOLED!,
})
try {
await storage.init()
} finally {
await storage.close()
}
After the schema exists, use the pooled connection at runtime and disable automatic initialization:
import { Mastra } from '@mastra/core/mastra'
import { PostgresStore } from '@mastra/pg'
export const mastra = new Mastra({
storage: new PostgresStore({
id: 'neon-storage',
connectionString: process.env.DATABASE_URL!,
disableInit: true,
}),
})
See Neon connection pooling for details.
Vector searchDirect link to Vector search
Neon supports the pgvector extension. Use the direct DATABASE_URL_UNPOOLED connection while creating the extension and indexes. After setup, configure PgVector with the pooled connection for runtime queries:
import { PgVector } from '@mastra/pg'
const vector = new PgVector({
id: 'neon-vector',
connectionString: process.env.DATABASE_URL!,
disableInit: true,
})
Setting disableInit: true prevents the runtime process from creating or changing the extension, tables and indexes.