Most RabbitMQ vs Kafka decisions get made against a feature matrix that expired years ago. The version still circulating says RabbitMQ can't replay and Kafka can't acknowledge individual messages, so you pick whichever capability you can't live without.

Both gaps closed. What's left is a difference in storage model, plus a constraint that neither project's documentation frames as a decision input: both brokers assume a long-lived connection.

This guide covers the architectural split, the serverless friction, and the decision.

**Key takeaways:**

- RabbitMQ routes messages and deletes them after acknowledgment, while Kafka retains an append-only log that consumers read at their own offset. That storage difference drives the choice.

- [RabbitMQ Streams](https://www.rabbitmq.com/blog/2021/07/13/rabbitmq-streams-overview) added non-destructive replay in 3.9, and [Kafka share groups](https://kafka.apache.org/blog/2026/02/17/apache-kafka-4.2.0-release-announcement/) reached production readiness in 4.2, so the old capability binary no longer separates them.

- The most-quoted throughput gap was measured in [2020](https://www.confluent.io/blog/kafka-fastest-messaging-system/) against RabbitMQ 3.8.5 with persistence disabled, in a mirrored-queue mode removed in RabbitMQ 4.0. Hence, its results are not representative of current RabbitMQ releases.

- Both brokers speak protocols built for persistent connections, which Vercel Functions running the Edge Runtime can't open, and which Node.js runtime functions hold only with care.

- Webhook fan-out and background jobs, the two workloads that usually trigger a broker purchase, are covered natively by [Vercel Queues](https://vercel.com/docs/queues) and [Vercel Workflows](https://vercel.com/docs/workflows).

## [Copy link to heading](#rabbitmq-vs-kafka-at-a-glance)RabbitMQ vs Kafka at a glance

The difference that determines everything downstream is what happens to a message after it's read. RabbitMQ queues are mutable, so the broker deletes a message once a consumer acknowledges it. Kafka topics are immutable logs, where a read advances a pointer and consumes nothing. Ordering, replay, consumer scaling, and operational burden all follow from that choice.

### [Copy link to heading](#what-this-comparison-is-based-on)What this comparison is based on

This comparison draws on the current releases of both projects, RabbitMQ 4.3.4 and Apache Kafka 4.3.1, and the documentation each maintainer publishes. Maintainer docs describe intended behavior and are useful starting points, so where documented behavior and observed production behavior diverge, production behavior takes precedence.

The criteria weighted most heavily are the ones that compound over a system's lifetime: what a message costs to store and re-read, what ordering survives once consumers scale out, how a single poisoned message gets handled, and how much operational surface each broker adds for a team without dedicated infrastructure engineers.

Here's where the two brokers split, with each row representing a design consequence rather than a feature checkbox:

| Decision axis | RabbitMQ | Apache Kafka |
| --- | --- | --- |
| Storage model | Queues delete on acknowledgment, Streams retain | Partitioned append-only log, retained by time or size |
| Routing control | Broker-side [exchanges and bindings](https://www.rabbitmq.com/docs/exchanges) | Producer-side partition assignment |
| Delivery direction | Push to subscribed consumers, pull available | Pull only, consumers issue fetch requests |
| Ordering | First in, first out per queue, single consumer only | Strict per partition, none across partitions |
| Message replay | Streams only, since 3.9 | Native, consumers rewind offsets at will |
| Consumer state | Broker tracks delivery state per consumer | Each consumer tracks its own offset |
| Queue semantics | Native to the design | Share groups, production-ready in 4.2 |
| Operational surface | Lower, single node viable, management UI built in | Higher, with partitions, rebalancing, and retention tuning |

Each row compresses a tradeoff that behaves differently under load than the cell suggests. The five with the most operational consequence are worth taking one at a time.

### [Copy link to heading](#why-a-read-deletes-in-rabbitmq-and-doesn't-in-kafka)Why a read deletes in RabbitMQ and doesn't in Kafka

RabbitMQ's default queue holds a message until someone acknowledges it, then removes it, so memory stays bounded and queue depth becomes a meaningful health signal. Kafka retains records for a configured window whether or not anyone read them, so storage cost tracks retention policy instead of backlog and a consumer that falls behind poses no threat to the broker.

### [Copy link to heading](#where-the-routing-decision-lives)Where the routing decision lives

Routing logic sits in the broker on RabbitMQ, through direct, fanout, topic, and headers exchanges. Producers publish to an exchange, bindings decide which queues receive a copy, and routing changes without a producer deploy. Kafka pushes that decision to the producer, which picks a partition by key. Tracing where a Kafka message went means reading the producer's key logic. Tracing a RabbitMQ message means inspecting the broker's binding table, which someone can change without a deploy.

### [Copy link to heading](#how-ordering-breaks-when-you-add-consumers)How ordering breaks when you add consumers

First in, first out holds within a RabbitMQ queue only while a single consumer reads it. Competing consumers break that order unless [Single Active Consumer](https://www.rabbitmq.com/docs/consumers) serializes processing, which costs the parallelism those consumers were added to provide. Kafka guarantees order within a partition, so a partition key gives per-entity ordering while different entities process in parallel.

### [Copy link to heading](#what-happens-to-a-single-bad-message)What happens to a single bad message

Delivery state lives in the RabbitMQ broker per consumer, which makes [per-message redelivery](https://www.rabbitmq.com/docs/reliability) native. Kafka historically offered only offset commits, so a consumer that needed to skip one bad record had an awkward problem. Share groups closed that gap in 4.2, at the cost of the ordering guarantee.

### [Copy link to heading](#what-each-broker-asks-you-to-operate)What each broker asks you to operate

A single RabbitMQ node is a legitimate production deployment for a small service, and the management UI ships in the box. Kafka's operational floor sits higher, because partitions, rebalancing, and retention are tuning decisions with production consequences. Managed services absorb much of that, though the mental model still has to live somewhere on the team.

## [Copy link to heading](#how-rabbitmq-routes-messages-for-teams-shipping-on-vercel)How RabbitMQ routes messages for teams shipping on Vercel

RabbitMQ is a message broker built on the Advanced Message Queuing Protocol (AMQP). Producers publish to exchanges, exchanges route copies into queues through bindings, and the broker pushes messages to subscribed consumers. Routing intelligence lives in the broker rather than in application code.

The current release is 4.3.4, and the 4.x series differs architecturally from the 3.x deployments still running in plenty of production clusters. Quorum queues, built on the Raft consensus algorithm, are the replicated queue type now that [mirroring is gone](https://www.rabbitmq.com/docs/3.13/ha).

RabbitMQ 4.3 also finished the metadata migration to [the Khepri store](https://www.rabbitmq.com/blog/2026/04/23/rabbitmq-4.3-release), a Raft-backed replacement for Mnesia that stays consistent through network partitions.

For a Next.js application on Vercel, RabbitMQ has to be reached from a [Vercel Function](https://vercel.com/docs/functions) on the Node.js runtime, over AMQP, on a connection the function keeps alive itself. None of the 4.x improvements change that, which is why the runtime constraints later apply the same way to both brokers.

### [Copy link to heading](#pros-and-cons-of-rabbitmq)Pros and cons of RabbitMQ

The RabbitMQ case for teams shipping on Vercel comes down to routing power and a low operational floor. It pulls its weight where the hard part of a system is the delivery topology rather than the volume moving through it. One engineer can run the whole thing and still understand what it's doing.

The case for RabbitMQ rests on four properties:

- **Routing expressiveness:** Fanout, topic matching, header routing, and per-message time to live are broker-side concerns, so topology changes without redeploying producers.

- **Low latency under light load:** With no mandatory batching step, messages move as they arrive, which is why RabbitMQ posts the lowest end-to-end latency in published head-to-head tests, at the reduced throughput where those numbers were measured.

- **Native failure handling:** Quorum queues in 4.3 handle delayed retries internally with linear backoff, which replaces the [dead-letter-and-republish](https://vercel.com/i/dead-letter-queue) workarounds teams built by hand.

- **Message priorities:** Quorum queues support 32 strict priority levels as of 4.3, so urgent work jumps the line instead of waiting behind a backlog.

Four costs come with it:

- **Replay requires a different primitive:** Standard queues can't replay, so getting replay means adopting Streams, a separate data structure with its own client.

- **Ordering caps throughput:** Preserving queue order means one consumer, so the only way to scale a strictly ordered workload is to shard it across more queues.

- **Vertical scaling ceiling:** Throughput is bounded by per-queue processing on a node, and published tests show CPU saturation setting in well before Kafka's ceiling.

- **The stream fast path is narrow:** Streams reach full speed over a dedicated binary protocol with Java and Go clients, and run slower over AMQP.

**Best for:** Task queues where each message is processed once and discarded, such as email sends, image processing, and PDF generation, plus any system whose complexity lives in routing rules rather than volume.

**Operating cost:** A small cluster handles the workloads most web applications generate, and the built-in management interface covers observability. The recurring cost is upgrade discipline, since the 3.x to 4.x path required migrating off mirrored queues and enabling feature flags in order.

### [Copy link to heading](#where-rabbitmq-stands-out)Where RabbitMQ stands out

RabbitMQ's advantage shows up when one published message has to reach different consumers depending on rules that change often. A topic exchange matches a routing key like `order.eu.priority` against binding patterns, so adding a consumer for European orders is a new binding rather than a producer deploy. The routing table becomes a reviewable configuration instead of conditional logic scattered across producers.

The delayed retry work in 4.3 shows RabbitMQ optimizing for the workload it gets used for. Rate-limited third-party APIs break background jobs constantly, and a per-message redelivery time lets one tenant's work wait while the rest keep moving.

## [Copy link to heading](#where-kafka's-log-model-fits-high-throughput-event-streams)Where Kafka's log model fits high-throughput event streams

Apache Kafka is a distributed append-only log. Producers write records to topic partitions, brokers retain them by a time or size policy rather than by consumption, and consumers pull data while tracking their own offset per partition. Multiple consumer groups read the same records at different positions without coordinating.

The [current release](https://kafka.apache.org/community/downloads/) is 4.3.1. Kafka 4.0 removed ZooKeeper support, so Kafka 4.x clusters use KRaft, Kafka's built-in Raft-based metadata protocol, which cuts a whole distributed system out of the operational picture. Idempotent producer delivery has been the default since 3.0, so retries no longer risk duplicate writes.

### [Copy link to heading](#pros-and-cons-of-kafka)Pros and cons of Kafka

Kafka's case is about retention and parallel consumption. It earns its operational weight where events keep their value after the first read, and where enough consumers need the same stream that copying it to each of them stops being reasonable. Analytics and audit systems fit that shape. Most web applications don't.

Kafka's advantages cluster around retention and parallel reads:

- **Replay as a first-class operation:** A new consumer group starts from the beginning of retained history, which makes event sourcing, audit trails, and reprocessing after a bug fix tractable.

- **Ordering with parallelism:** Partition keys give per-entity ordering while different entities process concurrently, which is what makes per-tenant event streams work at high volume.

- **Sustained throughput:** Producer batching amortizes disk input and output and the log writes each byte once, which puts Kafka's measured ceiling an order of magnitude above RabbitMQ's.

- **Queue semantics without leaving the log:** Share groups add individual acknowledgment and delivery counting to a Kafka topic.

The operational bill arrives in four places:

- **A latency floor by design:** The producer [`linger.ms`](https://kafka.apache.org/43/generated/producer_config.html) [default](https://kafka.apache.org/43/generated/producer_config.html) moved from 0 to 5 ms in Kafka 4.0, so batching waits before sending unless the batch fills first. RabbitMQ has no equivalent floor.

- **Partition count is semi-permanent:** Partitions set the parallelism ceiling for a consumer group, and changing them redistributes keys and disturbs the ordering guarantee that motivated partitioning.

- **Rebalancing is a production event:** Membership changes pause processing while assignments settle, and the effect grows with group size.

- **Retention drives storage cost:** Storage scales with the retention window rather than backlog, so retention policy becomes a recurring budget conversation.

**Best for:** Systems where several independent consumers need the same event stream, where replaying history is a product requirement rather than a recovery tool, or where volume runs past what one broker node absorbs.

**Operating cost:** Kafka's operational demands are real. A managed service such as Confluent Cloud or Amazon MSK absorbs most of them, and self-hosting is defensible with a dedicated infrastructure team and expensive without one.

### [Copy link to heading](#where-kafka-stands-out)Where Kafka stands out

The clearest case for Kafka is one where the same events feed genuinely different consumers. Picture one order stream read by a fulfillment service, an analytics pipeline, and a fraud model, each moving at its own pace. RabbitMQ approximates that with fanout exchanges and separate queues. Kafka handles it without duplicating storage, and a new consumer can join months later and read history that already exists.

Developers who stay happy with Kafka years in needed retained history for a product reason rather than an operational one. Kafka adopted for durability a queue would have provided pays log-shaped costs for queue-shaped work.

## [Copy link to heading](#running-rabbitmq-or-kafka-on-serverless-and-edge-runtimes)Running RabbitMQ or Kafka on serverless and Edge runtimes

Both brokers assume a persistent Transmission Control Protocol (TCP) connection, and that assumption fights ephemeral compute in ways neither project's documentation addresses. Opening a connection per operation fails in two directions at once. The client pays for connection setup on every invocation, and the broker absorbs churn that [eventually exhausts file handles](https://www.rabbitmq.com/docs/production-checklist) or memory.

### [Copy link to heading](#which-runtime-can-hold-a-broker-connection)Which runtime can hold a broker connection

Vercel Functions on the Node.js runtime can hold a broker connection, which makes it the runtime to pick for this workload. The Edge Runtime is built for a different job, and its [network surface](https://vercel.com/docs/functions/runtimes/edge) reflects that: `fetch`, `Request`, and `Response`, with `async_hooks`, `events`, `buffer`, `assert`, and `util` as its compatible Node.js modules. Without `net` or `tls`, neither Kafka's binary protocol nor AMQP has a socket to open.

The choice is getting simpler over time. Vercel now recommends the Node.js runtime over the Edge Runtime for new work, and Next.js 16.3 removed support for setting `runtime = 'edge'` on routes and pages.

### [Copy link to heading](#how-fluid-compute-makes-persistent-connections-viable)How Fluid compute makes persistent connections viable

[Fluid compute](https://vercel.com/docs/fluid-compute) is what lets a Node.js runtime function hold a broker connection at all. Concurrent invocations share a single instance and its global state, so a client initialized in module scope survives across requests instead of being rebuilt on every one.

Connection lifecycle is the piece you configure. The `attachDatabasePool` helper in `@vercel/functions` closes idle connections before an instance suspends, which prevents the phantom connection accumulation that used to plague serverless database access, and its [documented client list](https://vercel.com/kb/guide/efficiently-manage-database-connection-pools-with-fluid-compute) covers PostgreSQL, MySQL2, MariaDB, MongoDB, Redis, and Cassandra. A Kafka or RabbitMQ client sits outside that helper and needs its own disconnect on shutdown.

### [Copy link to heading](#the-flush-every-kafka-producer-in-a-function-needs)The flush every Kafka producer in a function needs

Inside short-lived compute, Kafka's batching becomes a correctness problem rather than a latency problem. A producer that buffers records and returns before the batch flushes loses them if the instance suspends first. The pattern that avoids it initializes the client once in module scope and awaits every send:

app/api/events/route.ts

```
import { Kafka } from 'kafkajs';

const kafka = new Kafka({
  clientId: 'your_client_id_here',
  brokers: [process.env.KAFKA_BROKERS!],
});

// Module scope, so Fluid compute reuses this across invocations
const producer = kafka.producer();
const connection = producer.connect();

export async function POST(request: Request) {
  const event = await request.json();
  await connection;

  // Awaiting send is the flush. Fire-and-forget loses records on suspension.
  await producer.send({
    topic: 'events',
    messages: [{ key: event.userId, value: JSON.stringify(event) }],
  });

  return Response.json({ accepted: true });
}
```

Clients built on librdkafka buffer more aggressively and need an explicit flush before teardown, which adds latency in exactly the place batching was supposed to save it. The feature that makes Kafka fast at high volume makes it slower in a function.

## [Copy link to heading](#when-to-use-rabbitmq,-when-to-use-kafka,-and-when-to-use-neither)When to use RabbitMQ, when to use Kafka, and when to use neither

Two questions settle most of these decisions. Does a message still have value after the first consumer reads it, and how many independent consumers need it? Messages that die on acknowledgment, read by a handful of consumers, don't need a log. Messages that stay useful for weeks, read by consumers nobody has built yet, do.

### [Copy link to heading](#when-rabbitmq-is-the-right-call)When RabbitMQ is the right call

Delivery topology, not volume, is the signal. When the hard part of a system is which consumer gets which message, and nobody on the team wants to own a distributed log, the broker-side routing model is the safer default.

RabbitMQ fits under these conditions:

- **Messages are work items:** Each one is processed once and discarded, and nobody will ever ask to replay them.

- **Routing complexity is the hard part:** Topic matching, per-message time to live, dead-letter exchanges, and priorities ship as broker features you'd otherwise build.

- **Latency beats volume:** Throughput sits where a small cluster copes, and the sub-batch delivery path is worth more than a higher ceiling.

- **Nobody wants to own partitions:** A single node is a real deployment, and the management UI is the whole observability story.

The cost is replay, which means accepting that messages are gone or adopting Streams as a second primitive.

### [Copy link to heading](#when-kafka-earns-its-operational-weight)When Kafka earns its operational weight

Kafka earns its operational weight when events keep their value after the first read. That value has to be a product requirement rather than a hedge, because the retention bill arrives either way.

Kafka fits under these conditions:

- **Multiple consumer groups read one stream:** Each at its own offset, each able to fall behind without affecting the others.

- **Replay is a product requirement:** Event sourcing, audit logs, or reprocessing history after a model change.

- **Volume runs past one broker's ceiling:** Sustained throughput where the log's write efficiency is the reason the system works.

- **Someone absorbs the operations:** A managed service, a dedicated infrastructure team, or both.

The cost is a latency floor, partition decisions that are awkward to reverse, and a retention bill that grows with the window.

### [Copy link to heading](#when-neither-broker-belongs-in-the-architecture)When neither broker belongs in the architecture

The third answer fits most applications, and it rarely gets considered. Webhook processing and background jobs look like broker problems because the vocabulary matches, when what they actually need is durable delivery with retries.

Neither broker belongs under these conditions:

- **The workload is webhook fan-out:** An inbound event needs to reach a handful of handlers reliably.

- **The workload is background jobs:** Work that must survive a crashed function, a timeout, or a deployment rolling out mid-run.

- **Retry semantics are the requirement:** What's needed is at-least-once delivery with [backoff](https://vercel.com/i/exponential-backoff), not a distributed log.

- **The consumer count is small and known:** Two or three pipelines, rather than open-ended fan-out to teams you haven't met yet.

Running a broker here means operating a distributed system to get retry semantics, then paying connection overhead on every invocation to reach it.

## [Copy link to heading](#how-vercel-supports-rabbitmq-and-kafka-workloads-for-product-teams)How Vercel supports RabbitMQ and Kafka workloads for product teams

Durable background work, fan-out to multiple consumers, and state that survives between steps are the workloads that usually justify buying a broker. All three exist as primitives on Vercel, so an application whose async work fits those shapes can ship without adding a broker to operate.

### [Copy link to heading](#background-jobs-that-vanish-when-a-function-crashes)Background jobs that vanish when a function crashes

The first version of every background job is a fire-and-forget call in a request handler, and it works until the function times out mid-run or a deployment rolls out while work is in flight. The work disappears silently, and the failure surfaces as a support ticket about a missing email rather than an error in the logs.

Vercel Queues addresses this with a durable topic and a lease model. Every message is written synchronously to [three availability zones](https://vercel.com/docs/queues/concepts) before the publish call returns, so it survives an entire zone failing. A consumer holds a visibility timeout lease, defaulting to 60 seconds and configurable up to 60 minutes, and if it crashes without acknowledging, the lease expires and the message is redelivered. Delivery is at-least-once, so consumers need to be idempotent.

### [Copy link to heading](#webhook-fan-out-to-more-than-one-consumer)Webhook fan-out to more than one consumer

Webhook handling starts as one endpoint doing one thing, then a second team needs the same events and the endpoint grows a branch. A few quarters later the handler is a router with four unrelated responsibilities, and a failure in the analytics path takes down fulfillment.

Consumer groups solve the coupling directly. Each group subscribes independently, tracks its own position, and processes at its own pace, so a slow or failing group has no effect on any other. Adding a route file with the same topic creates a separate group, so new pipelines land without touching existing ones.

The scale ceiling is higher than most teams assume. GitBook runs 30,000 documentation sites on a single Vercel deployment, where merge events drive 40,000 tag-based cache invalidations daily, each resolving in [under 300 ms](https://vercel.com/customers/how-gitbook-serves-30000-sites-with-sub-second-content-updates).

### [Copy link to heading](#multi-step-flows-that-need-state-between-steps)Multi-step flows that need state between steps

Onboarding sequences, payment reconciliation, and agent loops break the queue model because they need state between steps, and work that has to unwind on failure takes the shape of the [saga pattern](https://vercel.com/i/saga-pattern). The usual response wires up a queue, a status table, and per-step retry logic, and the coordination code ends up larger than the business logic it coordinates.

Vercel Workflows runs that orchestration inside application code. A function marked `"use workflow"` with steps marked `"use step"` gets durable state, retries at step boundaries, and the ability to suspend without consuming compute. `sleep()` handles delays from minutes to months, and hooks let a run wait for an external trigger. Workflows [reached general availability](/blog/a-new-programming-model-for-durable-execution) in April 2026 after processing over 100 million runs and 500 million steps across more than 1,500 teams in beta.

### [Copy link to heading](#broker-connections-that-leak-as-traffic-scales)Broker connections that leak as traffic scales

Developers who do need an external broker hit connection accumulation, and it arrives with traffic rather than on day one. The broker runs out of file handles before the application runs out of capacity, and the number that predicts it is instance count rather than request rate.

Concurrent function instances against the broker's connection limit is the metric to watch, with a per-instance pool ceiling that leaves headroom for a spike. [Rolling releases](https://vercel.com/docs/rolling-releases) help on the deploy path, since traffic shifts gradually instead of bringing a fleet of new instances online at once.

For consumers running outside Vercel, [poll mode](https://vercel.com/docs/queues/poll-mode) lets your own workers pull from a Vercel topic over standard OpenID Connect (OIDC) authentication, which keeps existing infrastructure in place while Vercel handles durability.

## [Copy link to heading](#ship-the-messaging-layer-your-team-can-operate)Ship the messaging layer your team can operate

The RabbitMQ vs Kafka question is worth answering carefully when the workload genuinely calls for a broker. Retained history that several consumers read at different offsets, or volume past what one node absorbs, are real requirements with real answers. What deserves scrutiny is the assumption that put the decision on the table, because webhook processing and background jobs get solved by retry semantics and durable delivery.

An unnecessary broker still costs something, even when the software is free. Where platform primitives already cover the workload, adding one means a system to operate, a connection model at odds with ephemeral compute, and a failure surface that shows up under exactly the traffic that made it seem necessary.

Vercel handles the messaging patterns most web applications need without external infrastructure:

- **Vercel Queues:** Durable topics with synchronous replication across three availability zones, at-least-once delivery, visibility timeouts, idempotency keys, and per-message retention from 60 seconds to 7 days.

- **Consumer groups with fan-out:** Independent subscribers process the same topic in isolation, and in poll mode a new group reads all non-expired history without republishing.

- **Vercel Workflows:** Durable multi-step orchestration in application code, with retries at step boundaries, `sleep()` for long delays, hooks for human-in-the-loop steps, and end-to-end encryption by default.

- **Fluid compute:** Concurrent invocations share an instance and its global state, so pools and clients persist across requests instead of being rebuilt per invocation.

- **Vercel Marketplace:** HTTP-native messaging services install from the dashboard with environment variables configured automatically, for cases where an external service is the right call.

[Start a new Vercel project](https://vercel.com/new) and ship on your first `git push`, or browse [vercel.com/templates](https://vercel.com/templates) to begin from a foundation you can grow into.

## [Copy link to heading](#frequently-asked-questions-about-rabbitmq-vs-kafka)Frequently asked questions about RabbitMQ vs Kafka

### [Copy link to heading](#is-rabbitmq-faster-than-kafka)Is RabbitMQ faster than Kafka?

At low throughput, yes. RabbitMQ delivers without a mandatory batching step, while Kafka's producer waits up to [`linger.ms`](http://linger.ms), which defaults to 5 ms since Kafka 4.0. The ranking flips as volume climbs, and the figures in circulation were measured on 3.x and 2.x releases, so treat any single number as a starting point rather than a verdict.

### [Copy link to heading](#can-rabbitmq-replay-messages-like-kafka)Can RabbitMQ replay messages like Kafka?

Yes, through RabbitMQ Streams, added in version 3.9. Streams are an append-only log with non-destructive consuming, so reading doesn't delete and consumers attach at any offset or timestamp. Standard queues still delete on acknowledgment and cannot replay.

### [Copy link to heading](#does-kafka-support-traditional-task-queues-now)Does Kafka support traditional task queues now?

Yes. Share groups, introduced by KIP-932, became production-ready in Kafka 4.2. Multiple consumers process records from the same partitions with individual acknowledgment and delivery counting, which gives queue semantics on a Kafka topic. The trade is ordering, which share groups give up for elastic scaling.

### [Copy link to heading](#can-you-connect-to-rabbitmq-or-kafka-from-a-serverless-function)Can you connect to RabbitMQ or Kafka from a serverless function?

From Vercel Functions on the Node.js runtime, yes, if you initialize the client in module scope so Fluid compute reuses it. Functions running the Edge Runtime cannot, because that runtime provides no raw TCP access.

### [Copy link to heading](#do-i-need-rabbitmq-or-kafka-if-i'm-building-on-vercel)Do I need RabbitMQ or Kafka if I'm building on Vercel?

Usually not. Vercel Queues and Vercel Workflows natively handle webhook processing, background jobs, retries, and fan-out to independent consumer groups. An external broker earns its place when throughput or replay requirements exceed platform tooling, or when consumers run on [external platforms](https://vercel.com/docs/integrations/external-platforms/kubernetes).