Skip to content

Capacity and sharding

Database starts with one logical SQL store. Capacity controls how that store is backed by Cloudflare D1 resources.

Use fixed for one D1 shard:

Terminal window
const database = db({
name: "main",
capacity: {
mode: "fixed",
},
sql: "create table posts (id text primary key, title text not null);",
})

You can omit capacity for the same starting shape. This is the default for most apps.

Use manual when you know the target shard count:

Terminal window
const database = db({
name: "main",
capacity: {
mode: "manual",
targetShardCount: 8,
},
sharding: {
tables: [
{ name: "events", keyColumn: "tenantId" },
{ name: "event_items", keyColumn: "tenantId" },
],
},
sql: `
create table if not exists events (
id text primary key,
tenantId text not null,
type text not null,
createdAt text not null
);
`,
})

targetShardCount must be a power of two from 1 to 64.

Use auto to declare an automatic expansion policy:

Terminal window
const database = db({
name: "main",
capacity: {
mode: "auto",
targetShardCount: 1,
maxShardCount: 16,
},
sharding: {
tables: [
{ name: "events", keyColumn: "tenantId" },
],
},
sql: "create table events (id text primary key, tenantId text not null);",
})

Layeron records the policy in the Database product metadata. The route API stays the same as capacity changes.

[!NOTE] Auto capacity does not automatically expand shards yet. Automatic expansion is currently under development and testing.

A good shard key is:

  • Stable for the lifetime of the row.
  • Present in common reads and writes.
  • High-cardinality enough to distribute load.
  • Part of the natural ownership model.

Tenant IDs, account IDs, workspace IDs, user IDs, and object owner IDs are common choices.

When a sharded statement targets one logical partition, pass the shard key:

Terminal window
await database.sql({
statement: "update events set type = ? where tenantId = ? and id = ?",
params: [type, tenantId, eventId],
shard: {
table: "events",
key: tenantId,
},
}).run()

The hint tells Database which logical partition the statement targets.

A one-shard database and a multi-shard database use the same Database Product boundary. Plan sharding policy before expanding to multiple shards, then keep route code carrying the key needed for routing.