# DuckDB storage [DuckDB](https://duckdb.org/) 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](https://mastra.ai/reference/vectors/duckdb), which is a separate API in the same package. ## 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](https://mastra.ai/reference/storage/libsql)) for `memory` and `workflows` in a [composite storage](https://mastra.ai/reference/storage/composite) setup. > **Warning:** 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](https://mastra.ai/reference/storage/clickhouse). ## Installation **npm**: ```bash npm install @mastra/duckdb@latest ``` **pnpm**: ```bash pnpm add @mastra/duckdb@latest ``` **Yarn**: ```bash yarn add @mastra/duckdb@latest ``` **Bun**: ```bash bun add @mastra/duckdb@latest ``` ## Usage ### As the observability domain in a composite store This is the standard local-development setup. LibSQL handles the other domains, and DuckDB handles observability. ```typescript 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: ```typescript const observability = await new DuckDBStore().getStore('observability') ``` ### Standalone When you need only observability storage outside the `Mastra` composite, instantiate `DuckDBStore` directly and access the observability domain: ```typescript import { DuckDBStore } from '@mastra/duckdb' const duckdb = new DuckDBStore({ path: './traces.duckdb' }) const observability = duckdb.observability await observability.init() ``` ### 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. ```typescript const duckdb = new DuckDBStore({ path: ':memory:' }) ``` ## Configuration ### `DuckDBStore` options **id** (`string`): Unique identifier for this storage instance. (Default: `'duckdb'`) **path** (`string`): Path to the DuckDB database file. Use \`:memory:\` for an ephemeral in-memory database. (Default: `'mastra.duckdb'`) ### 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 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](https://mastra.ai/reference/storage/libsql) for local development). ## 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: ```typescript import { DuckDBStore } from '@mastra/duckdb' const duckdb = new DuckDBStore({ path: './traces.duckdb' }) await duckdb.observability.init() ``` ## 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](https://mastra.ai/docs/observability/tracing/exporters/default). ## Related - [Storage overview](https://mastra.ai/reference/storage/overview) - [Composite storage](https://mastra.ai/reference/storage/composite) - [ClickHouse storage](https://mastra.ai/reference/storage/clickhouse): Production observability backend - [DuckDB vector store](https://mastra.ai/reference/vectors/duckdb): Vector search using the same package - [Observability overview](https://mastra.ai/docs/observability/overview)