Cloudflare recently entered public beta with K2, a serverless event streaming service built on R2 object storage. The service trades latency for cost and elasticity, and Cloudflare states the p99 produce latency at approximately one second. Public testing indicates end-to-end delivery runs slower than that figure.

From plumbing to streaming service

The project originated inside Basin Pipelines, which needed a durable place to park events before its pull-based processing engine could read and transform them. Most companies would reach for Apache Kafka at this point. Cloudflare could not, because Pipelines run across an edge spanning more than 335 cities on small slices of ephemeral machines networked over the public internet—Kafka assumes none of those conditions exist.

Instead the team built on the storage layer already handling durability. R2 provides eleven nines of durability with strongly consistent APIs. By pushing replication and consensus down into that layer, the application layer above becomes simpler; compute and storage scale independently. Object stores do not support append operations, which creates a problem when the abstraction is a log. K2 resolves this by holding writes in memory on an edge service, pausing briefly to allow more data to accumulate, then writing the batch out as a segment file. R2's atomic operations supply ordering and incrementing offsets, eliminating the need for a separate coordination service. That pause is where latency is introduced.

Hacker News reaction and pricing discussion

Hacker News commentary was largely positive about the pattern but pointed about the numbers. One commenter framed the shift as object storage becoming the new core data substrate, suggesting people should build Kafka—or even GitHub—on S3. The K2 tech lead, commenting as necubi, agreed that every data system not requiring sub-100ms latency is moving to object storage, noting his team works alongside the R2 team and can co-evolve the products. The post is credited to Micah Wylde and Marc Selwan.

The sharpest exchange came from a beta participant. Commenter e1g reported writes under a second but end-to-end delivery latency of p95 2.5 seconds and p99 7.5 seconds, asking whether that was expected. The team replied the tail latency was higher than expected, the Consume API has work to do on performance, and read latency improvements should appear within about a week.

A competitor in the same space, commenter sensodine working on s2.dev, argued the opportunity extends below 100ms, pointing to faster object storage tiers such as S3 Express and GCS rapid buckets. Both are single-zone and therefore still need quorum writes for regional durability. He described the underlying tension: how long to linger before flushing to object storage requires a direct trade-off between latency and the cost of API operations for PUTs. His own service uses stateful backend processes constantly flushing multi-tenant objects containing records from many streams, reaching roughly 50ms p99 acknowledgment latency from the same region without ruining unit economics.

Pricing drew objection. Commenter nnx found $0.04 per GB produced reasonable against other cloud event streams, but the identical consume charge was steep. That means actual usage is $0.08 per GB in the simplest case with one consumer, and fan-out strategies get very expensive very fast. That matters because fan-out is one use case Cloudflare positions K2 for. Retention is charged separately at $0.02 per GB per month, and nothing is billed during the beta.

The same commenter defended the cost case against obvious alternatives, stating K2's advantage over Google Pub/Sub is cost, particularly for longer retention. Object storage makes it much cheaper than self-hosted or cloud-hosted Kafka such as Amazon MSK or Confluent, with no clusters to manage and consistent performance as data volume grows. He restated the trade: produce and end-to-end latency around 1s p99 against systems relying on local disk replication.

Comparisons and roadmap

Several commenters asked how K2 differs from AutoMQ and WarpStream, which apply the same object-storage pattern, and noted Kafka now has diskless topic support. The answer: K2 is built for the Cloudflare ecosystem, and using it standalone does not make much sense.

Kafka compatibility is on the roadmap. The K2 tech lead was candid about why: the Kafka API is simultaneously too low level for normal users and too high level to deeply integrate into other systems like stream processing engines, and it requires a complex client library to use effectively. K2 instead uses a lease-based consume API, where a consumer polls a subscription, receives a batch leased for five minutes, then acknowledges it, negatively acknowledges it for redelivery, or extends the lease. That design allows higher read parallelism, which matters when consumers are Workers that parallelize well but are individually not very powerful.

On the producing side, a Worker binding sends batches and surfaces whether a failure is worth retrying. The example shows a Worker sending JSON-encoded page view events:

const result = await env.EVENTS.send([
  {
    content: new TextEncoder().encode(
      JSON.stringify({
        event: "page_view",
        path: new URL(request.url).pathname,
        timestamp: Date.now(),
      }),
    ),
    headers: { "content-type": "application/json" },
  },
]);
if (!result.success) {
  console.error(`Produce failed: ${result.error.message}`);
  return new Response("Failed to record event", {
    status: result.error.retryable ? 503 : 500,
  });
}


K2 represents data as bytes, leaving encoding to the application.

If these reactions are representative, the questions are about where the latency floor sits rather than whether the architecture makes sense. Cloudflare publishes a one-second produce figure, a user measured end-to-end tail latency several times that, and a competitor claims 50ms in a same-region configuration using stateful flushing rather than pure object storage.

Current limits and future work

Beta limits are 10GB of storage and 30 MB/s produce per stream, with a form for increases. Future work includes message keys and key-based ordering, multi-gigabyte-per-second write parallelism, push-based Worker consumers, a lower-latency express tier, and Kafka client support. Streams are created through the dashboard, the API, Wrangler, or cf, the command-line interface Cloudflare introduced the same week.