---
title: "Reference: Cloudflare D1 Storage | Storage"
description: Documentation for the Cloudflare D1 SQL storage implementation in Mastra.
packages:
  - "@mastra/cloudflare-d1"
  - "@mastra/core"
---

# Cloudflare D1 Storage

The Cloudflare D1 storage implementation provides a serverless SQL database solution using Cloudflare D1, supporting relational operations and transactional consistency.

## Installation

```bash
npm install @mastra/cloudflare-d1@beta
```

## Usage

```typescript
import { D1Store } from "@mastra/cloudflare-d1";

type Env = {
  // Add your bindings here, e.g. Workers KV, D1, Workers AI, etc.
  D1Database: D1Database;
};

// --- Example 1: Using Workers Binding ---
const storageWorkers = new D1Store({
  binding: D1Database, // D1Database binding provided by the Workers runtime
  tablePrefix: "dev_", // Optional: isolate tables per environment
});

// --- Example 2: Using REST API ---
const storageRest = new D1Store({
  accountId: process.env.CLOUDFLARE_ACCOUNT_ID!, // Cloudflare Account ID
  databaseId: process.env.CLOUDFLARE_D1_DATABASE_ID!, // D1 Database ID
  apiToken: process.env.CLOUDFLARE_API_TOKEN!, // Cloudflare API Token
  tablePrefix: "dev_", // Optional: isolate tables per environment
});
```

And add the following to your `wrangler.toml` or `wrangler.jsonc` file:

```
[[d1_databases]]
binding = "D1Database"
database_name = "db-name"
database_id = "db-id"
```

## Parameters

<PropertiesTable
  content={[
    {
      name: "binding",
      type: "D1Database",
      description: "Cloudflare D1 Workers binding (for Workers runtime)",
      isOptional: true,
    },
    {
      name: "accountId",
      type: "string",
      description: "Cloudflare Account ID (for REST API)",
      isOptional: true,
    },
    {
      name: "databaseId",
      type: "string",
      description: "Cloudflare D1 Database ID (for REST API)",
      isOptional: true,
    },
    {
      name: "apiToken",
      type: "string",
      description: "Cloudflare API Token (for REST API)",
      isOptional: true,
    },
    {
      name: "tablePrefix",
      type: "string",
      description:
        "Optional prefix for all table names (useful for environment isolation)",
      isOptional: true,
    },
  ]}
/>

## Additional Notes

### Schema Management

The storage implementation handles schema creation and updates automatically. It creates the following tables:

- `threads`: Stores conversation threads
- `messages`: Stores individual messages
- `metadata`: Stores additional metadata for threads and messages

### Initialization

When you pass storage to the Mastra class, `init()` is called automatically before any storage operation:

```typescript
import { Mastra } from "@mastra/core";
import { D1Store } from "@mastra/cloudflare-d1";

const storage = new D1Store({
  binding: D1Database,
});

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

If you're using storage directly without Mastra, you must call `init()` explicitly to create the tables:

```typescript
import { D1Store } from "@mastra/cloudflare-d1";

const storage = new D1Store({
  id: 'd1-storage',
  binding: D1Database,
});

// Required when using storage directly
await storage.init();

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

:::warning
If `init()` is not called, tables won't be created and storage operations will fail silently or throw errors.
:::

### Transactions & Consistency

Cloudflare D1 provides transactional guarantees for single-row operations. This means that multiple operations can be executed as a single, all-or-nothing unit of work.

### Table Creation & Migrations

Tables are created automatically when storage is initialized (and can be isolated per environment using the `tablePrefix` option), but advanced schema changes—such as adding columns, changing data types, or modifying indexes—require manual migration and careful planning to avoid data loss.
