Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
Chaturmind
← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
HomeLearnSystem DesignLow-Level Design & Design PatternsMachine Coding Exercises
✓ FreeIntermediate· 6 min read

Design a Pub-Sub Message Broker

Broker/Topic/Publisher/Subscriber/Message classes for an in-memory pub-sub, and an honest accounting of what's missing compared to Kafka or RabbitMQ.

Published September 23, 2026


Design a Pub-Sub Message Broker

Design a Notification/Observer-Based Pub-Sub built an in-process event bus. This lesson is a step up in scope — a standalone broker component, still in-memory, but modeling the actual broker/topic/producer/consumer shape a real message queue uses.

Core classes

class Message { String id; String payload; Instant timestamp; }

class Topic {
    private final Queue<Message> messages = new ConcurrentLinkedQueue<>();
    private final List<Subscriber> subscribers = new CopyOnWriteArrayList<>();
}

interface Subscriber { void onMessage(Message message); }

class Publisher {
    private final Broker broker;
    void publish(String topicName, String payload) {
        broker.getTopic(topicName).deliver(new Message(UUID.randomUUID().toString(), payload, Instant.now()));
    }
}

class Broker {
    private final Map<String, Topic> topics = new ConcurrentHashMap<>();
    Topic getTopic(String name) { return topics.computeIfAbsent(name, k -> new Topic()); }
}

Basic in-memory pub-sub with topic-based routing

class Topic {
    // ...fields above...
    void subscribe(Subscriber subscriber) { subscribers.add(subscriber); }

    void deliver(Message message) {
        for (Subscriber s : subscribers) {
            s.onMessage(message); // synchronous fan-out to every current subscriber of this topic
        }
    }
}

Topic-based routing here is deliberately simple — a message published to "orders.created" only reaches subscribers of exactly that topic name, with no pattern matching or hierarchical routing (a real broker's "orders.*" wildcard subscriptions, for instance) — a reasonable, explicitly-scoped simplification for an LLD exercise.

What's missing vs a real broker

Naming these gaps explicitly is the actual point of this exercise — recognizing the difference between "a working pub-sub toy" and "a production message queue" is a stronger signal than presenting this simplified version as complete:

  • Persistence: this Topic's messages exist only in a ConcurrentLinkedQueue in one process's memory — a process restart loses everything undelivered. Kafka/RabbitMQ durably write messages to disk before acknowledging a publish.
  • Partitioning: this design has one queue per topic, on one machine — Kafka partitions a topic across multiple machines specifically for horizontal write/read throughput (see Design: Message Queue System for the full partition/replication model).
  • Delivery guarantees: deliver() here is fire-and-forget synchronous iteration — no acknowledgment, no retry on a subscriber failure, no offset tracking to resume from a specific point after a consumer restart. Real brokers offer at-least-once (or exactly-once, with more machinery) delivery guarantees backed by consumer acknowledgment and offset commits.

Follow-up questions this topic invites — and their answers

Q: If you had to add ONE of these three missing features first for a real use case, which, and why? A: Usually persistence — an in-memory-only broker that loses all undelivered messages on restart is disqualifying for most real production use cases immediately, while partitioning and refined delivery guarantees are scaling/robustness refinements that matter once the basic durability requirement is already met.

Q: How would you add at-least-once delivery to this design without a full broker rewrite? A: Track per-subscriber acknowledgment (a subscriber calls back to confirm processing) and retain a message in the Topic's queue until every subscriber has acknowledged it, retrying delivery to any subscriber that hasn't acknowledged within a timeout — a meaningful step up in complexity from the current fire-and-forget deliver(), but a natural extension rather than a redesign.

Q: Is synchronous deliver() (subscribers processed in a loop on the publishing thread) a design smell? A: For an LLD exercise it's an acceptable simplification, but worth naming: a slow subscriber blocks the publisher (and every other subscriber's delivery) under this design — the same sync-vs-async tradeoff from Design a Notification/Observer-Based Pub-Sub applies, and a production version would dispatch to subscribers asynchronously (an executor per subscriber, or per topic) to decouple their processing time from the publisher's.

Q: How does ConcurrentLinkedQueue's choice here compare to using a plain synchronized Queue? A: ConcurrentLinkedQueue is a lock-free (CAS-based) concurrent queue implementation, generally offering better throughput under contention than externally synchronizing a plain LinkedList — a reasonable default choice for a queue accessed by potentially many publisher and consumer threads concurrently, without needing to hand-roll the synchronization Producer-Consumer Class Design builds explicitly for its own pedagogical purpose.

Previous

Design a Distributed ID Generator

Next

Design Twitter/X

AI Tutor

Lesson: Design a Pub-Sub Message Broker

Quick actions

AI responses can be inaccurate. Verify critical information.