Notion · Software Engineer
Updated · 2026-09-24

Notion Software Engineer
Interview Guide

THE 60-SECOND BRIEF

The source notes describe the role as building features that users rely on to organize their knowledge and work, with the role description centered on the editor and the tools around it. The reported design questions ask about real-time collaboration on a shared document, a notification service at large scale, and data storage choices for collaborative documents. The coding questions mix practical implementation, such as a rate limiter or a slow React component, with standard data-structure problems.

This guide covers the four rounds candidates report: Technical Screen, System Design Interview, Product Vision Discussion and Leadership Round. It groups the reported questions by category (coding, system design, behavioral), because the sources do not say which round asks which question. It then adds original SQL, coding, design and debugging drills, three of them with worked solutions, and a 7-day plan that gives each round its own preparation.

Notion candidates report 4 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.

Scope every query and cache key by tenantKeep money in integer minor unitsBuild at-least-once pipelines with explicit deduplication horizons

36 min read

Practice 13 Software Engineer prompts
6Company bank questionsSnapshot · Sep 24, 2026 PT
1Candidate experiences ↗Read their reports
13Practice promptsAcross five skill areas
3With worked solutionsIncluded in the practice prompts

The source notes describe the Software Engineer role at Notion as product engineering: building the underlying architecture and the user-facing features of the editor and the tools around it, and working with product managers and designers to turn user needs into technical specifications. The same role description mentions peer code review and on-call rotations for diagnosing production issues.

The reported questions reflect that mix. On the implementation side, candidates report being asked how to rate-limit an API, how to find out why a React component loads slowly, how to keep data consistent in a distributed system, and how they approached refactoring a legacy codebase. On the design side, they report real-time collaboration on one document, a notification service for millions of users, relational versus NoSQL storage, and monitoring for a high-traffic service. The PracHub bank adds problems tagged to this company and role: a text editor with undo/redo, a to-do-list object model, a recursive React JSON viewer, table aggregation, top errors in a time window, and a shared calendar service.

For preparation, practice explaining why you made a technical choice, as well as what you chose. Most of the reported design prompts have more than one reasonable answer. An answer that names the trade-off, says which user-visible behavior it protects, and says what it costs will hold up better under follow-up questions than one that just names a technology.

01

Technical Screen

reported

Candidates report that this round is an initial technical assessment of coding and problem-solving. The reported coding questions are practical: a rate limiter for an API, finding the slow part of a React component, keeping data consistent across services. The question list in the source notes also includes standard problems, such as the first unique character in a string, the lowest common ancestor in a binary tree and checking a Hankel matrix, plus a chess game design. The PracHub bank for the role has object-modeling tasks, such as a to-do list and a text editor with undo/redo. Prepare for both kinds. Say what the input looks like before you choose a structure. Name the simple solution and its complexity before you improve it. Then write code another engineer could maintain, with clear names and small functions.

What to demonstrate

  • Whether you can turn a loosely worded practical prompt, such as rate-limiting an API, into a concrete interface with stated inputs, outputs and failure behavior before writing code
  • Whether your data-structure choice follows from the operations the problem needs, for example a frequency map for first-unique-character or two stacks for undo/redo
  • Whether the code you write is clean and testable, and whether you check it against edge cases yourself instead of waiting for them to be pointed out

How to prepare

  • Solve the standard problems from the source notes' question list (first unique character, lowest common ancestor, Hankel matrix check) and say the time and space complexity out loud before writing each one
  • Implement a text editor with undo/redo and a to-do-list object model from a blank file, then add one feature to each and check how much of your design had to change
  • Implement a token-bucket rate limiter as a class with an injectable clock, and write tests for burst, refill and the boundary where a request is exactly at capacity
PracHub interview research
02

System Design Interview

reported

Candidates report this as an in-depth discussion of system design principles and architecture. The reported design questions include real-time collaboration for multiple users on one document, a notification service that scales to millions of users, relational versus NoSQL storage, database structures for a collaborative editor, and monitoring for a high-traffic service. The source notes list these topics for the area: sharding and partitioning, caching and latency, and event-driven architectures with message queues. Ask for the scale and access pattern first. Separate the read path from the write path. Name the consistency you need and where staleness is acceptable. Then go deep on the hardest part, such as concurrent edits for the collaboration problem or fan-out and retries for notifications.

What to demonstrate

  • Whether you settle requirements and scale before drawing components, and size the simplest design that meets them
  • Whether you can explain how concurrent edits to one document converge, for example operational transformation versus CRDTs, and what each costs
  • Whether you name the failure modes (a slow consumer, a duplicate delivery, a partition) and describe the recovery path for each
  • Whether you can justify a storage choice by the queries it makes cheap and the ones it makes expensive

How to prepare

  • Design real-time collaboration end to end: the operation format, how the server orders operations per document, how an offline client reconciles, and how a new client loads a snapshot plus recent operations
  • Design the notification service with fan-out through a queue, per-channel workers, idempotency keys, user preferences and retry with backoff, then say what you drop first under overload
  • For monitoring, write down the few service-level indicators you would alert on, where each is measured, and which dashboards or traces you would use to diagnose rather than to page
PracHub interview research
03

Product Vision Discussion

reported

Candidates report this round as an exploration of your understanding of product vision and alignment with company goals. The sources give no format, so prepare material that works as either a conversation or a structured exercise. Use the product for real work before the round. Form a specific opinion about one feature: who it serves, what is hard about it technically, and what you would change. Connect each opinion to an engineering consequence. The source notes also list product and technical strategy topics, such as balancing speed against technical debt and building a custom solution versus using an existing library; they do not tie them to a round, but they are useful material for this conversation.

What to demonstrate

  • Whether your view of the product is concrete, tied to a specific workflow or feature rather than to general praise
  • Whether you connect a technical trade-off to what a user experiences, such as latency while typing, sync conflicts or permission surprises
  • Whether you can prioritize: what you would build first, what you would defer, and what signal would change your mind

How to prepare

  • Use the product for a real task over several days, and write down three frictions you hit, each with a likely technical cause and a fix you could scope
  • Prepare one feature proposal on a single page: the user problem, the smallest version worth shipping, the main technical risk and how you would measure whether it worked
  • Rehearse a build-versus-buy answer with a real example from your own work, including the cost you accepted on the side you chose
PracHub interview research
04

Leadership Round

reported

Candidates report this as a final assessment of leadership and the broader business impact of engineering work. The sources do not tie specific questions to this round, but the reported behavioral questions are the closest match to its description: a disagreement with a product manager and how you resolved it, a project with a lot of ambiguity, balancing fast shipping against technical debt, your approach to mentoring junior engineers and building an inclusive team, and why you want to work at Notion. Pick stories where you made the decision. Give the business or user result along with the technical one. Keep the facts consistent with anything you said in earlier rounds.

What to demonstrate

  • Whether your stories show you making and owning a decision, including the alternative you rejected and why
  • Whether you can explain the business or user impact of engineering work, not only the technical outcome
  • Whether you describe disagreement and ambiguity with a concrete resolution, and state accurately what other people contributed

How to prepare

  • Write one story for each reported prompt (PM disagreement, ambiguity, speed versus debt, mentoring, legacy refactor), each with a measurable outcome and the decision that was yours
  • For the technical-debt story, state the criterion you used to decide when debt had to be paid, not only the outcome
  • Prepare a specific answer to why Notion, drawn from your product notes for the Product Vision Discussion, so the two rounds tell the same story
PracHub interview research

1 candidate reports. Individual accounts describe a particular role and hiring cycle.

PracHub editorial advice for the preparation topics above.

01

Answering the rate-limiter question with an algorithm name and no interface, state or failure behavior

Before coding, define what is limited (per user, per API key or per workspace), the limit and window, and what a rejected caller receives, typically HTTP 429 with a retry hint. Pick token bucket or sliding window and say why: token bucket allows controlled bursts, a sliding-window log is exact but stores every timestamp. Then say where the state lives once there is more than one server, and how an increment stays atomic there. Write it as a small class with an injectable clock so it can be tested.

02

Designing real-time collaboration without explaining how concurrent edits converge

A diagram of WebSockets and a database does not answer the question. Say how two users editing the same paragraph end with the same document. One option is a server that orders operations per document and transforms them (operational transformation). The other is data structures that merge without coordination (CRDTs). Explain what each costs in complexity and metadata. Cover the offline client that reconnects with queued edits, and how a new client loads a snapshot plus the operations after it.

03

Saying 'use strong consistency' or 'use NoSQL for scale' without naming what the data needs

For the reported data-consistency and relational-versus-NoSQL questions, name the guarantee each piece of data needs. A permission change may need read-your-writes. A view counter can be eventually consistent. Then name the mechanism that provides it: a single-leader transaction, an idempotency key on retried writes, or an outbox for events that must follow a commit. Justify a storage choice by the queries it makes cheap and the queries or joins it makes expensive.

04

Treating the Product Vision Discussion as a chance to praise the product

General enthusiasm is easy to say and hard to evaluate. Arrive with specific observations from using the product: a workflow that is slow, a sync or permission behavior that surprised you, a feature you would scope differently. Give the likely technical cause of each and what a first version of the fix would ship. When asked what to build, give a priority order and the signal that would change it.

05

Telling leadership stories in which the team did everything and your own decision is missing

For the reported prompts (PM disagreement, ambiguity, speed versus technical debt, mentoring), say what you decided, what you rejected, and what happened to users or the business as a result. Credit other people's parts accurately. Keep team size, timeline and your role the same in every telling, because the final round may go deeper on a project you already described.

Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.

10 technical prompts3 include a worked solution

How would you design a rate-limiting mechanism for our API?

medium
data structures and algorithms

How would you design a rate-limiting mechanism for our API?

Approach
  1. Walk one small example through your approach before writing the whole thing.
  2. Name the brute-force solution and its complexity before improving on it.
  3. State the target complexity and say which constraint rules the naive version out.
Follow-up
  • How does this change if the input no longer fits in memory?
  • Which test case would catch an off-by-one here?

How do you ensure data consistency in a distributed system?

medium
data structures and algorithms

How do you ensure data consistency in a distributed system?

Approach
  1. Choose the data structure from the access pattern, not from familiarity.
  2. Walk one small example through your approach before writing the whole thing.
  3. State the target complexity and say which constraint rules the naive version out.
Follow-up
  • Which test case would catch an off-by-one here?
  • How does this change if the input no longer fits in memory?

Fold a deduplicated usage stream into hourly rollups

easyWorked solution
aggregationdeduplicationwatermarksexact-arithmetic

You are given one day of usage_event rows, up to 250 million, each carrying event_id, tenant_id, workspace_id, environment, sku, quantity numeric(20,6), idempotency_key, occurred_at and ingested_at. Produce usage_rollup_hourly cells keyed (tenant_id, workspace_id, sku, hour_start) with quantity_sum, event_count and source_max_ingested_at. An event counts once per (tenant_id, idempotency_key). The rollup grain has no environment column, so state your filter. One pass. Give your time and space bounds, and say what the deduplication actually costs in memory.

Approach
  1. Bucket on occurred_at, never ingested_at: hour_start = date_trunc('hour', occurred_at at time zone 'UTC'). The two columns answer different questions. occurred_at says which hour the customer is billed for; ingested_at says how current the fold is. Using the second for the first makes late data invisible instead of correctable.
  2. The fold is trivial and the deduplication is the entire cost, so price it before designing anything clever. An exact set over (tenant_id, idempotency_key) at 250M entries, stored as a 16-byte 128-bit hash in an open-addressed table at 0.7 load factor, needs about 357M slots at 16 bytes each, roughly 5.7 GB. The fix is partitioning by hash(tenant_id) % P so each shard holds 1/P of the set and no tenant's keys straddle shards.
  3. Rule out a Bloom filter as a replacement, in the right direction: a false positive reports 'already seen' for an event never seen, so you drop a real event and lose revenue with no error raised. It is usable only as a negative pre-filter in front of the exact set, where a miss is conclusive and a hit must fall through to the real lookup.
  4. Accumulate in scaled integers, not binary floating point. numeric(20,6) admits values below 10^14, so one event scaled to micro-units can reach 10^20, past int64's 9.22 x 10^18; use a 128-bit or arbitrary-precision accumulator unless you first bound the per-event maximum. binary64 represents integers exactly only to 2^53, about 9.01 x 10^15, and cannot represent 0.1 at all, so two runs that sum in different orders disagree.
  5. Carry source_max_ingested_at = max(ingested_at) over the events folded into each cell, and count event_count over accepted, post-dedup events. Without that watermark there is no way to prove later what a number did and did not include, which is the first question any reconciliation asks.
  6. State the environment filter explicitly, because the rollup grain cannot record it. A fold that quietly includes staging bills non-production traffic; one that quietly excludes it loses a cost signal. Production-only is the billing answer, and either way it belongs in the job name and the output metadata. Complexity: O(n) time, O(distinct dedup keys) space, dominated by the dedup set rather than by the cells.
Worked solution 25 min
  1. Write both key tuples down before any code: dedup key (tenant_id, idempotency_key), cell key (tenant_id, workspace_id, sku, hour_start), with hour_start derived from occurred_at in UTC.
  2. Build a 10,000-row fixture containing one event duplicated three times under the same idempotency_key, two events sharing an idempotency_key across different tenant_id values, one event whose occurred_at is two hours before its ingested_at, and one staging event inside an otherwise production cell.
  3. Fold it and assert each of those four expectations separately rather than eyeballing a grand total.
  4. Re-run with the input shuffled and diff the output files.
  5. Size the dedup set for 250M keys using the load-factor arithmetic and write the number down next to the fixture.
EXPECTED RESULTThe triplicate contributes one event and its quantity once. The two same-key, different-tenant events both count, because the dedup key is the pair. The late event lands in the hour of its `occurred_at` while that cell's `source_max_ingested_at` advances to the later timestamp. The `staging` event is included or excluded per the stated filter and never silently.
Follow-up
  • A producer retries at 23:59:59 and the retry lands at 00:00:01. The unique index on the daily-partitioned table must include the partition key. What gets double-counted, and what is the smallest change that fixes it?
  • The consumer acknowledges its batch before committing the fold. Which failure loses revenue now, and which arrangement duplicates instead?
  • What makes a re-run over the same day produce byte-identical rollups?

For someone who has spent the last few years shipping features and reading other people's code, and who has not solved a timed problem from a blank file in a long time. Five days rebuild the primitives and the patterns that sit on them, working from invariants rather than remembered solutions, and the last two attach that back to the rest of the loop.

Small steps. Visible outcomes.0 / 7 completed
ONE WEEK · YOUR PACE

Prepare, practise & reflect

One practical outcome each day. Spend longer where you need it.

0 / 7 done
01Technical Screen: data-structure fundamentals
  • Solve first unique character index with a frequency map, and state why two passes over the string are still linear
  • Solve lowest common ancestor in a binary tree recursively. Then state what changes if the tree is a binary search tree, or if nodes have parent pointers
  • Solve the Hankel matrix check: every anti-diagonal must be constant, so compare each cell a[i][j] with its upper-right neighbor a[i-1][j+1]. Note that comparing with the upper-left neighbor tests the Toeplitz property instead. List the edge cases: a single row, a single column, a non-square matrix
  • Before writing each solution, say its complexity and the input size it handles

Deliverable: Three solved problems, each with its complexity stated before the code and a list of edge cases you tested.

Practice prompt ↗Practice prompt ↗Worked solution ↗
02Technical Screen: practical implementation and object modeling
  • Build a text editor with undo/redo using two stacks of operations, and state why a new edit clears the redo stack
  • Design a to-do-list object model, then add sharing or due dates and note which classes had to change
  • Implement a token-bucket rate limiter with an injectable clock and tests for burst, refill and exact-capacity requests
  • Work through the guide's worked coding exercise, Fold a deduplicated usage stream into hourly rollups, and check your deduplication key against its expected result

Deliverable: Working editor, to-do model and rate limiter, each with tests, plus a note on what the added feature forced you to redesign.

Practice prompt ↗Practice prompt ↗
03Data modeling and consistency
  • Answer the reported relational-versus-NoSQL question for document data. Write out the access patterns first, then the store each one favors
  • Write a short answer on data consistency in a distributed system that names at least two guarantees (such as read-your-writes and eventual consistency) and a mechanism for each
  • Complete the worked SQL exercise on credential revocation and the keyset pagination drill, and say why OFFSET skips rows on a growing table

Deliverable: A one-page data-modeling note covering storage choice, consistency guarantees and pagination, backed by the two SQL drills.

Practice prompt ↗Practice prompt ↗
04System Design Interview: real-time collaboration
  • Design real-time collaboration on a single document: operation format, per-document ordering, OT versus CRDT, presence, and offline reconnection
  • Answer the reported question on database structures for a collaborative editor: how blocks or operations are stored, and how a document loads quickly
  • Stress the design: two users editing the same text, a client offline for a day, and a document with very large history

Deliverable: A design diagram with a written explanation of how concurrent edits converge and how a client recovers after reconnecting.

Practice prompt ↗Practice prompt ↗Worked solution ↗
05System Design Interview: notifications, observability and debugging
  • Design the notification service: fan-out through a queue, per-channel workers, user preferences, idempotency keys, retries with backoff and a dead-letter path
  • Define the monitoring for a high-traffic service: the indicators you alert on, where each is measured, and what you use to diagnose rather than to page
  • Work through the guide's worked design exercise on a resumable usage export, and the webhook memory-leak debugging drill

Deliverable: A notification-service design with failure handling, an alerting list for one service, and an ordered debugging checklist.

Practice prompt ↗Practice prompt ↗
06Product Vision Discussion
  • Use the product for a real task and write down three frictions, each with a likely technical cause and a fix you could scope
  • Write a one-page feature proposal: user problem, smallest shippable version, main technical risk, and how you would measure success
  • Prepare answers to the reported questions on shipping speed versus technical debt and building a custom solution versus using a library, each with an example from your own work

Deliverable: Product notes with three frictions, one scoped feature proposal, and two trade-off answers you have said out loud.

Practice prompt ↗Practice prompt ↗
07Leadership Round and full rehearsal
  • Write one story for each reported behavioral prompt: PM disagreement, ambiguity, speed versus debt, mentoring and inclusion, legacy refactor, and why Notion
  • For each story, mark the decision that was yours, the alternative you rejected, and the user or business result
  • Rehearse the reversed-decision drill in this guide as a model for a story that includes the measurement that changed your mind
  • Run a mock with a peer: one coding problem from day 1 or 2, one design problem from day 4 or 5, and two behavioral stories. Note where your facts shifted between tellings

Deliverable: A story bank covering every reported behavioral prompt, and a mock-session list of the answers that need another pass.

Practice prompt ↗Worked solution ↗

Expand any day for tasks and deliverables. Your progress is saved on this device.

The reported behavioral questions for this role cover a disagreement with a product manager, a project with a lot of ambiguity, balancing fast shipping against technical debt, mentoring junior engineers and building an inclusive team, refactoring a legacy codebase, and why you want to work at Notion. For each one, state the situation briefly. Spend most of the answer on the decision you made and the alternative you rejected. Close with a measurable result and what you would change.

Why do you want to build at Notion specifically?

medium
behavioural and engineering judgement

Why do you want to build at Notion specifically?

Approach
  1. Pick a story where you made the decision, not one where you watched it.
  2. Name the disagreement and how you resolved it with evidence.
  3. State the situation in two sentences and spend the rest on the reasoning.
Follow-up
  • How did you know your change caused the improvement?
  • What did you decide not to do, and why?

Describe a time you had to refactor a legacy codebase; what were your …

medium
behavioural and engineering judgement

Describe a time you had to refactor a legacy codebase; what were your primary considerations?

Approach
  1. Close with what you would do differently, concretely.
  2. Pick a story where you made the decision, not one where you watched it.
  3. Name the disagreement and how you resolved it with evidence.
Follow-up
  • What did you decide not to do, and why?
  • How did you know your change caused the improvement?

Reverse a webhook ordering decision after measuring its cost

medium
reversing decisionshead-of-line blockingat-least-onceapi contracts

You argued for strict per-subscription ordering in webhook-delivery, which means one in-flight attempt per subscription. It shipped. Three months later a single unresponsive endpoint holds one subscription's queue at a six-hour backlog, and two customers report events arriving out of order anyway once their own retries are counted. Describe a decision you reversed: what you originally optimised for, the measurement that changed your mind, what the reversal cost in engineering time and customer change, and how you told the people who had already built on the original guarantee.

Approach
  1. State the original decision as a trade you made knowingly. Ordering across a network requires a single in-flight attempt per subscription, and its price is head-of-line blocking whenever one endpoint is slow. 'We priced it wrong' is a much stronger opening than 'we did not realise', and it is usually the true one.
  2. Bring the measurement that flipped it, not the anecdote: backlog age at the ninety-ninth percentile per subscription, the share of subscriptions where one slow endpoint gated an otherwise healthy queue, and the delivery throughput lost to serialisation. A reversal justified by complaints is indistinguishable from a reversal justified by fatigue.
  3. Name what you learned about the guarantee itself, which is the engineering content of this story. At-least-once delivery means a retried event already arrives after newer ones and the consumer already must be idempotent, so a guarantee the customer has to defend against anyway was never worth what it cost to provide.
  4. Describe the migration, because reversing a published contract is the hard half and the part candidates skip. Parallel attempts behind a per-subscription flag, a monotonically increasing sequence number added to the envelope so order-sensitive consumers can sort or discard, documentation that states at-least-once and unordered in those words, and a deprecation measured in quarters because the client is a pinned SDK inside a build pipeline you cannot see or redeploy.
  5. Give the cost in the two currencies that matter: engineer-weeks, and how many customers had to change code. Then say who you told before it shipped rather than in a changelog afterwards, and which large customer you left on the old behaviour and for how long.
  6. Close with the signal you now weight differently, stated as something you would do earlier next time: measuring the blocking cost on the slowest decile of endpoints before committing to the guarantee, rather than after a customer noticed.
Follow-up
  • A customer insists they need ordering. What do you offer them that is not global serialisation?
  • How did you choose the deprecation window given that you cannot see or redeploy the clients?
  • What would have to be true for you to reverse back?
  • 01

    Tell me about a time you had a disagreement with a product manager; how did you resolve it?

  • 02

    Describe a project where you had to navigate significant ambiguity.

  • 03

    How do you balance the need for shipping features quickly versus maintaining technical debt?

  • 04

    What is your approach to mentoring junior engineers and fostering an inclusive team environment?

  • 05

    Describe a time you had to refactor a legacy codebase; what were your primary considerations?

  • 06

    Why do you want to build at Notion specifically?

PracHub interview preparation framework
Is this an official Notion interview guide?

No. It is PracHub's own research and practice material for the Software Engineer role at Notion. Rounds and questions reflect what candidates have reported, not a process Notion has published, and they change over time. Confirm the current format and scope with your recruiter.

PracHub interview research
Which rounds do candidates report for the Notion Software Engineer loop?

Candidates report four: a Technical Screen, a System Design Interview, a Product Vision Discussion and a Leadership Round. The sources do not tie specific questions to specific rounds, so this guide groups the reported questions by category. Ask your recruiter what each round covers and whether you will write code in it.

PracHub Software Engineer practice
How long should I prepare for the interview process?

The source notes suggest two to four weeks of focused preparation. How much you need depends on your starting point. If you have not solved coding problems from a blank file recently, give the Technical Screen material extra days. If you have not led a design discussion recently, spend more time on the collaboration and notification designs. The 7-day plan in this guide is a minimum pass over every round, not a replacement for that preparation.

PracHub interview research
Are the coding questions algorithm puzzles or practical problems?

Both appear in the reported material. The coding questions candidates report are practical: rate-limiting an API, speeding up a slow React component, keeping data consistent in a distributed system. The question list in the source notes also includes standard problems, such as first unique character, lowest common ancestor and a Hankel matrix check. The PracHub bank for this role adds object-modeling tasks such as a to-do list and a text editor with undo/redo. Prepare for both, and practice explaining your design choices as you code.

PracHub Software Engineer practice
How should I prepare for the Product Vision Discussion?

Candidates describe this round as covering your understanding of product vision and alignment with company goals. The sources give no format. Use the product for real work beforehand. Form specific opinions about a few features, each with a likely technical cause and a scoped fix. Be ready to connect engineering trade-offs, such as shipping speed versus technical debt, to what a user experiences.

PracHub Software Engineer practice
What is the timeline from the first screen to an offer?

Candidate-reported figures put the process at roughly three to five weeks, and one source note gives three to six. Timelines depend on scheduling and team. Ask your recruiter for the expected sequence and when decisions are communicated.

PracHub interview research
Sources & methodology 3 sources ↗

Official role evidence, timestamped platform data and clearly labeled preparation advice.