← Atlassian Interview Insights

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

SeniorPrefer not to say
May 2026

Summary

System design round at Atlassian where the whole thing was basically one big rate limiter question. More depth required than I expected, especially once they pushed into distributed territory.

Questions Asked (1)

Q1

Design a rate limiter. Define the API (something like allow(client_id) returning a boolean), choose an algorithm, and walk through the trade-offs between approaches like fixed window, sliding window, token bucket, and leaky bucket. Also cover thread safety and how you'd extend this to a distributed system.

System DesignTechnical Trade-offsAPI & Integrations
Author's notes

I went with token bucket pretty quickly because I'd seen it before, but the interviewer kept pulling on the edges.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements (e.g., per-client limits, accuracy, latency, scalability) and defining a simple API like allow(client_id) -> boolean. Then compare algorithms (fixed window, sliding window, token bucket, leaky bucket) with trade-offs, and discuss thread safety and distributed extensions. Conclude with a recommended approach based on the requirements.

Pro tip: Emphasize that the choice of algorithm depends on the specific use case—e.g., token bucket for bursty traffic, sliding window for smoothness—and that distributed rate limiting often requires a centralized store like Redis with atomic operations.

1. Clarify Requirements

Ask about scale, accuracy, latency, and whether limits are per-client or global. Define the API contract, e.g., allow(client_id) returns true if request is allowed, false otherwise.

2. Compare Algorithms

Explain fixed window (simple but bursty at boundaries), sliding window (smoother but more memory), token bucket (allows bursts, refill rate), and leaky bucket (smooths output). Discuss trade-offs in memory, accuracy, and complexity.

3. Address Thread Safety

For a single-node implementation, use locks or atomic operations to ensure thread safety. Mention that lock contention can be a bottleneck, so consider lock-free data structures or sharding.

4. Extend to Distributed System

Use a centralized data store (e.g., Redis) with atomic operations (e.g., INCR, Lua scripts) to enforce limits across nodes. Discuss trade-offs: latency, consistency, and failure modes (e.g., Redis down).

5. Recommend and Summarize

Based on requirements, recommend an algorithm (e.g., token bucket for bursty traffic) and a distributed approach (e.g., Redis with sliding window). Summarize key trade-offs and potential optimizations.

Key Points to Mention

  • API design: allow(client_id) -> boolean, with optional parameters like cost or timestamp.
  • Fixed window: simple, but allows 2x burst at window boundaries.
  • Sliding window: smoother, but requires storing timestamps or using a log; can be approximated with sliding window counters.
  • Token bucket: allows bursts up to bucket size, refill rate controls average rate; leaky bucket: enforces constant output rate.
  • Thread safety: use locks, atomic counters, or concurrent data structures; consider contention and performance.
  • Distributed: use Redis with atomic operations (INCR, EXPIRE, Lua scripts) or a dedicated service; handle failures with fallbacks (e.g., local rate limiting).

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