DuckDB storage
DuckDB is an embedded, in-process analytical database. The @mastra/duckdb package provides an OLAP-backed observability store for local development, suitable for traces, logs, metrics, scores, and feedback without running an external service.
For vector search, see the DuckDB vector store reference, which is a separate API in the same package.
When to use DuckDBDirect link to When to use DuckDB
Local development of observability features. DuckDB is embedded and file-based, so it does not require a server and starts instantly. It supports the same observability signals as ClickHouse, which makes it useful for testing dashboards and trace exploration before deploying to a production backend.
DuckDB currently implements only the observability domain. Pair it with another storage adapter (such as LibSQL) for memory and workflows in a composite storage setup.
DuckDB is for development and not recommended for production. It runs in-process, persists to a single local file, and does not work on platforms with ephemeral filesystems (such as Railway, Fly.io, Render, Heroku, or serverless containers). For production observability, use ClickHouse.
InstallationDirect link to Installation
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/duckdb@latest
pnpm add @mastra/duckdb@latest
yarn add @mastra/duckdb@latest
bun add @mastra/duckdb@latest
UsageDirect link to Usage
As the observability domain in a composite storeDirect link to As the observability domain in a composite store
This is the standard local-development setup. LibSQL handles the other domains, and DuckDB handles observability.
import { Mastra } from '@mastra/core'
import { MastraCompositeStore } from '@mastra/core/storage'
import { LibSQLStore } from '@mastra/libsql'
import { DuckDBStore } from '@mastra/duckdb'
import { Observability, DefaultExporter } from '@mastra/observability'
export const mastra = new Mastra({
storage: new MastraCompositeStore({
id: 'composite-storage',
default: new LibSQLStore({
id: 'mastra-storage',
url: 'file:./mastra.db',
}),
domains: {
observability: new DuckDBStore().observability,
},
}),
observability: new Observability({
configs: {
default: {
serviceName: 'mastra',
exporters: [new DefaultExporter()],
},
},
}),
})
The .observability accessor returns the observability domain store directly. The equivalent generic form uses getStore(), which works for any composite-style storage adapter:
const observability = await new DuckDBStore().getStore('observability')
StandaloneDirect link to Standalone
When you need only observability storage outside the Mastra composite, instantiate DuckDBStore directly and access the observability domain:
import { DuckDBStore } from '@mastra/duckdb'
const duckdb = new DuckDBStore({ path: './traces.duckdb' })
const observability = duckdb.observability
await observability.init()
In-memory databaseDirect link to In-memory database
Pass :memory: to use an ephemeral DuckDB instance. Data is lost when the process exits, which is appropriate for unit tests and short-lived scripts.
const duckdb = new DuckDBStore({ path: ':memory:' })
ConfigurationDirect link to Configuration
DuckDBStore optionsDirect link to duckdbstore-options
id?:
path?:
Lower-level typesDirect link to Lower-level types
@mastra/duckdb also exports DuckDBConnection for sharing a single underlying database across multiple Mastra storage instances, and the corresponding DuckDBStorageConfig type. Most applications will not need these directly.
Supported domainsDirect link to Supported domains
DuckDB currently implements one storage domain:
| Domain | Supported |
|---|---|
observability | Yes |
memory | No |
workflows | No |
scores | No |
agents | No |
For a full storage solution, compose DuckDBStore with an adapter that covers the missing domains (most commonly LibSQL for local development).
InitializationDirect link to Initialization
When passed to Mastra through MastraCompositeStore, the observability domain initializes itself on first use. To run initialization explicitly outside of Mastra, call init() on the observability store:
import { DuckDBStore } from '@mastra/duckdb'
const duckdb = new DuckDBStore({ path: './traces.duckdb' })
await duckdb.observability.init()
Observability strategyDirect link to Observability strategy
DuckDB supports the event-sourced strategy used by DefaultExporter, which buffers spans in memory and writes completed events in batches. This is appropriate for development-scale traffic. For high-volume production workloads, see DefaultExporter storage provider support.
RelatedDirect link to Related
- Storage overview
- Composite storage
- ClickHouse storage: Production observability backend
- DuckDB vector store: Vector search using the same package
- Observability overview