
Product
Introducing Repository Access Permissions and Custom Roles
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.
@mastra/dsql
Advanced tools
Affected versions:
Amazon Aurora DSQL storage implementation for Mastra, providing thread, message, workflow, and observability storage using Aurora DSQL with IAM authentication.
Note
Aurora DSQL doesn’t support PostgreSQL extensions (CREATE EXTENSION), includingpgvector.
For vector storage, use a separate vector store like@mastra/s3vectors.
npm install @mastra/dsql
import { DSQLStore } from '@mastra/dsql';
const store = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
// region is auto-detected from host, or specify explicitly:
// region: 'us-east-1',
// user: 'admin', // default
// database: 'postgres', // default
});
// Initialize the store (creates tables if needed)
await store.init();
// Create a thread
await store.saveThread({
thread: {
id: 'thread-123',
resourceId: 'resource-456',
title: 'My Thread',
metadata: { key: 'value' },
createdAt: new Date(),
},
});
// Add messages to thread
await store.saveMessages({
messages: [
{
id: 'msg-789',
threadId: 'thread-123',
role: 'user',
content: { content: 'Hello' },
resourceId: 'resource-456',
createdAt: new Date(),
},
],
});
// Query threads and messages
const savedThread = await store.getThreadById({ threadId: 'thread-123' });
const messages = await store.listMessages({ threadId: 'thread-123' });
DSQLStore supports multiple connection methods:
1. Host Configuration (Recommended)
import { DSQLStore } from '@mastra/dsql';
const store = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
// region is auto-detected from host, or specify explicitly
// user: 'admin', // default
// database: 'postgres', // default
schemaName: 'custom_schema', // optional
});
2. Pre-configured pg.Pool
import { Pool } from 'pg';
import { AuroraDSQLClient } from '@aws/aurora-dsql-node-postgres-connector';
import { DSQLStore } from '@mastra/dsql';
const pool = new Pool({
host: 'abc123.dsql.us-east-1.on.aws',
Client: AuroraDSQLClient,
region: 'us-east-1',
});
const store = new DSQLStore({
id: 'my-dsql-store',
pool,
});
// Use store.pool for other libraries that need a pg.Pool
import { DSQLStore } from '@mastra/dsql';
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
const store = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
customCredentialsProvider: fromNodeProviderChain(),
});
const store = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
// Connection pool settings
max: 10, // maximum connections (default: 10)
min: 0, // minimum connections (default: 0)
idleTimeoutMillis: 600000, // 10 minutes (default)
maxLifetimeSeconds: 3300, // 55 minutes (default, must be < 3600)
connectionTimeoutMillis: 5000, // 5 seconds (default)
allowExitOnIdle: true, // default: true
});
| Option | Type | Default | Description |
|---|---|---|---|
id | string | (required) | Unique identifier for this store instance |
host | string | (required)* | DSQL cluster endpoint (e.g., abc123.dsql.us-east-1.on.aws) |
pool | pg.Pool | - | Pre-configured pg.Pool instance (cannot be used with host) |
user | string | 'admin' | Database user (Aurora DSQL built-in admin role is admin) |
database | string | 'postgres' | Database name (Aurora DSQL exposes a single built-in database named postgres per cluster) |
region | string | (auto-detected) | AWS region, extracted from host if not provided |
schemaName | string | 'public' | PostgreSQL schema name where Mastra tables/indexes are created |
customCredentialsProvider | AwsCredentialIdentityProvider | (default chain) | Custom AWS credentials provider |
max | number | 10 | Maximum connections in the pool |
min | number | 0 | Minimum connections in the pool |
idleTimeoutMillis | number | 600000 | Close idle connections after this many milliseconds |
maxLifetimeSeconds | number | 3300 | Maximum connection lifetime in seconds (must be < 3600 due to Aurora DSQL’s 60-minute connection limit) |
connectionTimeoutMillis | number | 5000 | Connection acquisition timeout in milliseconds |
allowExitOnIdle | boolean | true | Allow the process to exit when all connections are idle |
* Either host or pool is required.
The default pool settings are optimized for Aurora DSQL:
The maxLifetimeSeconds is set to 55 minutes to ensure connections are rotated before Aurora DSQL's 60-minute connection duration limit.
@mastra/dsql is built on top of Amazon Aurora DSQL using the official Node.js connector.
You usually interact with it like any other Mastra store, but there are some important Aurora DSQL characteristics to be aware of:
IAM-only authentication
@mastra/dsql uses @aws/aurora-dsql-node-postgres-connector to generate short-lived auth tokens automatically.customCredentialsProvider.Single database, schema-based isolation
postgres (no CREATE DATABASE).schemaName controls where Mastra tables are created.admin, optionally create an application schema, then connect as a non-admin role using that schema.No PostgreSQL extensions
CREATE EXTENSION is not supported (including pgvector, PostGIS, etc.).@mastra/s3vectors) alongside DSQLStore.JSON stored as text
@mastra/dsql stores structured fields (metadata, content, etc.) in TEXT columns and casts to JSON at query time as needed.Schema & DDL constraints
TRUNCATE, synchronous CREATE INDEX).CREATE INDEX ASYNC; there is a limit on the number of indexes per table.init() and index helper APIs are implemented to respect these constraints.Transactions & optimistic concurrency
Connection lifetime
maxLifetimeSeconds: 3300 ensures connections are recycled before hitting this limit.saveThread({ thread }): Create or update a threadgetThreadById({ threadId }): Get a thread by IDupdateThread({ id, title, metadata }): Update thread title and/or metadatadeleteThread({ threadId }): Delete a thread and its messageslistThreadsByResourceId({ resourceId, offset, limit, orderBy? }): List paginated threads for a resourcesaveMessages({ messages }): Save multiple messages in a transactionlistMessages({ threadId, resourceId?, perPage?, page?, orderBy?, filter? }): Get messages for a thread with paginationlistMessagesById({ messageIds }): Get specific messages by their IDsupdateMessages({ messages }): Update existing messagesdeleteMessages(messageIds): Delete specific messagesgetResourceById({ resourceId }): Get a resource by IDsaveResource({ resource }): Create or save a resourceupdateResource({ resourceId, workingMemory?, metadata? }): Update resource working memory and/or metadatapersistWorkflowSnapshot({ workflowName, runId, snapshot }): Save workflow stateloadWorkflowSnapshot({ workflowName, runId }): Load workflow statelistWorkflowRuns({ workflowName, pagination }): List workflow runs with paginationgetWorkflowRunById({ workflowName, runId }): Get a specific workflow runupdateWorkflowState({ workflowName, runId, state }): Update workflow stateupdateWorkflowResults({ workflowName, runId, results }): Update workflow resultscreateSpan(span): Create a single spanbatchCreateSpans({ records }): Create multiple spansupdateSpan({ traceId, spanId, updates }): Update a spanbatchUpdateSpans({ records }): Update multiple spansgetTrace(traceId): Get a trace by IDgetTracesPaginated({ ...filters, pagination }): Get paginated traces with filteringbatchDeleteTraces({ traceIds }): Delete multiple tracesgetScoreById({ id }): Get a score by IDsaveScore(score): Save an evaluation scorelistScoresByScorerId({ scorerId, pagination }): List scores by scorer with paginationlistScoresByRunId({ runId, pagination }): List scores by run with paginationlistScoresByEntityId({ entityId, entityType, pagination }): List scores by entity with paginationlistScoresBySpan({ traceId, spanId, pagination }): List scores by span with paginationThe store creates performance indexes during initialization for common query patterns:
mastra_threads_resourceid_createdat_idx: (resourceId, createdAt)mastra_messages_thread_id_createdat_idx: (thread_id, createdAt)mastra_ai_spans_traceid_startedat_idx: (traceId, startedAt)mastra_ai_spans_parentspanid_startedat_idx: (parentSpanId, startedAt)mastra_ai_spans_name_idx: (name)mastra_ai_spans_spantype_startedat_idx: (spanType, startedAt)mastra_scores_trace_id_span_id_created_at_idx: (traceId, spanId, createdAt)Notes:
CREATE INDEX ASYNC.init(). The store will continue to function without them, but queries may be slower until index creation completes.Create additional indexes to optimize specific query patterns:
await store.createIndex({
name: 'idx_threads_resource',
table: 'mastra_threads',
columns: ['resourceId'],
});
await store.createIndex({
name: 'idx_messages_composite',
table: 'mastra_messages',
columns: ['thread_id', 'createdAt'],
});
Under the hood:
createIndex uses CREATE INDEX ASYNC.ASC/DESC in CREATE INDEX ASYNC, so columns should be plain column names.// List all indexes
const allIndexes = await store.listIndexes();
// List indexes for a specific table
const threadIndexes = await store.listIndexes('mastra_threads');
// Get detailed statistics for an index
const stats = await store.describeIndex('idx_threads_resource');
console.log(stats);
// {
// name: 'idx_threads_resource',
// table: 'mastra_threads',
// columns: ['resourceId'],
// unique: false,
// size: '128 KB',
// definition: 'CREATE INDEX idx_threads_resource...',
// method: 'btree',
// scans: 1542,
// tuples_read: 45230,
// tuples_fetched: 12050
// }
// Drop an index
await store.dropIndex('idx_threads_status');
name (required): Index nametable (required): Table namecolumns (required): Array of column names (ASC/DESC automatically stripped for Aurora DSQL)unique: Create unique index (default: false)concurrent: Ignored in Aurora DSQL (indexes are always async)where: Partial index conditionmethod: Ignored in Aurora DSQL (only btree supported)FAQs
Amazon Aurora DSQL storage provider for Mastra
The npm package @mastra/dsql receives a total of 1,086 weekly downloads. As such, @mastra/dsql popularity was classified as popular.
We found that @mastra/dsql demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.

Product
Socket Firewall blocks malicious VS Code and Open VSX extensions before install, protecting developers from compromised editor marketplaces.