← Grammarly Interview Insights

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

SeniorPrefer not to say
Apr 2026

Summary

Grammarly system design round focused entirely on building a pub/sub system from scratch. The question kept expanding with follow-ups and I felt like I was playing whack-a-mole with requirements the whole time.

Questions Asked (1)

Q1

Design and implement a publish/subscribe system supporting subscribe(topic, handler), unsubscribe, and publish(topic, message). Then extend it to handle wildcard topic patterns, async delivery, durable subscriptions, and at-least-once vs. at-most-once delivery semantics. Also discuss thread safety, back-pressure, and scaling across many topics and subscribers.

System DesignTechnical Trade-offsAPI & Integrations
Author's notes

Started okay with the basic subscribe/publish interface, a map from topic to list of handlers, nothing fancy.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start with a minimal in-memory pub/sub implementation using a map of topics to handler lists, then iteratively layer on wildcard matching, async delivery, durability, and delivery semantics while explicitly calling out trade-offs at each step. Treat the discussion as a design conversation: clarify requirements, sketch the API, then reason about thread safety, back-pressure, and scaling before diving into code-level details.

Pro tip: Anchor every extension in a concrete failure mode it addresses (e.g., wildcards for hierarchical topics, durable subscriptions for offline consumers, at-least-once for payment events) and explicitly state the trade-off you're accepting—this shows you design for real systems, not just features.

1. Clarify requirements and define the core API

Ask about expected scale, delivery guarantees, ordering, and whether topics are hierarchical. Define subscribe(topic, handler), unsubscribe(topic, handler), and publish(topic, message) with clear semantics for return values and error cases.

2. Implement the minimal in-memory version

Use a concurrent map from topic to a thread-safe collection of handlers. For publish, snapshot the handler list and invoke each handler, handling exceptions so one bad handler doesn't break others.

3. Extend with wildcards and async delivery

Support wildcard patterns (e.g., 'orders.*', 'orders.#') via a trie or regex-based matcher, and decouple publish from handler execution using a thread pool or per-subscriber queues to avoid blocking the publisher.

4. Add durability and delivery semantics

Persist messages for durable subscriptions (e.g., write-ahead log or broker-backed queue) and implement at-least-once (ack after processing, retry on failure) vs. at-most-once (fire-and-forget) with idempotency keys for deduplication.

5. Address thread safety, back-pressure, and scaling

Use concurrent data structures and locks for subscription changes, bounded queues with rejection or blocking for back-pressure, and partition topics across brokers or shard subscribers to scale horizontally.

Key Points to Mention

  • Thread safety: use ConcurrentHashMap, copy-on-write handler lists, or read-write locks to avoid concurrent modification during publish.
  • Wildcard matching: trie-based topic trees for hierarchical patterns (e.g., MQTT-style 'sport/+/player1') vs. regex for flat patterns, and the performance trade-offs.
  • Async delivery: thread pools, per-subscriber queues, and the risk of unbounded queues causing memory issues; consider reactive streams or back-pressure-aware libraries.
  • Durable subscriptions: persistence via write-ahead logs or external brokers (Kafka, RabbitMQ), and how to handle offline consumers and message replay.
  • Delivery semantics: at-least-once requires acks and retries (idempotent handlers), at-most-once is simpler but lossy; discuss exactly-once as a combination of idempotency and transactional guarantees.
  • Scaling: partitioning topics, sharding subscribers, and using a distributed broker (e.g., Kafka) to handle many topics and subscribers; mention back-pressure strategies like bounded queues and rate limiting.

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