Skip to main content

Elasticsearch

The Elasticsearch storage implementation provides agent memory, workflow snapshot, and score storage on top of an Elasticsearch cluster using the official @elastic/elasticsearch client. It shares the same connection configuration as ElasticSearchVector, so a single cluster (and even a single client instance) can serve both agent memory and semantic recall.

ElasticSearchStore currently implements the memory, workflows, and scores storage domains.

Installation
Direct link to Installation

npm install @mastra/elasticsearch

Usage
Direct link to Usage

Using a URL
Direct link to Using a URL

import { ElasticSearchStore } from '@mastra/elasticsearch'

const storage = new ElasticSearchStore({
id: 'elasticsearch-storage',
url: 'http://localhost:9200',
})

await storage.init()

Using authentication
Direct link to Using authentication

import { ElasticSearchStore } from '@mastra/elasticsearch'

const storage = new ElasticSearchStore({
id: 'elasticsearch-storage',
url: 'https://my-cluster.example.com:9200',
auth: { apiKey: process.env.ELASTICSEARCH_API_KEY! },
})

auth also accepts { username, password } or { bearer }.

Using a pre-configured client
Direct link to Using a pre-configured client

For advanced configurations (cloud IDs, TLS options, custom transport), pass a pre-configured client. The same client can be shared with ElasticSearchVector:

import { Client } from '@elastic/elasticsearch'
import { ElasticSearchStore, ElasticSearchVector } from '@mastra/elasticsearch'

const client = new Client({
node: 'https://my-cluster.example.com:9200',
auth: { apiKey: process.env.ELASTICSEARCH_API_KEY! },
})

const storage = new ElasticSearchStore({ id: 'elasticsearch-storage', client })
const vector = new ElasticSearchVector({ id: 'elasticsearch-vector', client })

When you provide your own client, storage.close() does not close it — you remain responsible for its lifecycle.

Parameters
Direct link to Parameters

id:

string
Unique identifier for the storage instance

url?:

string
Elasticsearch node URL (e.g., http://localhost:9200)

auth?:

ElasticSearchAuth
Authentication options: { apiKey }, { username, password }, or { bearer }

client?:

Client
Pre-configured Elasticsearch client (from @elastic/elasticsearch) for advanced setups

disableInit?:

boolean
Disable automatic initialization; call storage.init() explicitly before use
note

You must provide either url or client. These options are mutually exclusive.

Additional Notes
Direct link to Additional Notes

Index Structure
Direct link to Index Structure

Each Mastra storage table maps to one Elasticsearch index of the same name (for example mastra_threads, mastra_messages, mastra_workflow_snapshot, mastra_scorers). Records are stored as opaque JSON documents with a keyword key field, so no index mappings need to be managed manually — indexes are created on first use.

Consistency
Direct link to Consistency

Elasticsearch search is near-real-time. All writes are performed with an immediate refresh so subsequent reads and searches observe them, and point reads use real-time get-by-ID lookups.

Closing Connections
Direct link to Closing Connections

When shutting down your application, close the connection:

await storage.close()

This only closes clients created by ElasticSearchStore from a url; user-provided clients are left open.

Usage Example
Direct link to Usage Example

Adding memory to an agent
Direct link to Adding memory to an agent

src/mastra/agents/elasticsearch-agent.ts
import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'
import { ElasticSearchStore } from '@mastra/elasticsearch'

export const elasticsearchAgent = new Agent({
id: 'elasticsearch-agent',
name: 'Elasticsearch Agent',
instructions:
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
storage: new ElasticSearchStore({
id: 'elasticsearch-agent-storage',
url: process.env.ELASTICSEARCH_URL!,
auth: { apiKey: process.env.ELASTICSEARCH_API_KEY! },
}),
options: {
lastMessages: 10,
},
}),
})

Using with Mastra instance
Direct link to Using with Mastra instance

import { Mastra } from '@mastra/core'
import { ElasticSearchStore } from '@mastra/elasticsearch'

const storage = new ElasticSearchStore({
id: 'mastra-storage',
url: 'http://localhost:9200',
})

const mastra = new Mastra({
storage, // init() called automatically
})

If using storage directly without Mastra, call init() explicitly:

import { ElasticSearchStore } from '@mastra/elasticsearch'

const storage = new ElasticSearchStore({
id: 'elasticsearch-storage',
url: 'http://localhost:9200',
})

await storage.init()

// Access domain-specific stores via getStore()
const memoryStore = await storage.getStore('memory')
const thread = await memoryStore?.getThreadById({ threadId: '...' })