Skip to main content
Mastra 1.0 is available 🎉 Read announcement

DynamoDB Storage

The DynamoDB storage implementation provides a scalable and performant NoSQL database solution for Mastra, leveraging a single-table design pattern with ElectroDB.

Features
Direct link to Features

  • Efficient single-table design for all Mastra storage needs
  • Based on ElectroDB for type-safe DynamoDB access
  • Support for AWS credentials, regions, and endpoints
  • Compatible with AWS DynamoDB Local for development
  • Stores Thread, Message, Trace, Eval, and Workflow data
  • Optimized for serverless environments
  • Configurable TTL (Time To Live) for automatic data expiration per entity type

Installation
Direct link to Installation

npm install @mastra/dynamodb@latest

Prerequisites
Direct link to Prerequisites

Before using this package, you must create a DynamoDB table with a specific structure, including primary keys and Global Secondary Indexes (GSIs). This adapter expects the DynamoDB table and its GSIs to be provisioned externally.

Detailed instructions for setting up the table using AWS CloudFormation or AWS CDK are available in TABLE_SETUP.md. Please ensure your table is configured according to those instructions before proceeding.

Usage
Direct link to Usage

Basic Usage
Direct link to Basic Usage

import { Memory } from "@mastra/memory";
import { DynamoDBStore } from "@mastra/dynamodb";

// Initialize the DynamoDB storage
const storage = new DynamoDBStore({
id: "dynamodb", // Unique identifier for this storage instance
config: {
tableName: "mastra-single-table", // Name of your DynamoDB table
region: "us-east-1", // Optional: AWS region, defaults to 'us-east-1'
// endpoint: "http://localhost:8000", // Optional: For local DynamoDB
// credentials: { accessKeyId: "YOUR_ACCESS_KEY", secretAccessKey: "YOUR_SECRET_KEY" } // Optional
},
});

// Example: Initialize Memory with DynamoDB storage
const memory = new Memory({
storage,
options: {
lastMessages: 10,
},
});

Local Development with DynamoDB Local
Direct link to Local Development with DynamoDB Local

For local development, you can use DynamoDB Local.

  1. Run DynamoDB Local (e.g., using Docker):

    docker run -p 8000:8000 amazon/dynamodb-local
  2. Configure DynamoDBStore to use the local endpoint:

    import { DynamoDBStore } from "@mastra/dynamodb";

    const storage = new DynamoDBStore({
    id: "dynamodb-local",
    config: {
    tableName: "mastra-single-table", // Ensure this table is created in your local DynamoDB
    region: "localhost", // Can be any string for local, 'localhost' is common
    endpoint: "http://localhost:8000",
    // For DynamoDB Local, credentials are not typically required unless configured.
    // If you've configured local credentials:
    // credentials: { accessKeyId: "fakeMyKeyId", secretAccessKey: "fakeSecretAccessKey" }
    },
    });

    You will still need to create the table and GSIs in your local DynamoDB instance, for example, using the AWS CLI pointed to your local endpoint.

Parameters
Direct link to Parameters

id:

string
Unique identifier for this storage instance.

config.tableName:

string
The name of your DynamoDB table.

config.region?:

string
AWS region. Defaults to 'us-east-1'. For local development, can be set to 'localhost' or similar.

config.endpoint?:

string
Custom endpoint for DynamoDB (e.g., 'http://localhost:8000' for local development).

config.credentials?:

object
AWS credentials object with `accessKeyId` and `secretAccessKey`. If not provided, the AWS SDK will attempt to source credentials from environment variables, IAM roles (e.g., for EC2/Lambda), or the shared AWS credentials file.

config.ttl?:

object
TTL (Time To Live) configuration for automatic data expiration. Configure per entity type: thread, message, trace, eval, workflow_snapshot, resource, score. Each entity config includes: enabled (boolean), attributeName (string, default: 'ttl'), defaultTtlSeconds (number).

TTL (Time To Live) Configuration
Direct link to TTL (Time To Live) Configuration

DynamoDB TTL allows you to automatically delete items after a specified time period. This is useful for:

  • Cost optimization: Automatically remove old data to reduce storage costs
  • Data lifecycle management: Implement retention policies for compliance
  • Performance: Prevent tables from growing indefinitely
  • Privacy compliance: Automatically purge personal data after specified periods

Enabling TTL
Direct link to Enabling TTL

To use TTL, you must:

  1. Configure TTL in DynamoDBStore (shown below)
  2. Enable TTL on your DynamoDB table via AWS Console or CLI, specifying the attribute name (default: ttl)
import { DynamoDBStore } from "@mastra/dynamodb";

const storage = new DynamoDBStore({
name: "dynamodb",
config: {
tableName: "mastra-single-table",
region: "us-east-1",
ttl: {
// Messages expire after 30 days
message: {
enabled: true,
defaultTtlSeconds: 30 * 24 * 60 * 60, // 30 days
},
// Threads expire after 90 days
thread: {
enabled: true,
defaultTtlSeconds: 90 * 24 * 60 * 60, // 90 days
},
// Traces expire after 7 days with custom attribute name
trace: {
enabled: true,
attributeName: "expiresAt", // Custom TTL attribute
defaultTtlSeconds: 7 * 24 * 60 * 60, // 7 days
},
// Workflow snapshots don't expire
workflow_snapshot: {
enabled: false,
},
},
},
});

Supported Entity Types
Direct link to Supported Entity Types

TTL can be configured for these entity types:

EntityDescription
threadConversation threads
messageMessages within threads
traceObservability traces
evalEvaluation results
workflow_snapshotWorkflow state snapshots
resourceUser/resource data
scoreScoring results

TTL Entity Configuration
Direct link to TTL Entity Configuration

Each entity type accepts the following configuration:

enabled:

boolean
Whether TTL is enabled for this entity type.

attributeName?:

string
The DynamoDB attribute name to use for TTL. Must match the TTL attribute configured on your DynamoDB table. Defaults to 'ttl'.

defaultTtlSeconds?:

number
Default TTL in seconds from item creation time. Items will be automatically deleted by DynamoDB after this duration.

Enabling TTL on Your DynamoDB Table
Direct link to Enabling TTL on Your DynamoDB Table

After configuring TTL in your code, you must enable TTL on the DynamoDB table itself:

Using AWS CLI:

aws dynamodb update-time-to-live \
--table-name mastra-single-table \
--time-to-live-specification "Enabled=true, AttributeName=ttl"

Using AWS Console:

  1. Go to the DynamoDB console
  2. Select your table
  3. Go to "Additional settings" tab
  4. Under "Time to Live (TTL)", click "Manage TTL"
  5. Enable TTL and specify the attribute name (default: ttl)

Note: DynamoDB deletes expired items within 48 hours after expiration. Items remain queryable until actually deleted.

AWS IAM Permissions
Direct link to AWS IAM Permissions

The IAM role or user executing the code needs appropriate permissions to interact with the specified DynamoDB table and its indexes. Below is a sample policy. Replace ${YOUR_TABLE_NAME} with your actual table name and ${YOUR_AWS_REGION} and ${YOUR_AWS_ACCOUNT_ID} with appropriate values.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchGetItem",
"dynamodb:BatchWriteItem"
],
"Resource": [
"arn:aws:dynamodb:${YOUR_AWS_REGION}:${YOUR_AWS_ACCOUNT_ID}:table/${YOUR_TABLE_NAME}",
"arn:aws:dynamodb:${YOUR_AWS_REGION}:${YOUR_AWS_ACCOUNT_ID}:table/${YOUR_TABLE_NAME}/index/*"
]
}
]
}

Key Considerations
Direct link to Key Considerations

Before diving into the architectural details, keep these key points in mind when working with the DynamoDB storage adapter:

  • External Table Provisioning: This adapter requires you to create and configure the DynamoDB table and its Global Secondary Indexes (GSIs) yourself, prior to using the adapter. Follow the guide in TABLE_SETUP.md.
  • Single-Table Design: All Mastra data (threads, messages, etc.) is stored in one DynamoDB table. This is a deliberate design choice optimized for DynamoDB, differing from relational database approaches.
  • Understanding GSIs: Familiarity with how the GSIs are structured (as per TABLE_SETUP.md) is important for understanding data retrieval and potential query patterns.
  • ElectroDB: The adapter uses ElectroDB to manage interactions with DynamoDB, providing a layer of abstraction and type safety over raw DynamoDB operations.

Architectural Approach
Direct link to Architectural Approach

This storage adapter utilizes a single-table design pattern leveraging ElectroDB, a common and recommended approach for DynamoDB. This differs architecturally from relational database adapters (like @mastra/pg or @mastra/libsql) that typically use multiple tables, each dedicated to a specific entity (threads, messages, etc.).

Key aspects of this approach:

  • DynamoDB Native: The single-table design is optimized for DynamoDB's key-value and query capabilities, often leading to better performance and scalability compared to mimicking relational models.
  • External Table Management: Unlike some adapters that might offer helper functions to create tables via code, this adapter expects the DynamoDB table and its associated Global Secondary Indexes (GSIs) to be provisioned externally before use. Please refer to TABLE_SETUP.md for detailed instructions using tools like AWS CloudFormation or CDK. The adapter focuses solely on interacting with the pre-existing table structure.
  • Consistency via Interface: While the underlying storage model differs, this adapter adheres to the same MastraStorage interface as other adapters, ensuring it can be used interchangeably within the Mastra Memory component.

Mastra Data in the Single Table
Direct link to Mastra Data in the Single Table

Within the single DynamoDB table, different Mastra data entities (such as Threads, Messages, Traces, Evals, and Workflows) are managed and distinguished using ElectroDB. ElectroDB defines specific models for each entity type, which include unique key structures and attributes. This allows the adapter to store and retrieve diverse data types efficiently within the same table.

For example, a Thread item might have a primary key like THREAD#<threadId>, while a Message item belonging to that thread might use THREAD#<threadId> as a partition key and MESSAGE#<messageId> as a sort key. The Global Secondary Indexes (GSIs), detailed in TABLE_SETUP.md, are strategically designed to support common access patterns across these different entities, such as fetching all messages for a thread or querying traces associated with a particular workflow.

Advantages of Single-Table Design
Direct link to Advantages of Single-Table Design

This implementation uses a single-table design pattern with ElectroDB, which offers several advantages within the context of DynamoDB:

  1. Lower cost (potentially): Fewer tables can simplify Read/Write Capacity Unit (RCU/WCU) provisioning and management, especially with on-demand capacity.
  2. Better performance: Related data can be co-located or accessed efficiently through GSIs, enabling fast lookups for common access patterns.
  3. Simplified administration: Fewer distinct tables to monitor, back up, and manage.
  4. Reduced complexity in access patterns: ElectroDB helps manage the complexity of item types and access patterns on a single table.
  5. Transaction support: DynamoDB transactions can be used across different "entity" types stored within the same table if needed.