Kafka is excellent software. Running it yourself on AWS is the part I'd skip.
The reason is arithmetic before it's operations. A Kafka cluster keeps three copies of every message in three Availability Zones, so every GB written crosses a zone boundary twice, and AWS bills each crossing. MSK doesn't charge for that replication. Once the transfer is counted, my model has MSK cheaper than the same brokers on EC2 from about 700 events a second, and at 100 MB/s with ten consumers the gap is about $24,000 a month (Kinesis or Kafka on AWS?).
Then come the operations: patching and upgrading brokers one at a time, replacing a dead one and moving its partitions, growing disks before they fill, three KRaft controllers since Kafka 4, and someone on call for all of it. MSK does that work, inside the client's account, with the same Kafka protocol. The only reason left to run it yourself is a version, plugin or setting MSK doesn't offer, with a team that has done it before.
Use it when
- A Kafka version, plugin or broker setting that MSK doesn't offer, with a team that already runs Kafka.
- Very small clusters where MSK's markup on the brokers matters more than the hours of work: in my cost model, EC2 is cheaper only below about 700 events a second, and by under $200 a month.
Don't use it when
- Any Kafka that MSK can run: at volume, MSK costs less, because it doesn't bill replication between AZs.
- A team without someone who has run Kafka through an upgrade and a broker failure.
Pricing
Sydney, bare EC2: 3 brokers (m7g.large, $0.102 an hour each) and 3 KRaft controllers (m7g.medium), about $335 a month; gp3 disks $0.096/GB-month for every copy kept; replication between AZs $0.02 per GB, twice for every GB written. Plus the people who run it. Checked 1 November 2026.
Gotchas, with fixes
Gotcha: Replication crosses AZs: with three replicas in three AZs, every GB written is copied twice across zones, at $0.02 per GB each time in Sydney. At 100 MB/s that's about $10,000 a month, more than MSK's markup on the brokers.
Fix: Use MSK, where replication between brokers is free. If you must run it yourself, budget the transfer first and turn on fetch-from-follower for the consumers.
Gotcha: Every broker is a server to patch, upgrade and replace: rolling restarts one broker at a time, partition reassignment after a failure, disks that fill up.
Fix: Automate all of it from day one (an image per version, a rolling-restart runbook, alarms on disk and under-replicated partitions), or let MSK do it.
Gotcha: Kafka 4 runs on KRaft only: ZooKeeper is gone, and the controllers are three more nodes to run.
Fix: Run three dedicated KRaft controllers on small instances, separate from the brokers.
Provisioning
Official Pulumi package · Official Terraform provider
The servers are plain EC2 (aws.ec2.Instance or an autoscaling group, official in both); Kafka itself is installed and configured on them (Ansible, a baked image, or Strimzi on EKS). Topics and ACLs through the Kafka provider (@pulumi/kafka, Mongey/kafka in Terraform).
Use instead
Amazon MSK: on AWS it costs less once replication between AZs is counted, and AWS patches, replaces and upgrades the brokers.
Alternatives
- Amazon MSK (managed Kafka) Any Kafka on AWS: same protocol, the brokers run by AWS, replication between AZs free.
- Amazon Kinesis A stream with a few consumers and no Kafka requirement.
Decision guides
Where it fits
- Event-driven plumbing: Don't.
Running Kafka yourself on AWS costs more than MSK once replication between AZs is counted, and every patch and broken broker is yours.
Instead: Amazon MSK (managed Kafka)
Sources
- Apache Kafka operations
- Apache Kafka KRaft
- EC2 data transfer pricing (between Availability Zones)
- Amazon MSK pricing (no charge for replication between brokers)
Last reviewed by Nicolas Dao