@mastra/core
Version:
Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.
150 lines (102 loc) • 5.65 kB
Markdown
[](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.
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, MastraStorageExporter } 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 MastraStorageExporter()],
},
},
}),
})
```
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')
```
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()
```
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:' })
```
**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'`)
`@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.
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()
```
DuckDB supports the `event-sourced` strategy used by `MastraStorageExporter`, which buffers spans in memory and writes completed events in batches. This is appropriate for development-scale traffic. For high-volume production workloads, see [`MastraStorageExporter` storage provider support](https://mastra.ai/docs/observability/tracing/exporters/mastra-storage).
- [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)