Products · Developer platform
D1
Create managed, serverless databases with SQL semantics
Pricing and limits
Pricing
As of Nov 3, 2026, from Cloudflare's docs, last updated there Oct 30, 2026. Licensed CC BY 4.0; navigation removed.
D1 bills based on:
- Usage: Queries you run against D1 will count as rows read, rows written, or both (for transactions or batches).
- Scale-to-zero: You are not billed for hours or capacity units. If you are not running queries against your database, you are not billed for compute.
- Storage: You are only billed for storage above the included limits of your plan.
- Databases: The Workers Paid plan includes 100,000 databases per account. Each additional database costs $0.10 per month.
Billing metrics
| Workers Free | Workers Paid | |
|---|---|---|
| Rows read | 5 million / day | First 25 billion / month included + $0.001 / million rows |
| Rows written | 100,000 / day | First 50 million / month included + $1.00 / million rows |
| Storage (per GB stored) | 5 GB (total) | First 5 GB included + $0.75 / GB-mo |
| Databases | 10 | First 100,000 included + $0.10 per additional database per month. |
You pay $0.10 per month for each D1 database above the included amount, even when it is empty or receives no traffic. Usage and storage are billed separately.
Refer to D1 limits for database creation and storage limits.
Track your D1 usage
To accurately track your usage, use the meta object, GraphQL Analytics API, or the Cloudflare dashboard ↗︎. Select your D1 database, then view: Metrics > Row Metrics.
Definitions
- Rows read measure how many rows a query reads (scans), regardless of the size of each row. For example, if you have a table with 5000 rows and run a
SELECT * FROM tableas a full table scan, this would count as 5,000 rows read. A query that filters on an unindexed column may return fewer rows to your Worker, but is still required to read (scan) more rows to determine which subset to return. - Rows written measure how many rows were written to D1 database. Write operations include
INSERT,UPDATE, andDELETE. Each of these operations contribute towards rows written. A query thatINSERT10 rows into auserstable would count as 10 rows written. - DDL operations (for example,
CREATE,ALTER, andDROP) are used to define or modify the structure of a database. They may contribute to a mix of read rows and write rows. Ensure you are accurately tracking your usage through the available tools (meta object, GraphQL Analytics API, or the Cloudflare dashboard ↗︎). - Row size or the number of columns in a row does not impact how rows are counted. A row that is 1 KB and a row that is 100 KB both count as one row.
- Defining indexes on your table(s) reduces the number of rows read by a query when filtering on that indexed field. For example, if the
userstable has an index on a timestamp columncreated_at, the querySELECT * FROM users WHERE created_at > ?1would only need to read a subset of the table. - Indexes will add an additional written row when writes include the indexed column, as there are two rows written: one to the table itself, and one to the index. The performance benefit of an index and reduction in rows read will, in nearly all cases, offset this additional write.
- Storage is based on gigabytes stored per month, and is based on the sum of all databases in your account. Tables and indexes both count towards storage consumed.
- Free daily usage limits reset at 00:00 UTC. Monthly included usage resets based on your monthly subscription renewal date, which is determined by the day you first subscribed.
- There are no data transfer (egress) or throughput (bandwidth) charges for data accessed from D1.
- Read replication does not charge extra for read replicas. You incur the same usage billing based on
rows_readandrows_writtenby your queries.
Frequently Asked Questions
Frequently asked questions related to D1 pricing:
Will D1 always have a Free plan?
Yes, the Workers Free plan will always include the ability to prototype and experiment with D1 for free.
What happens if I exceed the daily limits on reads and writes, or the total storage limit, on the Free plan?
When your account hits the daily read and/or write limits, you will not be able to run queries against D1. D1 API will return errors to your client indicating that your daily limits have been exceeded. Once you have reached your included storage limit, you will need to delete unused databases or clean up stale data before you can insert new data, create or alter tables or create indexes and triggers.
Upgrading to the Workers Paid plan will remove these limits, typically within minutes.
What happens if I exceed the monthly included reads, writes and/or storage on the paid tier?
You will be billed for the additional reads, writes and storage according to D1's pricing metrics.
How can I estimate my (eventual) bill?
Every query returns a meta object that contains a total count of the rows read (rows_read) and rows written (rows_written) by that query. For example, a query that performs a full table scan (for instance, SELECT * FROM users) from a table with 5000 rows would return a rows_read value of 5000:
"meta": {
"duration": 0.20472300052642825,
"size_after": 45137920,
"rows_read": 5000,
"rows_written": 0
}
These are also included in the D1 Cloudflare dashboard ↗︎ and the analytics API, allowing you to attribute read and write volumes to specific databases, time periods, or both.
Does D1 charge for data transfer / egress?
No.
Does D1 charge additional for additional compute?
D1 itself does not charge for additional compute. Workers querying D1 and computing results: for example, serializing results into JSON and/or running queries, are billed per Workers pricing, in addition to your D1 specific usage.
Do queries I run from the dashboard or Wrangler (the CLI) count as billable usage?
Yes, any queries you run against your database, including inserting (INSERT) existing data into a new database, table scans (SELECT * FROM table), or creating indexes count as either reads or writes.
Can I use an index to reduce the number of rows read by a query?
Yes, you can use an index to reduce the number of rows read by a query. Creating indexes for your most queried tables and filtered columns reduces how much data is scanned and improves query performance at the same time. If you have a read-heavy workload (most common), this can be particularly advantageous. Writing to columns referenced in an index will add at least one (1) additional row written to account for updating the index, but this is typically offset by the reduction in rows read due to the benefits of an index.
Does a freshly created database, and/or an empty table with no rows, contribute to my storage?
Yes, although minimal. An empty table consumes at least a few kilobytes, based on the number of columns (table width) in the table. An empty database consumes approximately 12 KB of storage.
How much do additional databases cost?
The Workers Paid plan includes 100,000 databases per account. Each additional database costs $0.10 per month. Query and storage charges apply separately.
For example, 100,020 databases existing for a full billing month cost (100,020 - 100,000) × $0.10 = $2.00 for the 20 additional databases.
Limits
As of Nov 3, 2026, from Cloudflare's docs, last updated there Oct 30, 2026. Licensed CC BY 4.0; navigation removed.
| Feature | Limit |
|---|---|
| Databases per account | Workers Paid: 1,000,000. The first 100,000 databases are included. Each database above 100,000 costs $0.10 per month. Free: 10. |
| Maximum database size | 10 GB (Workers Paid) / 500 MB (Free) |
| Maximum storage per account | 1 TB (Workers Paid) 1 / 5 GB (Free) |
| Time Travel duration (point-in-time recovery) | 30 days (Workers Paid) / 7 days (Free) |
| Maximum Time Travel restore operations | 10 restores per 10 minutes (per database) |
| Queries per Worker invocation (read subrequest limits) | 1000 (Workers Paid) / 50 (Free) |
| Maximum number of columns per table | 100 |
| Maximum number of rows per table | Unlimited (excluding per-database storage limits) |
Maximum string, BLOB or table row size |
2,000,000 bytes (2 MB) |
| Maximum SQL statement length | 100,000 bytes (100 KB) |
| Maximum bound parameters per query | 100 |
| Maximum arguments per SQL function | 32 |
Maximum characters (bytes) in a LIKE or GLOB pattern |
50 bytes |
| Maximum bindings per Workers script | Approximately 5,000 2 |
| Maximum SQL query duration | 30 seconds 3 |
Maximum file import (d1 execute) size |
5 GB 4 |
| Maximum query result size | 50 MB 5 |
Batch limits
Limits for individual queries (listed above) apply to each individual statement contained within a batch statement. For example, the maximum SQL statement length of 100 KB applies to each statement inside a db.batch().
The Queries per Worker invocation limit is an exception: a db.batch() call counts as a single query against it, not one query per statement. For example, a batch containing 2,000 statements executes in a single Worker invocation, while issuing 2,000 individual queries in one invocation fails with Too many API requests by single Worker invocation.
Cloudflare also offers other storage solutions such as Workers KV, Durable Objects, and R2. Each product has different advantages and limits. Refer to Choose a data or storage product to review which storage option is right for your use case.
Need a higher limit?
To request an adjustment to a limit, complete the Limit Increase Request Form ↗︎. If the limit can be increased, Cloudflare will contact you with next steps.
Frequently Asked Questions
Frequently asked questions related to D1 limits:
How much work can a D1 database do?
D1 is designed for horizontal scale out across multiple, smaller (10 GB) databases, such as per-user, per-tenant or per-entity databases. The Workers Paid plan includes 100,000 databases per account. You pay $0.10 per D1 database per month above the included amount. Query and storage charges apply separately.
Storage
Each D1 database can store up to 10 GB of data.
Caution
Note that the 10 GB limit of a D1 database cannot be further increased.
Concurrency and throughput
Each individual D1 database is inherently single-threaded, and processes queries one at a time.
Your maximum throughput is directly related to the duration of your queries.
- If your average query takes 1 ms, you can run at most 1,000 queries per second.
- If your average query takes 100 ms, you can run at most 10 queries per second.
Note that there is a small overhead per request that is not included in the timings that D1 reports. As a result, a database receiving many small requests would reach its limit before 1 / query duration requests per second.
To get more throughput from a single database, reduce the number of requests rather than only the duration of each query. For example, use batch() to send multiple statements in a single request, so that the per-request overhead is paid once for the whole batch.
A database that receives too many concurrent requests will first attempt to queue them. If the queue becomes full, the database will return an "overloaded" error.
Each individual D1 database is backed by a single Durable Object. When using D1 read replication ↗︎ each replica instance is a different Durable Object and the guidelines apply to each replica instance independently.
Query performance
Query performance is the most important factor for throughput. As a rough guideline:
- Read queries like
SELECT name FROM users WHERE id = ?with an appropriate index onidwill take less than a millisecond for SQL duration. - Write queries like
INSERTorUPDATEcan take several milliseconds for SQL duration, and depend on the number of rows written. Writes need to be durably persisted across several locations - learn more on how D1 persists data under the hood ↗︎. - Data migrations like a large
UPDATEorDELETEaffecting millions of rows must be run in batches. A single query that attempts to modify hundreds of thousands of rows or hundreds of MBs of data at once will exceed execution limits. Break the work into smaller chunks (e.g., processing 1,000 rows at a time) to stay within platform limits.
To ensure your queries are fast and efficient, use appropriate indexes in your SQL schema.
CPU and memory
Operations on a D1 database, including query execution and result serialization, run within the Workers platform CPU and memory limits.
Exceeding these limits, or hitting other platform limits, will generate errors. Refer to the D1 error list for more details.
How many simultaneous connections can a Worker open to D1?
You can open up to six connections (to D1) simultaneously for each invocation of your Worker.
For more information on a Worker's simultaneous connections, refer to Simultaneous open connections.
Footnotes
- The maximum storage per account can be increased by request on Workers Paid and Enterprise plans. Refer to the guidance on limit increases on this page to request an increase. ↩
- A single Worker script can have up to 1 MB of script metadata. A binding is defined as a binding to a resource, such as a D1 database, KV namespace, environmental variable, or secret. Each resource binding is approximately 150-bytes, however environmental variables and secrets are controlled by the size of the value you provide. Excluding environmental variables, you can bind up to ~5,000 D1 databases to a single Worker script. ↩
- Requests to Cloudflare API must resolve in 30 seconds. Therefore, this duration limit also applies to the entire batch call. ↩
- The imported file is uploaded to R2. Refer to R2 upload limit. ↩
- This limit takes effect on 2026-11-04. Queries that return a result larger than 50 MB will fail and return an error. Import and export operations via the REST API are not subject to this limit. For more information, refer to the query result size limit changelog entry. ↩
Timeline
October 2026
- D1 will enforce a maximum query result size of 50 MB
Beginning Wednesday, November 4, 2026, D1 will enforce a maximum query result size of 50 MB. Queries that return a result larger than 50 MB will fail and return the following error: D1 query result exceeded the maximum response size limit of 50 MB The 50 MB limit covers the 99.999th percentile of requests across D1, so most D1 users will not be impacted. Import and export operations via the REST…
- Increased Errors for Durable Objects and Downstream Services in Eastern North America (ENAM) Incident
Minor impact. Resolved Oct 29, 2026, 16:50 UTC.
- Increased Durable Objects, D1 and Workflows Error Rates Incident
Minor impact. Resolved Oct 29, 2026, 16:33 UTC.
- Increased Errors for Durable Objects in the Eastern North America region Incident
Minor impact. Resolved Oct 28, 2026, 11:10 UTC.
- Increased Errors for Durable Objects in the Eastern North America region Incident
Minor impact. Resolved Oct 28, 2026, 03:28 UTC.
- D1 database undelete requests limited to the last 7 days
The D1 undelete API now only accepts requests for databases that were deleted within the last 7 days. Requests to undelete a database that was deleted more than 7 days ago will fail and return an error. If you delete a D1 database by mistake, send the undelete request as soon as possible, and no later than 7 days after deletion. For more information, refer to the undelete D1 database API referenc…
- United States jurisdiction
You can create D1 databases with the us jurisdiction. These databases run and persist data within the United States. Use this option for regional data residency requirements. To create a database with the us jurisdiction, run: npx wrangler@latest d1 create db-with-us-jurisdiction --jurisdiction=us For more information, refer to D1 data location.
September 2026
- D1 enforces free tier daily query limits
Beginning September 1, 2026, D1 queries on the Workers Free plan will fail when an account exceeds the daily row read or row write limits. Queries via the Workers Binding API and the REST API will return errors until the limit resets at midnight UTC. Stored data is not affected. You will receive email alerts when the daily limit is reached. The following errors indicate that a limit has been exce…
June 2026
- Billable usage and budget alerts now in product sidebars
Pay-as-you-go customers can now view billable usage and create budget alerts directly from the product overview pages for Workers & Pages, D1, R2, Workers KV, Queues, Vectorize, Durable Objects, and Containers. A new sidebar widget shows current-period spend and the billing cycle date range, alongside a button to create a budget alert. The widget pulls from the same data as the Billable Usage das…
May 2026
- D1 migrations support nested layouts via `migrations_pattern`
You can now point wrangler d1 migrations apply at a nested migrations layout — such as the one produced by Drizzle ↗︎ (migrations/0001_init/migration.sql) — using the new migrations_pattern D1 binding config: { "d1_databases": [ { "binding": "DB", "database_name": "my-database", "database_id": "<UUID>", "migrations_dir": "migrations", "migrations_pattern": "migrations/*/migration.sql", }, ], } mi…
November 2025
- D1 can restrict data localization with jurisdictions
You can now set a jurisdiction when creating a D1 database to guarantee where your database runs and stores data. Jurisdictions can help you comply with data localization regulations such as GDPR. Supported jurisdictions include eu and fedramp. A jurisdiction can only be set at database creation time via wrangler, REST API or the UI and cannot be added/updated after the database already exists. n…
September 2025
- D1 automatically retries read-only queries
D1 now detects read-only queries and automatically attempts up to two retries to execute those queries in the event of failures with retryable errors. You can access the number of execution attempts in the returned response metadata property total_attempts. At the moment, only read-only queries are retried, that is, queries containing only the following SQLite keywords: SELECT, EXPLAIN, WITH. Que…
June 2025
- Automate Worker deployments with a simplified SDK and more reliable Terraform provider
Simplified Worker Deployments with our SDKs We've simplified the programmatic deployment of Workers via our Cloudflare SDKs. This update abstracts away the low-level complexities of the multipart/form-data upload process, allowing you to focus on your code while we handle the deployment mechanics. This new interface is available in: cloudflare-typescript ↗︎ (4.4.1) cloudflare-python ↗︎ (4.3.1) Fo…
May 2025
- 50-500ms Faster D1 REST API Requests
Users using Cloudflare's REST API to query their D1 database can see lower end-to-end request latency now that D1 authentication is performed at the closest Cloudflare network data center that received the request. Previously, authentication required D1 REST API requests to proxy to Cloudflare's core, centralized data centers, which added network round trips and latency. Latency improvements rang…
April 2025
- D1 Read Replication Public Beta
D1 read replication is available in public beta to help lower average latency and increase overall throughput for read-heavy applications like e-commerce websites or content management tools. Workers can leverage read-only database copies, called read replicas, by using D1 Sessions API. A session encapsulates all the queries from one logical session for your application. For example, a session ma…
January 2025
- 40-60% Faster D1 Worker API Requests
Users making D1 requests via the Workers API can see up to a 60% end-to-end latency improvement due to the removal of redundant network round trips needed for each request to a D1 database. p50, p90, and p95 request latency aggregated across entire D1 service. These latencies are a reference point and should not be viewed as your exact workload improvement. This performance improvement benefits a…