Engineering13 August 2026· 5 min read

Stop Throwing Kafka at Everything: A Developer's Guide to System Design

Before you spin up three Redis clusters and a Kubernetes pod for an app that barely has fifty active users, let's talk about how to actually approach system design without losing your mind.

EngineeringDevelopmentCode
Stop Throwing Kafka at Everything: A Developer's Guide to System Design

A few months ago, I was having coffee with a junior dev in Akure who was building an event ticketing MVP for local tech meetups. Before he had written a single database migration or processed one test payment, he was already stressing over whether to deploy Kafka or RabbitMQ for his background jobs.

I had to pause and ask him: "Bro, how many people are actually buying tickets at the same second?"

His answer? Maybe fifty people on a good Saturday.

That conversation reminded me of a trap almost every engineer falls into at some point. We see shiny tech words floating around tech Twitter—Load Balancers, Redis, Microservices, Sharding, Kubernetes—and suddenly, a simple feature turns into a monster setup. We start picking our tools before we even understand the problem we're trying to solve.

Developer working on code

The Resume-Driven Design Problem

The biggest mistake I see folks make is designing for scale they don't have. They know Redis, so they slap Redis into the architecture. They read an article about Netflix's microservices, so they split a CRUD app into six microservices.

Then power drops, their local docker setup breaks, or AWS sends them a bill charged in USD while their startup is earning in Naira, and the pain sets in.

System design isn't about flexing how many technologies you can cram into a diagram. It's about trade-offs. It's about knowing why a piece of infrastructure belongs in your architecture and what it costs you to maintain it.

Step 1: Figure Out What You're Building

Before you draw a single box on a whiteboard or write a line of code, ask the basic questions:

What are the functional requirements? If it's a URL shortener, the system takes a long link, gives back a short one, and redirects users when they click it. That's it.

What are the non-functional requirements? Does it need real-time speed? Does it need 99.99% uptime? If a server goes offline during peak hours in Onitsha, does the data survive?

Don't guess. Lock down the requirements first.

Step 2: Do the Math

You don't need a degree in pure math to do scale estimation. You just need rough figures to guide your decisions.

Handling 500 requests a day is a completely different beast from handling 50,000 requests per second. If you're building a lightweight logistics tracker for bus parks in Owerri, a single PostgreSQL instance on a cheap virtual server will probably handle your load for the next two years without sweating.

When you estimate traffic and storage up front, you avoid over-engineering things you don't need yet.

Data and metrics

Step 3: Define the API Boundary

Once you know the scale, lay out the entry points. How will your mobile app or frontend talk to your backend?

Keep it clean:

  • POST /api/v1/shorten
  • GET /{shortCode}

APIs set the boundaries of your system. Once your endpoints are clear, you can actually visualize how data flows from the user's phone down to your database.

Step 4: Start Simple, Add Complexity Only When It Hurts

Start with the absolute minimum architecture:

Client -> Load Balancer -> App Server -> Database

That's your foundation. You only add extra components when you hit a clear bottleneck.

Why add a Cache? Because hitting your primary database every time a million users request the exact same home feed will fry your database CPU. You introduce Redis to save those expensive reads.

Why add a Message Queue? Because sending a transactional email or processing an image upload during an HTTP request makes the user wait unnecessarily. You put that heavy task in a queue so a background worker can deal with it quietly while the user gets an instant success response.

Tech workspace scene

Every Box Needs a Reason

When I look at an architecture diagram, I always ask one thing: "What happens if this specific box dies?"

If you can't explain why a component exists or what happens when it fails, it shouldn't be in your stack. Simple, boring architecture that you can debug at 2 AM when servers are burning is worth ten times more than a complex, fragile web of microservices you barely understand.

Build simple first. Scale when the users actually force you to.

Related from Engineering

Available for Hire

Let's build your next big product.

Accepting project-based freelance, remote engineering roles, and hybrid positions.

© 2026 Samuel Stanley · Full Stack Engineer