docs/src/content/en/reference/storage/cloudflare.mdx
Mastra provides two Cloudflare storage implementations:
CloudflareKVStorage) - A globally distributed, eventually consistent key-value storeCloudflareDOStorage) - A strongly consistent, SQLite-based storage using Durable Objects:::warning[Observability Not Supported]
Cloudflare storage does not support the observability domain. Traces from the DefaultExporter cannot be persisted, and Mastra Studio's observability features won't work with Cloudflare as your only storage provider. To enable observability, use composite storage to route observability data to a supported provider like ClickHouse or PostgreSQL.
:::
npm install @mastra/cloudflare@latest
The KV storage implementation provides a globally distributed, serverless key-value store solution using Cloudflare Workers KV.
import { CloudflareKVStorage } from '@mastra/cloudflare/kv'
// --- Example 1: Using Workers Binding ---
const storageWorkers = new CloudflareKVStorage({
id: 'cloudflare-workers-storage',
bindings: {
threads: THREADS_KV, // KVNamespace binding for threads table
messages: MESSAGES_KV, // KVNamespace binding for messages table
// Add other tables as needed
},
keyPrefix: 'dev_', // Optional: isolate keys per environment
})
// --- Example 2: Using REST API ---
const storageRest = new CloudflareKVStorage({
id: 'cloudflare-rest-storage',
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!, // Cloudflare Account ID
apiToken: process.env.CLOUDFLARE_API_TOKEN!, // Cloudflare API Token
namespacePrefix: 'dev_', // Optional: isolate namespaces per environment
})
<PropertiesTable content={[ { name: 'id', type: 'string', description: 'Unique identifier for this storage instance.', isOptional: false, }, { name: 'bindings', type: 'Record<string, KVNamespace>', description: 'Cloudflare Workers KV bindings (for Workers runtime)', isOptional: true, }, { name: 'accountId', type: 'string', description: 'Cloudflare Account ID (for REST API)', isOptional: true, }, { name: 'apiToken', type: 'string', description: 'Cloudflare API Token (for REST API)', isOptional: true, }, { name: 'namespacePrefix', type: 'string', description: 'Optional prefix for all namespace names (useful for environment isolation)', isOptional: true, }, { name: 'keyPrefix', type: 'string', description: 'Optional prefix for all keys (useful for environment isolation)', isOptional: true, }, ]} />
The storage implementation handles schema creation and updates automatically. It creates the following tables:
threads: Stores conversation threadsmessages: Stores individual messagesmetadata: Stores additional metadata for threads and messagesCloudflare KV is an eventually consistent store, meaning that data may not be immediately available across all regions after a write.
Keys in Cloudflare KV are structured as a combination of a configurable prefix and a table-specific format (e.g., threads:threadId).
For Workers deployments, keyPrefix is used to isolate data within a namespace; for REST API deployments, namespacePrefix is used to isolate entire namespaces between environments or applications.
The Durable Objects storage implementation provides strongly consistent, SQLite-based storage using Cloudflare Durable Objects. This is ideal for applications that require transactional consistency and SQL query capabilities.
import { DurableObject } from 'cloudflare:workers'
import { CloudflareDOStorage } from '@mastra/cloudflare/do'
class AgentDurableObject extends DurableObject<Env> {
private storage: CloudflareDOStorage
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env)
this.storage = new CloudflareDOStorage({
sql: ctx.storage.sql,
tablePrefix: 'mastra_', // Optional: prefix for table names
})
}
async run() {
const memory = await this.storage.getStore('memory')
await memory?.saveThread({
thread: { id: 'thread-1', resourceId: 'user-1', title: 'Chat', metadata: {} },
})
}
}
<PropertiesTable content={[ { name: 'sql', type: 'SqlStorage', description: 'SqlStorage instance from Durable Objects ctx.storage.sql', isOptional: false, }, { name: 'tablePrefix', type: 'string', description: 'Optional prefix for table names (only letters, numbers, and underscores allowed)', isOptional: true, }, { name: 'disableInit', type: 'boolean', description: 'When true, automatic table creation/migrations are disabled. Useful for CI/CD pipelines where migrations run separately.', isOptional: true, }, ]} />
Unlike KV, Durable Objects provide strong consistency guarantees. All reads and writes within a Durable Object are serialized, making it very suitable for fast, long-running agents.
Durable Objects storage uses SQLite under the hood, enabling efficient queries, filtering, and pagination that aren't possible with key-value storage.
Both storage implementations handle schema creation and updates automatically. They create the following tables:
threads: Stores conversation threadsmessages: Stores individual messagesworkflow_snapshot: Stores workflow run stateFor backwards compatibility, the following aliases are available:
// These are deprecated - use CloudflareKVStorage and CloudflareDOStorage instead
import { CloudflareStore } from '@mastra/cloudflare/kv' // alias for CloudflareKVStorage
import { DOStore } from '@mastra/cloudflare/do' // alias for CloudflareDOStorage