← Atlassian Interview Insights

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

Senior
Jun 2026

Summary

System design round at Atlassian for a software engineer role, focused entirely on a notification reliability problem. Pretty deep dive, the kind where you realize halfway through that you've been thinking about it too shallowly.

Questions Asked (5)

Q1

Your document-signing system is supposed to send notifications after a signature event, but some notifications are silently dropped and nothing shows up in the logs. How do you redesign this to be reliable?

System DesignRoot Cause AnalysisTechnical Trade-offs
Author's notes

This is a bigger question than it looks.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by diagnosing why notifications are silently dropped—likely due to fire-and-forget calls, missing error handling, or lack of delivery guarantees. Then propose a redesign using durable message queues, transactional outbox, idempotent consumers, and comprehensive observability to ensure reliability and traceability.

Pro tip: Emphasize the importance of end-to-end tracing and dead-letter queues to catch silent failures, and mention that reliability must be balanced with latency and cost—showing you understand trade-offs.

1. Root Cause Analysis

Identify why notifications are dropped: check for synchronous fire-and-forget calls, swallowed exceptions, missing retries, or lack of logging. Consider race conditions and non-atomic operations.

2. Design for Reliability

Introduce a durable message queue (e.g., Kafka, SQS) with at-least-once delivery, and use the transactional outbox pattern to atomically persist signature events and notification intents.

3. Ensure Idempotency and Retries

Make notification consumers idempotent to handle duplicate messages, and implement exponential backoff retries with a dead-letter queue for poison messages.

4. Add Observability

Instrument the entire flow with structured logging, metrics (e.g., success/failure counts, latency), and distributed tracing to detect and debug silent drops.

5. Discuss Trade-offs

Acknowledge trade-offs: increased complexity, potential latency, and cost. Propose monitoring and alerting to maintain reliability without over-engineering.

Key Points to Mention

  • Transactional outbox pattern to avoid dual-write inconsistency
  • Message queue with at-least-once delivery and dead-letter queue
  • Idempotent consumers to handle duplicate deliveries
  • Retry policies with exponential backoff and jitter
  • Distributed tracing and structured logging for end-to-end visibility
  • Monitoring and alerting on queue depth, failure rates, and latency

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

Q2

How would you guarantee a notification is persisted before it's ever attempted, so a crash between signing and sending doesn't silently lose it?

System DesignData Modeling
Author's notes

The outbox pattern.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Frame the problem as a classic dual-write consistency issue between signing and sending, and propose a transactional outbox pattern where the notification is persisted in the same transaction as the business event that triggers it. Then describe an asynchronous dispatcher that reads from the outbox, attempts delivery, and updates status, ensuring at-least-once delivery with idempotency to handle duplicates.

Pro tip: Emphasize that the outbox table should be in the same database as the business data to guarantee atomicity, and mention that you'd use a unique constraint on a deduplication key to prevent duplicate notifications from retries.

1. Identify the dual-write problem

Explain that signing and sending are separate operations, and a crash between them can lose the notification if not persisted first. This is a classic dual-write consistency issue.

2. Propose transactional outbox pattern

Persist the notification in an outbox table within the same database transaction that signs it (or triggers it). This guarantees atomicity: either both the business change and the notification record are committed, or neither.

3. Design asynchronous dispatcher

A separate process (or worker) polls the outbox table for pending notifications, attempts to send them, and updates their status to 'sent' or 'failed' with retry logic. This decouples persistence from delivery.

4. Ensure idempotency and at-least-once delivery

Since the dispatcher may retry, include a unique deduplication key (e.g., notification ID) to make sending idempotent. The system guarantees at-least-once delivery; duplicates are handled by the receiver or by checking status before sending.

5. Handle failures and monitoring

Implement retries with exponential backoff, dead-letter queues for persistent failures, and monitoring/alerting on outbox backlog to detect issues. Also consider cleanup of old sent notifications.

Key Points to Mention

  • Transactional outbox pattern for atomicity between business data and notification persistence
  • Same database transaction to avoid dual-write inconsistency
  • Asynchronous dispatcher with polling or change data capture (CDC)
  • Idempotency keys to handle duplicate sends from retries
  • At-least-once delivery guarantee and its implications
  • Monitoring, retries, and dead-letter queues for operational robustness

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

Q3

How do you make sure retries don't result in duplicate notifications being sent to the user?

System DesignAPI & Integrations
Author's notes

Idempotency keys.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by defining the problem: retries can cause duplicate notifications if the operation isn't idempotent. Then explain how you'd design the notification system to be idempotent, using techniques like unique idempotency keys, deduplication, and transactional outbox patterns. Finally, discuss how you'd handle edge cases and monitor for duplicates.

Pro tip: Mention that idempotency should be enforced at the notification service level, not just the caller, and that you'd use a unique constraint on a deduplication key to atomically prevent duplicates even under concurrent retries.

1. Clarify requirements and constraints

Ask about the notification types (email, push, SMS), expected volume, and whether at-least-once or exactly-once delivery is required. This shows you consider trade-offs.

2. Design for idempotency

Explain that each notification request should carry a unique idempotency key (e.g., derived from event ID and user ID). The notification service checks this key before sending.

3. Implement deduplication with atomic operations

Use a database with a unique constraint on the idempotency key, or a distributed cache like Redis with SETNX, to atomically record that a notification was sent. If the key exists, skip sending.

4. Handle retries and failures gracefully

Ensure that retries use the same idempotency key. If a send fails after recording the key, you might need a two-phase approach or a status flag to avoid losing notifications.

5. Monitor and test for duplicates

Set up logging and metrics to detect duplicate sends. Write tests that simulate retries and concurrent requests to verify idempotency.

Key Points to Mention

  • Idempotency keys: unique identifiers for each notification request to deduplicate retries.
  • Database unique constraints or Redis SETNX for atomic deduplication.
  • Transactional outbox pattern to ensure notifications are sent exactly once even if the system crashes.
  • At-least-once vs exactly-once delivery semantics and their trade-offs.
  • Handling concurrent retries with distributed locks or atomic operations.
  • Monitoring and alerting for duplicate notifications to catch issues in production.

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

Q4

What observability would you build around this notification pipeline, and how would you know something is going wrong before users start complaining?

System DesignProduct Analytics & Metrics
Author's notes

I talked through structured logging at each state transition, metrics on queue depth and failure rates, and alerting on a growing backlog.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Structure your answer around the four golden signals (latency, traffic, errors, saturation) applied to each stage of the notification pipeline, then layer on business-level metrics like delivery success rate and user engagement. Emphasize proactive detection by defining SLOs with error budgets and setting up alerts on burn rates, so you catch issues before users notice.

Pro tip: Tie every technical metric to a user or business impact—e.g., 'a 1% drop in delivery rate means 10,000 missed notifications per day'—and mention how you'd use canary deployments and synthetic probes to validate changes before full rollout.

1. Map the pipeline and define SLIs

Break the notification pipeline into stages (ingestion, queuing, rendering, delivery, feedback) and identify key service level indicators (SLIs) for each, such as latency, error rate, and throughput.

2. Instrument with metrics, logs, and traces

Ensure each stage emits structured logs, distributed traces, and metrics (e.g., using Prometheus, OpenTelemetry) so you can pinpoint failures and measure performance end-to-end.

3. Set SLOs and alert on burn rates

Define service level objectives (SLOs) for critical user journeys (e.g., 99.9% of notifications delivered within 1 minute) and configure alerts based on error budget burn rates to detect issues early.

4. Add business and user-centric monitoring

Track metrics like notification open rates, click-through rates, and unsubscribe rates to detect silent failures or degradation that technical metrics might miss.

5. Implement proactive testing and canary analysis

Use synthetic transactions, canary deployments, and A/B tests to validate pipeline changes and catch regressions before they impact all users.

Key Points to Mention

  • The four golden signals: latency, traffic, errors, and saturation for each pipeline component
  • Distributed tracing to follow a notification from trigger to delivery and identify bottlenecks
  • SLOs with error budgets and multi-window burn-rate alerts to balance reliability and velocity
  • Business metrics like delivery success rate, open rate, and unsubscribe rate as leading indicators of user satisfaction
  • Synthetic monitoring and canary deployments to detect issues in pre-production or during rollout
  • Log aggregation and structured logging for debugging and post-mortem analysis

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

Q5

How would you handle documents that were signed but never notified, where the failure happened before anything was even queued?

System DesignRoot Cause Analysis
Author's notes

A reconciliation job that periodically scans for signed documents past some age threshold with no corresponding successful notification.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the scenario: documents were signed but never notified, and the failure occurred before any queuing. Then walk through a systematic root cause analysis, focusing on the pre-queue stage, and propose both immediate remediation and long-term preventive measures. Emphasize observability, idempotency, and robust error handling.

Pro tip: Demonstrate a blameless post-mortem mindset and highlight the importance of designing for failure at every step, especially in distributed systems where silent failures can occur before events are even recorded.

1. Clarify the Scenario

Ask questions to understand the exact flow: where are documents signed, what triggers notification, and what does 'before anything was even queued' mean in this system? Identify the components involved and the expected sequence of events.

2. Trace the Failure Point

Investigate logs and metrics to pinpoint where the process broke. Since the failure happened before queuing, focus on the signing service, any synchronous calls, and the handoff to the queuing mechanism.

3. Identify Root Cause

Determine why the failure occurred: was it a code bug, a network issue, a configuration error, or a missing error handler? Use techniques like the 5 Whys to dig deeper.

4. Implement Immediate Fix

Propose a short-term solution to handle the affected documents, such as a manual backfill or a script to reprocess them, ensuring no data loss and minimal customer impact.

5. Prevent Recurrence

Suggest long-term improvements: add monitoring and alerts for pre-queue stages, implement idempotent operations, use transactional outbox patterns, and ensure proper error handling and retries.

Key Points to Mention

  • Importance of observability and logging at every step, especially before queuing.
  • Idempotency and exactly-once processing to avoid duplicate notifications.
  • Transactional outbox pattern or similar to ensure atomicity between signing and queuing.
  • Blameless post-mortem culture and learning from failures.
  • Graceful degradation and fallback mechanisms for critical paths.
  • Testing strategies like chaos engineering to uncover silent failures.

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