Skip to content

Cloudflare D1 free tier limits, and what counts as a row written

D1 on Workers Free allows 100,000 rows written and 5 million read a day per account. What counts as a write, what happens past it, and how to stay under.

EngineeringBy Rushi Patel, Senior iOS developerUpdated 6 November 20266 min read

Cloudflare D1’s free tier allows 100,000 rows written and 5 million rows read a day, counted across every database on the account, and resets at 00:00 UTC. When you go over, every query on every D1 database in the account fails until the reset. We found that out by taking three products down with one load test. Here is what the limits are, what counts as a row, and how to stay under them.

The limits on Workers Free

Limit Workers Free Workers Paid
Rows read 5 million a day 25 billion a month included
Rows written 100,000 a day 50 million a month included
Storage 5 GB for the account 5 GB included, up to 1 TB
Database size 500 MB 10 GB
Databases 10 100,000 included
Queries per Worker invocation 50 1,000

From Cloudflare’s D1 pricing and limits pages, checked on 6 November 2026. Workers Paid is 5 US dollars a month. A db.batch() call counts as one query toward the per-invocation limit, but every row inside it still counts toward reads and writes.

What counts as a row written

This is where the 100,000 goes faster than you expect.

  • Every inserted, updated or deleted row counts. Inserting 10 rows is 10.
  • Every index the write touches adds a row. A table with two indexes on the columns you insert costs three rows per insert.
  • Deletes count. Cleaning up after a test costs as much as the test did, and a retention job that deletes old rows every night spends writes every night.
  • Schema changes (CREATE, ALTER, DROP) can count as reads and writes.

So one logical event is usually several rows. An email OTP in SignOps is about 8 over its life: the code row and its index, a daily counter, the check, then the deletion when it expires. At 8 rows each, 100,000 writes is about 12,000 codes a day, before anything else on the account writes a row.

What happened to us

We run three products on one Cloudflare account: SignOps, Triplli, quotation software for travel agencies in India, and Cabaro, taxi booking software for cab operators. Each has its own D1 database. On the free plan they share one daily allowance.

On 20 October 2026 we load tested SignOps push on production: 26,000 imported device tokens, three sends to 25,000 devices, then deleting the test devices. Each failed send wrote a row per device, and the cleanup wrote the same again. The account went past 100,000 rows written, and from then until 00:00 UTC, every write failed on all three products, including a travel agency quoting live customers in Triplli. Reads kept working, so pages loaded and every save failed.

The only fix that day was to wait.

How to stay under the limit

Work out the row cost before a test. Rows written times (1 + indexes touched), plus the cleanup. 26,000 devices with two indexes is 78,000 rows to insert and 78,000 to delete: over the daily limit before a single send.

Run volume tests locally. wrangler dev with a local D1 (wrangler d1 migrations apply DB --local) has no daily limit. Keep production tests to a few hundred rows.

Store counts, not events. We replaced one row per failed device with one row per message, platform and reason, holding a count. A 25,000-device send with every token failing now writes a handful of rows instead of 25,000.

Cap per customer, per day. If customers’ usage writes rows, give each organisation a daily ceiling well under the account’s allowance, so one busy customer cannot use it all.

Give each product its own account. The limit is per account. A second free Cloudflare account gives a second product its own 100,000 writes, and a spike in one cannot reach the other. It costs nothing but a login.

Or pay 5 dollars. Workers Paid includes 50 million rows written a month, about 1.6 million a day, and lifts the daily cutoff within minutes of upgrading.

Checking how close you are

The Cloudflare dashboard shows rows read and written per database under Storage and Databases, D1, Metrics. For the account total, add up every database, or query the GraphQL Analytics API’s d1AnalyticsAdaptiveGroups dataset for rowsWritten grouped by day. Check it after any change that adds a table, an index or a scheduled job.

Frequently asked questions

More questions? Email us and the answer goes on this page.

hello@signops.dev
What are the Cloudflare D1 free tier limits?

On the Workers Free plan, D1 allows 5 million rows read and 100,000 rows written a day, 5 GB of storage across the account, 10 databases of up to 500 MB each, and 50 queries per Worker invocation. The daily limits reset at 00:00 UTC.

What happens when you exceed the D1 free tier daily limit?

D1 stops running queries and returns errors to your Worker saying the daily limit has been exceeded, until 00:00 UTC. Every database on the account is affected, because the limit is counted per account, not per database.

Do indexes count as rows written in D1?

Yes. A write that touches an indexed column writes one row to the table and one to each index on that column, so a table with two indexes costs three rows written per insert. Deletes and updates count too.

Is the D1 limit per database or per account?

Per account. Every D1 database on a Workers Free account shares the same 5 million reads and 100,000 writes a day.

How do I raise the D1 write limit?

Move to Workers Paid, 5 US dollars a month, which includes 50 million rows written and 25 billion rows read a month, then bills for more. Or put a second project on its own free Cloudflare account so it gets its own daily allowance.

Send your first push today.

Free for 1,000 push devices, 100 approvals and 1,000 passkey sign-ins a month, and 500 email codes to try. No card until you pass a free amount.