Writing

Why You Shouldn't Use Kafka & Microservices for Small Projects (Over-Engineering)

Deploying Kubernetes, Kafka, and 10 microservices for an app with 100 daily users isn't engineering foresight—it's over-engineering suicide. Here is a pragmatic, traffic-based decision framework on when and how to actually scale.

Furkan ÖzayOctober 17, 2026 · 5 min read
czCZAY.DEV // EDITORIALEN
SISTEM MIMARISI

#Sistem Mimarisi · 5 MIN READ

FURKAN ÖZAYVOL. 2026 // #1157

There is a seductive trap almost every software engineer falls into when starting a greenfield project: designing a system that has zero active users as if ten million people will hammer it tomorrow morning.

You open the architectural whiteboard: 12 independent microservices, an Apache Kafka cluster for asynchronous events, isolated databases per service, gRPC for inter-service communication, and an elaborate Kubernetes mesh just to keep everything afloat.

It sounds like "real engineering" you can proudly show off on LinkedIn. But the brutal reality of production is simple: Deploying Kafka and microservices for an app with 100 daily visitors isn't great engineering—it's suffocating the product before it even takes its first breath.

· · ·

1. The "Netflix Does It This Way" Myth

The root cause of this over-engineering epidemic is reading engineering blogs from tech giants without understanding their organizational and operational context.

Here is what people conveniently forget: Neither Netflix, Uber, nor Amazon started with microservices on Day 1.

  • Netflix ran on a monolithic architecture for years until a massive database corruption event in 2008 forced a transformation. Their migration to microservices wasn't driven by "cool tech," but by organizational scaling: hundreds of developers stepping on each other's toes in a single repository and a single database hitting physical hardware ceilings.
  • Shopify handles a massive percentage of global black-friday e-commerce traffic to this day on a well-architected Modular Monolith built on Ruby on Rails.

If you are building a product with a team of 2 to 5 engineers (or solo), your primary existential threat is not whether your database can handle 100,000 writes per second. Your primary threat is moving too slowly, failing to iterate, and spending 80% of your development bandwidth fixing distributed plumbing instead of delivering customer value.

· · ·

2. The Hidden Tax of Premature Distributed Systems

In a monolithic application, executing a business transaction (await orderService.createOrder()) takes nanoseconds in memory. If something fails midway, a standard database transaction (ROLLBACK) restores state deterministically.

The second you split into microservices and an event bus like Kafka, you inherit a whole catalog of distributed systems nightmares:

  1. Distributed Transactions & Saga Patterns: The payment service charged the credit card, but the inventory service crashed before reserving the stock. How do you issue compensating transactions reliably?
  2. Network Latency & Flakiness: Sub-millisecond in-memory function calls turn into 20–50ms HTTP/gRPC roundtrips over a network that is inherently unreliable.
  3. Observability Nightmare: Tracking down a bug now requires distributed tracing (OpenTelemetry, Jaeger) and centralized logging infrastructure just to find which queue dropped a message.
  4. Deployment Paralysis: Instead of deploying a single binary or container with one command, you are orchestrating cross-service schema migrations, API versioning, and complex CI/CD matrices.

Warning: The Golden Rule: Never Solve a Problem You Don't Have Yet

System design is not an exercise in speculative vanity; it is an exercise in constraint management. Every architectural tool you introduce to solve a hypothetical scaling bottleneck brings its own operational tax and cognitive overhead today.

· · ·

3. The Pragmatic Scaling Ladder

So what is the pragmatic alternative? How should you actually evolve your backend infrastructure as user volume grows?

plaintext
      ▲
     / \     Stage 4: 1M+ DAU & Multiple Independent Teams
    /   \    ➔ Event-Driven (Kafka), Kubernetes, Polyglot Microservices
   /-----\   
  /       \   Stage 3: 250k - 1M DAU
 /         \  ➔ Read-Replicas, Asynchronous Queues (BullMQ / RabbitMQ)
/-----------\ 
/             \ Stage 2: 50k - 250k DAU
/               \ ➔ Redis Cache (Cache-Aside), Connection Pooling (PgBouncer)
/-----------------\
/                   \ Stage 1: 0 - 50k DAU
/                     \ ➔ Modular Monolith + Single Managed PostgreSQL

Stage 1: 0 – 50,000 DAU (Clean Modular Monolith)

  • Architecture: A single Node.js (Fastify/NestJS), Go, or Python application.
  • Database: A single managed PostgreSQL or MySQL instance.
  • Strategy: Write modular code with clear domain boundaries, not spaghetti. If you ever need to extract a service later, the boundaries already exist—but keep them running in the same process today. This setup can comfortably handle tens of thousands of daily active users with sub-50ms latencies on a $20/month VPS.

Stage 2: 50,000 – 250,000 DAU (Caching & Connection Management)

  • Bottleneck: Repeated read queries spike database CPU usage.
  • Fix:
    • Place Redis in front of the database using the Cache-Aside pattern. Serve high-frequency reads directly from RAM in 1–2 milliseconds.
    • Introduce PgBouncer or connection pooling to prevent connection exhaustion during traffic bursts.

Stage 3: 250,000 – 1,000,000 DAU (Read/Write Split & Async Workers)

  • Bottleneck: Synchronous heavy tasks (sending emails, processing uploads, generating reports) tie up API threads. Database reads overwhelm the primary node.
  • Fix:
    • Offload non-critical tasks to lightweight background job queues like BullMQ or RabbitMQ.
    • Add 1–2 Read Replicas to the database, routing read-heavy queries away from the write master.

Stage 4: 1,000,000+ DAU (Event-Driven & Domain Extraction)

  • Why Now? Independent engineering squads (Payments, Search, Identity) need to deploy without stepping on each other, and audit logs generate terabytes of sequential events.
  • Fix: Now Kafka, event streaming, and dedicated microservices are justified, because the organizational and architectural bottlenecks finally exceed the operational cost.
· · ·

Unsure Which Stage Your Project Needs?

If you want an interactive way to diagnose your current user volume, identify upcoming bottlenecks, and see exact tool recommendations for each phase, check out our interactive roadmap:

👉 Explore the Interactive Backend Scaling Decision Matrix

· · ·

Conclusion

The best architecture is never the one with the most moving parts. The best architecture is the one that solves business objectives with the least complexity and the highest engineering velocity.

Spend the two months you would have wasted configuring Kafka and Kubernetes on polishing your user experience. Keep your monolith clean and modular; when the traffic arrives, scaling it systematically is far easier—and infinitely more enjoyable.

Read next