← Asana Interview Insights

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

SeniorPrefer not to say
Jul 2026

Summary

Asana system design round focused entirely on building a collaborative todo-list service, the kind of thing that sounds deceptively simple until you're 20 minutes in and realize you haven't even touched real-time sync yet. Heavy on trade-offs, concurrency models, and consistency decisions.

Questions Asked (8)

Q1

Design a collaborative todo-list service where teammates can create shared lists, add and edit items, assign owners, set due dates, reorder items, and see each other's changes in near real time across web and mobile.

System DesignTechnical Trade-offsData Modeling
Author's notes

This is the main question and it ate the whole session.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying functional and non-functional requirements, then sketch a high-level architecture with clear separation of concerns (API, real-time layer, storage). Dive into data modeling for lists/items and the real-time sync mechanism, discussing trade-offs like conflict resolution and consistency models.

Pro tip: Emphasize idempotency and conflict resolution (e.g., operational transformation or CRDTs) for concurrent edits, and discuss how to handle offline scenarios gracefully—this shows depth beyond basic CRUD.

1. Clarify requirements and scope

Ask about scale (users, lists, items), real-time expectations (latency, consistency), and platform constraints (web/mobile). Define core features and non-functional requirements like availability and durability.

2. High-level architecture

Propose a client-server architecture with REST/GraphQL APIs for CRUD and WebSocket (or SSE) for real-time updates. Include load balancers, stateless app servers, and a pub/sub system for fan-out.

3. Data modeling and storage

Design schemas for users, lists, items, and assignments. Choose a database (e.g., relational for strong consistency or NoSQL for scale) and discuss indexing for efficient queries (e.g., by list ID, due date).

4. Real-time sync and conflict resolution

Detail how changes propagate: clients send mutations, server persists and broadcasts to subscribers. Address concurrent edits with optimistic concurrency (versioning) or CRDTs, and discuss offline support with local queues and sync on reconnect.

5. Scalability and trade-offs

Discuss scaling WebSocket connections (e.g., using Redis pub/sub), database sharding, and caching. Compare consistency vs. latency trade-offs and justify choices based on requirements.

Key Points to Mention

  • WebSocket vs. long polling for real-time updates, and handling reconnections
  • Data model: lists, items, assignments, due dates, and ordering (e.g., fractional indexing for reorder)
  • Conflict resolution strategies: versioning, operational transformation, or CRDTs
  • Offline support and sync mechanisms for mobile clients
  • Scalability: pub/sub fan-out, sharding, and caching
  • Trade-offs: consistency vs. availability, latency vs. durability

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

Q2

How would you order concurrent changes to a shared list so every client, including one that's been offline, can reason about what happened and catch up from a single cursor?

System DesignTechnical Trade-offs
Author's notes

This is where I felt the most lost.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements: total ordering, offline catch-up, and single-cursor semantics. Then propose a design using a central sequencer that assigns a monotonic version to each change, with clients storing the last version they've seen and fetching all changes after that version. Discuss trade-offs like latency, conflict resolution, and scalability.

Pro tip: Emphasize that the cursor should be a logical version (e.g., a sequence number or timestamp) rather than a physical offset, and mention that you'd handle gaps due to concurrent writes by ensuring the sequencer is the single source of truth.

1. Clarify requirements and constraints

Ask about consistency needs, expected concurrency, offline duration, and whether clients need to see all changes or just the latest state. This shows you understand the problem space before jumping to solutions.

2. Propose a central sequencer for total order

Describe a service that receives all mutations, assigns a monotonically increasing version number, and persists the ordered log. This ensures every client sees the same order.

3. Design the client catch-up mechanism

Explain that clients store the last version they've processed and request changes after that version. The server returns the ordered list of changes, allowing the client to apply them in order and update its cursor.

4. Address offline and concurrent scenarios

Discuss how an offline client can catch up by replaying changes from its cursor, and how concurrent changes are serialized by the sequencer. Mention potential issues like log growth and snapshotting.

5. Discuss trade-offs and alternatives

Compare with other approaches (e.g., CRDTs, vector clocks) and explain why a central sequencer with a single cursor is suitable for this use case, noting trade-offs in latency, scalability, and complexity.

Key Points to Mention

  • Monotonic versioning (e.g., sequence numbers) to establish total order
  • Central sequencer or log as the single source of truth
  • Client cursor as a logical version, not a physical offset
  • Idempotent change application and exactly-once semantics
  • Snapshotting or log compaction to handle long offline periods
  • Trade-offs: latency vs consistency, scalability of central sequencer

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

Q3

When multiple users reorder items at the same time, what goes wrong with dense integer positions and how do you handle the merge?

System DesignAlgorithms & Data Structures
Author's notes

I knew fractional indexing was a thing and mentioned it, which landed okay.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by explaining the problem with dense integer positions: concurrent reorders cause conflicts because updating one item's position requires shifting many others, leading to write conflicts and inconsistent ordering. Then describe a merge strategy using fractional or sparse ordering (e.g., LexoRank) to minimize conflicts, and outline how to handle concurrent updates via optimistic concurrency or operational transformation.

Pro tip: Mention that Asana likely uses a fractional indexing scheme like LexoRank, and emphasize the importance of idempotent operations and conflict resolution to maintain a consistent user experience.

1. Identify the problem with dense integers

Explain that dense integer positions require renumbering many items on each reorder, causing write contention and conflicts when multiple users reorder simultaneously.

2. Introduce sparse/fractional ordering

Propose using fractional or sparse positions (e.g., LexoRank) so that reordering only updates the moved item's position, reducing conflicts.

3. Describe conflict detection and resolution

Outline how to detect concurrent modifications (e.g., via versioning or timestamps) and resolve conflicts using last-write-wins, operational transformation, or CRDTs.

4. Explain merge strategy

Detail how to merge concurrent reorders: either serialize operations per list, use a merge algorithm that respects user intent, or employ a conflict-free replicated data type (CRDT) for ordering.

5. Discuss trade-offs and edge cases

Mention trade-offs like position precision limits, rebalancing strategies, and how to handle conflicts when two users insert at the same position.

Key Points to Mention

  • Dense integer positions cause O(n) updates and write conflicts on concurrent reorders.
  • Fractional indexing (e.g., LexoRank) allows O(1) updates by assigning positions between neighbors.
  • Optimistic concurrency control with version numbers or ETags to detect conflicts.
  • Conflict resolution strategies: last-write-wins, operational transformation, or CRDTs.
  • Rebalancing or periodic renumbering to avoid precision exhaustion.
  • Idempotent operations and client-side retries for robustness.

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

Q4

Walk through how a committed write reaches all other connected clients. What guarantees that the published event isn't lost if the message bus is briefly unavailable?

System DesignAPI & Integrations
Author's notes

Outbox pattern.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by outlining the end-to-end write path: client request → API server → database commit → event publication → message bus → fan-out to connected clients. Then focus on the reliability mechanisms (transactional outbox, idempotency, at-least-once delivery) that ensure the event is not lost if the bus is temporarily unavailable.

Pro tip: Emphasize the transactional outbox pattern and idempotent consumers—this shows you understand how to bridge the gap between database commits and message bus availability without sacrificing correctness.

1. Describe the write path

Walk through how a client write is received by the API server, validated, and persisted to the database in a single transaction.

2. Explain event publication

Detail how the committed write generates an event that is published to the message bus, and how the outbox pattern ensures atomicity between the DB commit and event publication.

3. Cover message bus delivery

Explain how the message bus (e.g., Kafka, RabbitMQ) durably stores events and guarantees at-least-once delivery to consumers, including retries and acknowledgments.

4. Describe fan-out to clients

Explain how consumers process events and push updates to connected clients (e.g., via WebSockets or long polling), handling idempotency and ordering where needed.

5. Address bus unavailability

Detail how the outbox pattern decouples DB commit from bus availability: events are stored in the outbox table and a relay process retries publishing until success, ensuring no loss.

Key Points to Mention

  • Transactional outbox pattern to atomically persist the write and the event
  • At-least-once delivery and idempotent consumers to handle duplicates
  • Message bus durability (persistent queues, replication) and retry mechanisms
  • Relay/publisher process that polls the outbox and publishes to the bus with backoff
  • Client connection management (WebSockets, heartbeats) and reconnection logic
  • Monitoring and alerting for outbox backlog and bus health

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

Q5

How does your design change if a single hot list suddenly has thousands of simultaneous editors instead of tens?

System DesignTechnical Trade-offs
Author's notes

Per-list serialization becomes the obvious bottleneck.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the current design assumptions (e.g., polling, locking, data model) and then systematically scale each component: client updates, server fan-out, storage contention, and conflict resolution. Emphasize trade-offs between consistency, latency, and cost, and propose a phased migration rather than a full rewrite.

Pro tip: Anchor your answer in Asana's real-time collaboration context: mention that hot lists are often a small fraction of total lists, so sharding by list ID and using a pub/sub fan-out with presence tracking is more practical than global locking. Show you'd measure first (e.g., edit rate, conflict frequency) before over-engineering.

1. Clarify current design and scale assumptions

Ask about the existing architecture (polling vs. WebSocket, DB choice, locking strategy) and define what 'thousands of simultaneous editors' means in terms of edit rate, list size, and consistency requirements.

2. Identify bottlenecks at each layer

Walk through client, API, real-time transport, application logic, and storage to pinpoint where contention arises: e.g., DB row locks, broadcast fan-out, presence tracking, and conflict resolution.

3. Propose scalable architecture changes

Suggest sharding by list ID, moving to a pub/sub model (e.g., Redis Pub/Sub or Kafka) for fan-out, using CRDTs or operational transforms for conflict-free merges, and caching hot list state in memory.

4. Address consistency and conflict resolution trade-offs

Discuss how to handle concurrent edits: optimistic concurrency with version vectors, CRDTs for automatic merges, or server-side serialization with a queue—each with latency and complexity trade-offs.

5. Outline migration and monitoring plan

Propose a phased rollout (e.g., feature flag, canary lists), define key metrics (edit latency, conflict rate, fan-out cost), and describe fallback strategies if the new system degrades.

Key Points to Mention

  • Sharding by list ID to isolate hot lists and avoid global contention
  • Pub/sub fan-out (e.g., Redis, Kafka) instead of direct DB polling or per-client queries
  • Conflict resolution via CRDTs or operational transforms, with trade-offs vs. locking
  • Presence and cursor tracking at scale using in-memory stores and throttled updates
  • Caching hot list state and using write-behind or batched persistence to reduce DB load
  • Phased migration with feature flags and monitoring of edit latency and conflict rates

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

Q6

An offline client made three edits while disconnected, two of which conflict with changes committed by others in the meantime. What happens on reconnect and what does the user see?

System DesignTechnical Trade-offsAdaptability & Ambiguity
Author's notes

I described replaying the client's ops against the current server state, detecting field-level conflicts, and surfacing them to the user for the ambiguous ones while auto-resolving the clean ones.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the sync model and conflict resolution strategy (e.g., operational transformation or CRDTs), then walk through the reconnect flow: detecting conflicts, resolving them, and presenting outcomes to the user. Emphasize user experience by describing how conflicts are surfaced and how the user can resolve them.

Pro tip: Highlight the importance of preserving user intent and minimizing data loss—show that you consider both technical correctness and user trust when designing conflict resolution.

1. Clarify the sync model

Briefly state assumptions about the system's sync architecture (e.g., server-authoritative, OT, or CRDTs) and how conflicts are detected.

2. Describe the reconnect process

Explain the sequence: client sends pending edits, server identifies conflicts, and applies a resolution strategy (e.g., last-write-wins, merge, or manual).

3. Detail conflict resolution for the two conflicting edits

For each conflict, describe how the system resolves it—either automatically (with rationale) or by flagging for user input—and what data is preserved.

4. Explain the user experience

Describe what the user sees: notifications of conflicts, a diff view, options to keep or discard changes, and how the non-conflicting edit is applied seamlessly.

5. Discuss trade-offs and edge cases

Mention trade-offs (e.g., automatic vs. manual resolution, complexity of CRDTs) and edge cases (e.g., multiple conflicts, offline duration) to show depth.

Key Points to Mention

  • Conflict detection mechanisms (e.g., version vectors, timestamps)
  • Resolution strategies: operational transformation (OT) vs. conflict-free replicated data types (CRDTs) vs. last-write-wins
  • User interface for conflict resolution: diff views, merge options, notifications
  • Preserving user intent and minimizing data loss
  • Handling the non-conflicting edit seamlessly
  • Trade-offs between automatic and manual conflict resolution

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

Q7

How do you prevent the operation log from growing indefinitely while still letting a client that's been offline for days catch up?

System DesignData Modeling
Author's notes

Said something about a compaction window and a snapshot at the compaction boundary so a client can bootstrap from the snapshot and replay only the tail.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements: how long clients can be offline, acceptable catch-up latency, and consistency guarantees. Then propose a hybrid approach: maintain a bounded operation log with periodic snapshots, and use a fallback mechanism (like a full state sync or snapshot) for clients whose last-seen sequence is older than the log retention window.

Pro tip: Mention that you'd monitor the distribution of client offline durations to tune the retention window, and consider a tiered storage approach (hot log in memory/SSD, cold log in object storage) to balance cost and catch-up capability.

1. Clarify requirements and constraints

Ask about maximum offline duration, acceptable catch-up time, consistency model, and storage budget to frame the design.

2. Design a bounded operation log

Propose a log with a retention window (e.g., time-based or size-based) and a sequence number per operation, so clients can request operations after their last-seen sequence.

3. Introduce periodic snapshots

Take snapshots of the full state at intervals, and store them alongside the log. Clients that are too far behind can start from the latest snapshot and then apply subsequent operations.

4. Define a fallback for stale clients

If a client's last-seen sequence is older than the log retention, have it fetch the latest snapshot (or a full state sync) instead of replaying operations, ensuring it can still catch up.

5. Address operational concerns

Discuss monitoring, tuning retention based on client behavior, and using tiered storage (e.g., cold storage for older operations) to extend catch-up capability without unbounded growth.

Key Points to Mention

  • Sequence numbers or versioning for operations to track client progress
  • Log retention policies (time-based, size-based) and truncation
  • Periodic snapshots of full state to bound replay
  • Fallback to snapshot or full sync for clients beyond retention
  • Tiered storage (hot vs. cold) to balance cost and catch-up window
  • Monitoring client offline durations to tune retention and snapshot frequency

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

Q8

If you needed to add collaborative rich-text editing inside an item's description, what would you change and why is that harder than syncing item fields?

System DesignTechnical Trade-offs
Author's notes

Character-level concurrency is a different beast from field-level last-write-wins.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by contrasting the data models: item fields are small, independent values that can be synced with simple last-write-wins or field-level versioning, while rich-text descriptions are structured documents requiring operational transformation or CRDTs to merge concurrent edits. Then outline the concrete changes—document model, sync protocol, presence, and conflict resolution—and explain why each adds complexity beyond field syncing.

Pro tip: Emphasize that the hard part isn't storing rich text but merging concurrent edits without losing user intent—mention that Asana likely already has a real-time sync layer for fields, so the key is extending it with a document-aware conflict resolution strategy rather than building a separate system.

1. Contrast data models

Explain that item fields are atomic, independently versioned values, whereas a rich-text description is a structured document with nested formatting and ordering, making concurrent edits interdependent.

2. Identify required changes

List the changes: a document model (e.g., ProseMirror/CRDT), a sync protocol supporting fine-grained operations, presence/awareness, and a conflict resolution algorithm (OT or CRDT).

3. Explain why it's harder

Detail the challenges: concurrent edits can conflict semantically (e.g., two users editing the same paragraph), operations must be transformed against each other, and you need to preserve intent and formatting.

4. Discuss trade-offs

Compare OT vs CRDTs in terms of complexity, latency, offline support, and server requirements, and mention how to integrate with existing field sync (e.g., separate channels or unified protocol).

5. Address operational concerns

Cover presence, undo/redo, version history, permissions, and performance at scale, showing awareness of production challenges beyond the core algorithm.

Key Points to Mention

  • Atomic fields vs. structured document model
  • Operational Transformation (OT) vs. CRDTs for concurrent editing
  • Fine-grained operations and transformation against concurrent edits
  • Presence and awareness (cursor positions, selections)
  • Integration with existing sync layer and backward compatibility
  • Offline support and conflict resolution semantics

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