← Grammarly Interview Insights

Grammarly·Software Engineer·Onsite - System Design / Architecture·Senior

SeniorPrefer not to say
Jun 2026

Summary

Grammarly system design round, one big question about building a pub/sub system from scratch. Went deeper than I expected and covered a lot of ground fast.

Questions Asked (1)

Q1

Design an in-process publish/subscribe system with subscribe, unsubscribe, and publish operations. Walk through your data structures, thread-safety concerns, ordering guarantees, how you'd handle slow subscribers, and how you'd extend this to a distributed setting.

System DesignTechnical Trade-offsAlgorithms & Data Structures
Author's notes

I started with the easy part, a map from topic strings to a set of callbacks, and that was fine.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements (e.g., in-process, thread-safe, ordering, slow subscriber handling) and then design a simple pub/sub system using a topic-based registry with thread-safe data structures. Walk through the core operations, discuss trade-offs for concurrency and slow subscribers, and finally outline a distributed extension with message brokers and partitioning.

Pro tip: Demonstrate awareness of real-world constraints: mention that slow subscribers can be handled with bounded queues and backpressure, and that distributed pub/sub requires considering message ordering, delivery guarantees, and fault tolerance. This shows you think beyond the happy path.

1. Clarify Requirements and Scope

Ask questions to understand expected scale, ordering guarantees, delivery semantics (at-least-once, at-most-once), and whether subscribers can be added/removed concurrently. This ensures you design the right system.

2. Design Core Data Structures

Propose a thread-safe registry mapping topics to subscriber lists, using concurrent data structures like ConcurrentHashMap and CopyOnWriteArrayList. Explain how subscribe/unsubscribe modify the registry and how publish iterates over subscribers.

3. Address Thread-Safety and Ordering

Discuss locking strategies (fine-grained vs. coarse-grained), use of read-write locks, and how to ensure message ordering per subscriber. Mention that ordering can be maintained by delivering messages sequentially per subscriber, possibly with a dedicated queue.

4. Handle Slow Subscribers

Explain strategies like bounded queues, dropping messages, or using a separate thread pool per subscriber. Discuss backpressure and the trade-off between message loss and system stability.

5. Extend to Distributed Setting

Outline how to scale out using a message broker (e.g., Kafka, RabbitMQ), partitioning topics, and ensuring fault tolerance. Mention challenges like network partitions, message ordering across nodes, and exactly-once semantics.

Key Points to Mention

  • Thread-safe data structures: ConcurrentHashMap for topics, CopyOnWriteArrayList for subscribers to allow concurrent reads and safe writes.
  • Ordering guarantees: Per-subscriber FIFO ordering can be achieved with a dedicated queue and single-threaded delivery per subscriber.
  • Slow subscriber handling: Bounded queues with configurable overflow policies (block, drop, or disconnect) and backpressure mechanisms.
  • Concurrency trade-offs: Lock striping, read-write locks, or lock-free structures to minimize contention.
  • Distributed extension: Use of message brokers, partitioning, replication, and handling of network failures and message durability.
  • Delivery semantics: At-least-once vs. at-most-once vs. exactly-once, and how they affect design choices.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.