Cloudflare
KV
Cloudflare KV
Consistência Eventual
Cache
Edge
Serverless

Cloudflare KV: What Globally Distributed Means When You Need to Write

How Cloudflare KV's eventual consistency architecture works in practice, what workloads it's designed for, and where it will set you back in production.

Cloudflare KV: What Globally Distributed Means When You Need to Write

Cloudflare KV is sold as a globally distributed store, and that description is technically correct. What it leaves out is that "globally distributed" applies fully to reads, and only partially to writes — with a delay of up to 60 seconds that changes everything about how you should use it.

When you write a key to KV, the writing goes to a central store. From there, it propagates to all Cloudflare points of presence — more than 300 PoPs distributed globally. This propagation is not instantaneous. The official documentation indicates up to 60 seconds for all PoPs to receive the new value. During this window, a Worker running in Frankfurt can return the old value while a Worker in São Paulo already sees the new one. Two Workers in the same region may diverge if one of them has not yet received the update.

This is eventual consistency. Cloudflare documents this behavior clearly, but the phrase "globally distributed" is seductive enough that many teams don't read that part until they debug a bug in production.

What happens in a reading

Reading in KV has two paths, and the difference between them matters for latency. When a Worker does env.MY_KV.get('chave'), the runtime checks if that key is cached in the PoP that is serving the request. If it is — and most hot keys will be — the reading returns in sub-millisecond, straight from the PoP memory. This is the happy path and is what makes KV exceptionally fast for reads.

If the key is not cached in that PoP — because it is a new key, because it was written recently and has not yet propagated, or because the PoP simply has not received that input — the runtime searches the central store. This adds about 20ms. It's not dramatic, but it is measurable, and you will see this number appear in trace when the key is cold.

The detail that generates surprise: there is no guarantee of read-your-writes. You write a key and immediately try to read it in the same Worker invocation. Reading may return the previous value. This behavior is documented and intentional — it is a direct consequence of the PoP caching architecture. If you need read-your-writes, KV is not the right tool for that flow.

For which workload was the KV built

The KV architecture makes perfect sense when you know the problem it solves: data written at a low frequency and read at a very high frequency. The economic model reinforces this pattern. Reads cost $0.50 per million after the first 10 million free monthly. Write-ins cost $0.50 per million after the first free million. In the free tier, you have 100 thousand reads per day and only 1 thousand writes per day.

The cost and limits point to the same workload: write little, read a lot. Feature flags are the canonical example. A JSON file with product flags changes a few times a day at most. But it is read by every request from every Worker in every PoP in the world. A 60-second propagation is acceptable for a flag — you don't need every user on the planet to see the feature at the same millisecond. The number of reads, potentially billions per month, are cached at minimal cost.

The same reasoning applies to rendered HTML templates, application configuration, catalog data with a low update frequency, and session tokens with a defined TTL. You write once, read tens of thousands of times, and KV delivers that with cache latency.

Where will KV betray you

Any workload that requires immediate consistency will produce bugs when implemented over KV. The most common case is a user session with mutable state. The user logs out; you write the invalid session flag in KV; in the next 60 seconds, a different PoP can still authenticate requests with the old token because it did not receive the update.

Accurate counters are another point of failure. KV has no atomic operations — there is no compare-and-swap, there is no atomic increment. Two Workers reading the same counter simultaneously will read the same value, increment independently and one of the increments will be lost. For rate limiting counters that need to be accurate, KV is the wrong tool. Durable Objects exist for this case.

Data that changes per request also doesn't fit. If each response to the user changes a value in the KV, you are paying $0.50 per million writes in a volume that can be gigantic, with latency of ~150ms per write for confirmation in the central store, plus propagation delay. The cost scales in a way that doesn't make economic sense, and the write latency will appear in the p99 tail of your requests.

For immediate per-key consistency with low write latency, D1 with the Sessions API is Cloudflare's current path. For shared state that requires atomic operations, Durable Objects.

The cost model without illusions

The free tier is generous for experimentation but narrow for production of any volume. 100,000 readings per day equate to just over 1 constant request per second — a real application with reasonable traffic exceeds that in minutes.

In the paid tier, what changes is that readings are practically free at scale. $0.50 per million reads is cheap enough to not appear as a relevant line on the bill if your workload is properly read-heavy. Writes at $0.50 per million, with 1 million free per month, cover most config standards and flags at no significant cost.

What may surprise you is the storage: $0.50 per GB-month in addition to the first free GB. For small values ​​— configuration JSON, tokens, flags — you will hardly touch this limit. For those considering storing binaries of considerable size in KV (the limit per value is 25MB), the storage cost starts to appear. For large files, R2 at $0.015/GB makes more sense.

What KV solves well and what it doesn't

KV is a high-performance reading tool with occasional writing. When you opt into this model, it delivers sub-millisecond latency for hot reads, automatic global distribution without setting up replication, and a pricing model that favors massive volume reads.

The mistake isn't using KV — it's using it as if it were a general-purpose database. No tool replaces correct workload diagnosis. If your data changes frequently per user, requires atomicity, or needs immediate consistency, KV won't deliver — and you'll find that in production, not development.

Also read