Cloudflare Workers KV vs D1 for Small SaaS: Cost & Latency

Building a small SaaS on Cloudflare Workers means choosing between two very different storage primitives โ and that choice has real cost and latency consequences that aren’t obvious from the docs alone.
Introduction
The Cloudflare Workers ecosystem has matured considerably by April 2026. Workers KV and D1 (SQLite at the edge) are both production-ready, yet many small SaaS builders still default to KV out of habit โ even when D1 would serve them better, or vice versa.
The confusion is understandable. Wrong choice and you’re either overpaying, fighting eventual consistency bugs, or watching p95 latency spike on cold reads.
The thesis: for small SaaS products running under 100,000 requests per day, D1 SQLite often wins on cost and query flexibility. But KV still dominates for pure read-heavy, globally-distributed access patterns where sub-10ms response times aren’t negotiable.
What this covers:
- How KV’s eventual consistency model creates real-world data hazards for transactional SaaS features
- D1’s per-query pricing versus KV’s per-operation pricing at the 100K request threshold
- Latency profiles for both primitives under realistic SaaS workloads (auth checks, user settings, feature flags)
- A decision framework for picking the right primitive at different product stages
Key Takeaways
- Cloudflare D1 offers free tier access up to 5 million rows read per day and 100,000 rows written per day as of 2026, making it cost-competitive for small SaaS workloads under 100K daily requests.
- Workers KV delivers single-digit millisecond read latency from Cloudflare’s 300+ edge locations globally, but its eventual consistency model โ propagation can take up to 60 seconds per Cloudflare’s official docs โ makes it unsuitable for write-then-read transactional patterns.
- D1 SQLite supports full SQL queries including JOINs and transactions, removing an entire class of application-level complexity that KV forces onto developers.
- The KV vs D1 decision is primarily architectural, not financial. Both options are cheap at this scale.
Background & Context
Cloudflare Workers KV launched in 2018 as a globally-replicated key-value store designed for edge caching: configuration data, session tokens, feature flags. Fast reads, eventual consistency, no relations. It fit the CDN-adjacent use cases Workers was originally built for.
D1 came much later. Public beta in 2022, general availability in late 2023, and by Q1 2026 it’s running millions of production databases. D1 is SQLite running at the edge, replicated across Cloudflare’s infrastructure. It supports standard SQL, transactions, and WAL mode for read performance. According to Cloudflare’s official storage options documentation, D1 is the recommended path for “relational or structured data, complex queries, and transactional workloads.”
The reason this question keeps surfacing in 2026: the serverless SaaS market has exploded. Builders are shipping real products โ subscription management, lightweight CRMs, developer tools โ entirely on Workers. These products need more than a cache. They need data integrity.
Cloudflare’s own documentation now explicitly distinguishes use cases. KV is listed for “read-heavy workloads requiring global low-latency access.” D1 is listed for “relational data that requires ACID transactions.” That split wasn’t always so cleanly articulated, which is why confusion persists.
Main Analysis
KV’s Latency Advantage Is Real โ And Limited
Workers KV reads from the nearest edge node after the first cache warm. Cloudflare’s docs state that KV delivers read latency “generally less than 1ms for cached values” across their global network. For feature flags, rate-limiting state, or user-facing configuration that changes infrequently, this is hard to beat.
The write path is a different story. KV writes propagate globally in up to 60 seconds per Cloudflare’s official documentation. For a SaaS app where a user updates their billing plan and immediately hits a paywalled feature, that 60-second window is a bug waiting to happen. Developers work around this with { cacheTtl: 0 } on reads, which effectively bypasses the cache and sends every read to central storage โ eliminating the latency advantage entirely.
At under 100K requests per day, KV pricing is practically zero. The free tier covers 100,000 reads and 1,000 writes daily. Paid usage is $0.50 per million reads and $5.00 per million writes according to Cloudflare’s pricing page (as of April 2026). Financial cost isn’t the issue at this scale.
D1’s SQL Flexibility Changes Application Architecture
D1 running SQLite changes what you can build without an external database. A standard SaaS user table, subscription records, audit logs, and feature entitlements โ that’s a JOIN and a transaction, not four separate KV namespaces with application-level consistency logic duct-taped together.
D1’s free tier (as of April 2026, per Cloudflare’s official pricing) includes 5 million rows read per day, 100,000 rows written per day, and up to 500MB storage. A small SaaS under 100K requests daily won’t touch those ceilings for months, possibly years.
Latency is the tradeoff. D1 reads run through Cloudflare’s infrastructure but don’t cache at the edge the same way KV does. Cloudflare’s docs indicate D1 queries typically complete in 2โ5ms for simple indexed lookups under normal load, measured from the Worker runtime. That’s fast โ but not sub-1ms KV fast. For a login flow or API response, the difference is irrelevant. For a globally-distributed real-time feature where every microsecond shows up in the UX, it might matter.
Consistency Is the Actual Decision Factor
This discussion often focuses on cost. It shouldn’t. At sub-100K requests, both are near-free. The real question is: does your data need to be consistent immediately after a write?
Yes? D1. ACID transactions, no propagation delay, SQL constraints enforce data integrity at the database layer.
No? KV. Truly static or slow-changing data โ app config, published content, CDN-adjacent state โ KV is faster and simpler. Don’t overcomplicate it.
Comparison: KV vs D1 for Small SaaS Workloads
| Criteria | Workers KV | D1 SQLite |
|---|---|---|
| Read Latency (cached) | <1ms (edge cache hit) | 2โ5ms (central query) |
| Write Consistency | Eventual (~60s propagation) | Strong (ACID transactions) |
| Query Flexibility | Key lookups only | Full SQL, JOINs, transactions |
| Free Tier (daily) | 100K reads / 1K writes | 5M row reads / 100K row writes |
| Data Modeling | Flat key-value pairs | Relational schemas |
| Storage Limit (free) | 1GB | 500MB |
| Best For | Feature flags, session tokens, config | User data, subscriptions, audit logs |
| Worst For | Transactional SaaS features | Global real-time read fan-out |
The table makes the split clear. These aren’t competing products โ they’re tools for different layers of the same application. Most small SaaS products need both.
Practical Implications: Three SaaS Scenarios
Scenario 1 โ Auth + Subscription State
A user logs in. The app checks their subscription tier before rendering a dashboard. This is exactly the D1 use case. A users table with a subscription_tier column, queried with a simple indexed lookup. Using KV here creates a consistency window where a just-upgraded user sees a stale free tier. D1 eliminates that class of bug entirely.
This approach can fail when the D1 query isn’t indexed properly โ full table scans at 2โ5ms each add up fast across concurrent sessions. Schema discipline matters.
Scenario 2 โ Feature Flags at the Edge
A/B test flags, maintenance mode switches, per-region configuration. These values change maybe once a day. KV with a short cache TTL (60โ300 seconds) is the right call. No transactions needed, global low-latency reads, and the 60-second propagation delay is acceptable for this use case.
Putting feature flags in D1 adds unnecessary query overhead to every request. That’s not a scalability problem at 100K requests โ it’s an architectural smell that compounds as you grow.
Scenario 3 โ Rate Limiting
Rate limiting is where both primitives show their limits. KV’s atomic operations (via getWithMetadata plus write patterns) can work for simple counters, but Cloudflare’s own docs recommend Durable Objects for rate limiting that requires strict consistency. Neither KV nor D1 is the right tool here โ worth knowing before you architect around either one.
What to watch: Cloudflare has signaled interest in D1 read replication closer to the edge, mentioned in their 2025 Birthday Week announcements. If read replicas ship in 2026, D1’s latency gap with KV narrows significantly โ making D1 the practical default for almost every SaaS data workload on Workers.
Conclusion & Future Outlook
The KV vs D1 decision breaks down to one clear framework:
- Consistency required + relational data โ D1 SQLite
- Read-heavy, slow-changing, globally-distributed โ Workers KV
- Rate limiting or counters with strict consistency โ Durable Objects (neither KV nor D1)
- Cost below 100K requests/day โ Irrelevant. Both are free or near-free
The next 6โ12 months are worth watching. D1’s roadmap points toward edge-proximate read replicas, which would close the latency gap with KV for global reads. If that ships in 2026, the practical argument for KV in SaaS applications gets considerably narrower.
The mindset shift worth making today: stop treating KV as the default Cloudflare Workers database. It was never designed for that role. D1 is. For most small SaaS workloads, D1 is the right starting point โ and KV is the optimization layer you add on top for specific, well-understood access patterns.
If your current Workers stack is using KV with a custom consistency layer bolted on, that’s the clearest signal it’s time to migrate to D1.
References
Photo by Conny Schneider on Unsplash


