District by Zomato · Software Engineer
Updated · 2026-10-02

District by Zomato Software Engineer
Interview Guide

THE 60-SECOND BRIEF

District by Zomato is described by candidates as a consumer platform whose backend handles food delivery traffic in real time. The features that candidates list for this role include notification services, order management and user engagement platforms, all of which have to cope with sharp traffic spikes while keeping latency low. A Software Engineer here is described as building and maintaining the backend services behind those features, working with product managers and other engineers, and following the code from design review through to ownership of what ships.

This guide is for candidates interviewing for the Software Engineer role at District by Zomato, including SDE-1 level applications. It covers the reported system design questions, the topics candidates connect with the loop (notification systems, high-level design, multi-channel delivery, DSA), the stack named in the role requirements (Java, Go or Python, relational and NoSQL databases, cloud and containers as extras), and a plan for the days before the interview.

No round names, order or count are reported for this loop. What candidates report is a mix of coding and system design, with the design questions centred on notification systems and distributed-systems trade-offs.

Notification System DesignHigh-Level Design (HLD)Multi-Channel Notifications

30 min read

Browse Software Engineer questions

See the practice prompts

12Practice promptsAcross five skill areas

The reported questions all sit in system design, and two of the three are about the same system: a notification service for a food delivery platform, and how that service handles push, SMS and email. The third is broader, asking how you keep a distributed system both available and consistent. Candidates also describe example scenarios such as a sudden surge of notifications at peak hours and the trade-off between a message queue and direct service-to-service calls. If you can walk through one notification design end to end and then re-use its parts to answer those variants, you cover most of what is reported.

The role description candidates give is backend-heavy: services that take significant traffic spikes, low-latency paths balanced against scalability, and features such as order management and user engagement. That points your preparation at concrete building blocks: an ingestion API with an idempotency key, a durable queue, per-channel workers, retry with backoff and a dead-letter path, user preference storage, and the database choice behind each. Pick Java, Go or Python (the languages the requirements name) and be able to write the coding side in it without hesitation.

Coding is reported alongside design, with an emphasis on data structures and algorithms; candidates for SDE-1 positions mention that foundational knowledge matters as much as practical application. Spend design time on the order a structured answer follows: clarify load and constraints, define the API, sketch the high-level design, then go deep on one or two components. Say your assumptions aloud as you go, because a silent pause hides your reasoning.

Candidates also report questions about past projects, technical challenges and team disagreements, so keep two or three real stories ready with the decision you made and its result. The role asks for communication and for coping with shifting priorities; a story where a plan changed mid-way and you adapted is more useful than a generic success.

01

Preparation focus

editorial

No round names, order, count or durations are reported for this loop, so treat the recruiter as the source for the format and ask whether each stage is coding, design or a conversation about past work. What candidates do report is the content: system design (notification systems, distributed systems, API design), data structures and algorithms, and questions about previous projects, technical challenges and disagreements with teammates. The three reported design questions are the notification system for a food delivery platform, handling push, SMS and email in one notification service, and ensuring high availability and consistency in a distributed system. Prepare by building one complete notification design you can narrate in order (requirements, API, high-level components, then failure handling and scale), and keep a coding language of your choice warm for algorithm problems.

What to demonstrate

  • Whether you can structure an open-ended design: constraints first, API next, then components and their trade-offs
  • Command of distributed-systems basics reported for the loop: CAP theorem, load balancing, sharding, caching and message queues
  • Working code on data structures and algorithms in a language such as Java, Go or Python
  • How clearly you explain past projects and technical decisions

How to prepare

  • Ask the recruiter for the stage sequence and whether coding is on a shared editor or a whiteboard, then practise in that setup
  • Rehearse the notification system design aloud from the order-placed event through to a delivered push, SMS or email, including retries and de-duplication
  • Prepare the queue versus direct service-to-service comparison and the peak-hour surge answer, since candidates report both as example scenarios
  • Practise DSA problems in one backend language and explain each choice of data structure and its complexity
PracHub preparation framework ↗

PracHub editorial advice for the preparation topics above.

01

Jumping to boxes and arrows for the notification system without asking about load, latency or which events trigger a message

Open with a short list of questions: events that trigger notifications, expected peak rate, acceptable delay per channel, and whether losing or duplicating a message is worse. Write the answers on the board and design against them.

02

Treating push, SMS and email as one code path with a switch statement, so a slow SMS provider stalls everything

Describe a channel abstraction with an adapter per provider, a separate queue and worker pool per channel, and independent retry and failure handling. Say which channel falls back to which and what the user preference store decides.

03

Saying a queue 'makes it reliable' without addressing duplicates, ordering or poison messages

State the delivery guarantee you are choosing (usually at-least-once), add an idempotency key so a retried send is not delivered twice, and name the retry limit, backoff and dead-letter queue for messages that keep failing.

04

Answering the availability and consistency question with a memorised CAP definition and no example

Pick two data items in the notification system, such as a preference record and a delivery-status log, and say which needs strong consistency, which can be stale, and which replication or quorum setting you would use for each.

05

Solving the coding problem silently and presenting only the final code

State the brute-force approach and its complexity first, name the data structure that improves it, then code while narrating; finish by testing an empty input and a duplicate-heavy input.

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

9 technical prompts0 include a worked solution

Identify the heaviest tenants in a five-minute window under memory pressure

medium
top-kheavy hittersstreaming

The edge service handles about 3,000 requests per second across roughly 50,000 tenants, peaking near 9,000. Expose the 50 heaviest tenants by request count over the trailing five minutes so limits can be tightened before one tenant's backfill starves the fleet. You may not retain five minutes of raw records. Give the exact solution and its memory, then the bounded-memory approximation with its error stated as a formula, and say which you would ship and at what tenant cardinality that choice changes.

Approach
  1. Do the exact version first, because it is affordable at this cardinality: a ring of 300 one-second counters per tenant, advanced lazily, is 1,200 bytes of counters per tenant and roughly 60 to 90 MB for 50,000 tenants with overhead. Carry a running total and subtract the bucket you overwrite so a window read is O(1) rather than 300 adds.
  2. Extract the top 50 with a size-k min-heap over the tenant sums: O(d log k) for d tenants, against O(d log d) to sort them all. Maintaining the heap continuously instead of on query requires a tenant-to-heap-index map, because incrementing a count already inside the heap means sifting from a known position, and without that map you rebuild the heap on every request.
  3. State the approximation precisely rather than gesturing at sketches. Misra-Gries with m counters retains every item whose true count exceeds N/(m+1), and each retained count underestimates the truth by at most N/(m+1). With m = 1,000 and N = 900,000 requests in the window the error is roughly 900 requests, which is fine for spotting a tenant sending 50,000 and useless for ranking two tenants 200 apart.
  4. Say what breaks when the window slides: Misra-Gries and Space-Saving are insert-only and cannot be decremented as records age out. The workable construction is one summary per sub-window, say ten seconds, with 30 summaries merged at query time, and the merged error is the sum of the per-summary errors, so the bound degrades linearly in the number of sub-windows.
Follow-up
  • The heaviest tenant is heavy because of one export job rather than user traffic. Should the limiter treat those as the same tenant?
  • Two tenants sit tied at the boundary of the top 50. Does your answer flap, and does the flapping matter?

Canonicalise a request body into a stable idempotency fingerprint

medium
parsingcanonicalisationhashing

idempotency_key.request_fingerprint is a SHA-256 over the method, path and canonicalised body, and a retry whose fingerprint differs must be rejected with 422 rather than served the stored response. Write the canonicaliser. Bodies are JSON up to 256 KB nested at most 32 levels; clients vary key order, whitespace and unicode escaping, and some send 64-bit ids as JSON numbers. Produce a deterministic byte string such that semantically identical bodies match and any semantic difference does not. State your complexity and name two normalisations you refuse to perform.

Approach
  1. Parse once into a tree, then re-serialise under fixed rules: object keys sorted, array order preserved, one escaping convention, no insignificant whitespace. Parsing is O(n) and sorting keys is O(k log k) per object, so O(n log n) overall with O(depth) stack, and the 32-level cap is enforced during parsing because hostile nesting is how a canonicaliser becomes a stack overflow.
  2. Sort keys by their UTF-8 bytes and say why the obvious implementation is wrong in some runtimes: a default string comparison that orders by UTF-16 code units places surrogate pairs, meaning code points from U+10000 up, below U+E000 to U+FFFF, which is not UTF-8 byte order, so two services written in different languages disagree on the same document.
  3. Do not re-encode numbers through a double. IEEE-754 binary64 represents integers exactly only up to 2^53, so normalising a 19-digit id through a float changes it, and 1 against 1.0 cannot be reconciled without deciding whether they are the same value. Preserve the literal token, and require ids as strings at the API boundary if you want them comparable.
  4. Reject duplicate keys rather than picking one. JSON permits them and parsers disagree, most keeping the last, so any choice you make ties the fingerprint to a parser detail that the code handling the request does not necessarily share.
Follow-up
  • A client sends the same logical request with an extra field your API ignores. Same key, different fingerprint, so you return 422. Is that the right answer?
  • Where does the fingerprint get computed relative to request decompression and the body-size limit?

Find overlapping job attempts and peak concurrency from lease records

medium
sweep lineintervalsleases

A day of job_run history yields about 50,000,000 attempt records: (job_run_id, job_type, attempt, started_at, finished_at which is NULL when the worker died, lease_expires_at). Leases expire on a clock, so a job that outran its lease ran twice. Produce (a) every job_run_id whose attempts overlapped in wall-clock time and (b) the peak number of simultaneously running attempts per job_type with the minute it occurred. Target O(n log n). State how you treat a NULL finished_at and what clock skew does to your answer.

Approach
  1. Define the interval before sorting anything: an attempt occupies [started_at, COALESCE(finished_at, lease_expires_at)). finished_at is observed and lease_expires_at is only a promise, so every attempt without a finish contributes an estimate and the whole result is a lower bound on overlap rather than an exact count.
  2. For peak concurrency, sweep: emit 2n endpoints, sort by (timestamp, kind) with ends ordered before starts at equal timestamps, then walk the sequence maintaining a counter per job_type and record each type's maximum with its timestamp. O(n log n) dominated by the sort, O(n) space, or O(1) extra if the sort is external and the walk streams.
  3. For overlap detection, do not compare attempts pairwise. A single global sort by (job_run_id, started_at) gives both the grouping and the order; within a group, keep the maximum end seen so far and report an overlap exactly when the next start is less than that running maximum, which is one linear pass after the sort.
  4. Half-open intervals matter and are easy to get wrong: with closed intervals an attempt ending at the same millisecond another begins reads as concurrency two, and across 50,000,000 records that artefact swamps the real signal.
Follow-up
  • A handler is not idempotent and you have found 400 overlapping jobs. Which of them actually caused damage, and what would you query to find out?
  • Peak concurrency for one job_type is 4 against a configured cap of 4. Is the cap working, or is the data hiding attempts that never started?

The plan starts with the reported notification design, widens to multi-channel delivery, surge handling and distributed-systems theory, then spends two days on coding and data-layer practice before a full dry run. Days that practise reported or practice-set questions list them.

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
01Notification system: requirements and API
  • Write the functional and non-functional requirements for a food-delivery notification service: which order events trigger a message, peak rate, latency per channel, and how bad a duplicate or lost message is
  • Define the ingestion API with an idempotency key, a user-preferences endpoint and a delivery-status endpoint, with request and response fields
  • Sketch the high-level design with the API service, a durable queue, workers and a store for status and preferences

Deliverable: A one-page requirements list, an API contract and a high-level diagram for the notification system.

Practice prompt ↗
02Multi-channel delivery: push, SMS and email
  • Design a channel abstraction: one adapter per provider, one queue and worker pool per channel, so a slow provider stays isolated
  • Write the retry policy per channel: backoff, retry limit, dead-letter queue, and when to fall back from one channel to another
  • Decide where templates, localisation and user opt-out checks live in the flow

Deliverable: A per-channel flow diagram with retry, fallback and dead-letter rules written next to each channel.

Practice prompt ↗
03Peak-hour surges and queue versus direct calls
  • Prepare the answer to a sudden surge of notifications at peak hours: queue buffering, autoscaled workers, priority lanes for order-status messages over promotions, rate limiting and backpressure
  • Write a comparison of a message queue and direct service-to-service calls covering coupling, latency, failure isolation, ordering and operational cost
  • Rework your day 1 design to add the surge controls and say what degrades first under overload

Deliverable: A short comparison table (queue versus direct call) and a revised design with surge controls marked.

Practice prompt ↗Practice prompt ↗
04Availability and consistency in distributed systems
  • Summarise CAP in your own words and attach one concrete example from the notification system to each side of the trade-off
  • Cover the tools by name: load balancing, replication, sharding with a partition key, caching and its invalidation, and leader election or quorum writes
  • Pick a relational or NoSQL store for the preference data and for the delivery log, and justify each choice by its access pattern

Deliverable: A two-minute spoken answer to the availability-and-consistency question, with a store choice and justification for two datasets.

Practice prompt ↗
05Data structures and algorithms in your backend language
  • Choose Java, Go or Python and write the practice problem on heaviest tenants in a five-minute window under memory pressure, stating the complexity
  • Write the idempotency-fingerprint practice problem, which maps directly to de-duplicating retried notification sends
  • Write the overlapping-attempts and peak-concurrency practice problem, then test an empty list and identical timestamps

Deliverable: Three solved practice problems in one language, each with its complexity and edge cases listed.

Practice prompt ↗Practice prompt ↗Practice prompt ↗
06Data layer and your own project stories
  • Work the keyset paging practice problem and relate it to paging through a user's notification history
  • Write two project stories with the decision you made, the trade-off, and the result, plus one story about a disagreement with a teammate
  • Work the outage practice prompt, then note which story would answer a question about a technical challenge you handled

Deliverable: A keyset-paging query, plus three written stories (two projects, one disagreement) each with a result.

Practice prompt ↗Practice prompt ↗
07Full dry run
  • Speak the entire notification design aloud, from clarifying questions to failure handling, then answer the multi-channel and availability questions back to back
  • Solve one fresh algorithm problem while narrating, ending with a complexity statement
  • Write the questions you will ask the recruiter about the stage format and the questions you will ask the team about the services you would own

Deliverable: A recorded or written full mock with a list of gaps to fix, and your questions for the recruiter and the team.

Practice prompt ↗Practice prompt ↗Practice prompt ↗

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

Candidates report that, next to the technical stages, you may be asked about past projects, how you handled technical challenges and team disagreements. The role description mentions working with product managers and other engineers, taking ownership of features, and coping with shifting priorities, so choose stories that show your own decisions and what changed because of them.

Tell callers you do not own that their integration breaks

medium
deprecationcompatibilitystakeholders

A field in a write endpoint's response must change shape. You own the endpoint; you do not own the four internal callers or the outbound webhook consumers who read it. Describe a deprecation you were responsible for: what you shipped first, how you established who was actually reading the field, the window you gave and what set its length, what you did about the consumer who never moved, and how you decided removal was safe. Name the signal you used, not the announcement you sent.

Approach
  1. Establish the reader set empirically rather than from a wiki of owners: per-field usage counters keyed by principal, or access logs attributed to a consumer. State the blind spot of whichever you pick, since a consumer that reads the field only on a monthly job will not appear in a week of logs.
  2. Ship additive first. Populate the new field alongside the old one so no reader is forced to move, which is also what keeps a rolling deploy safe, because old and new instances answer the same requests at the same time and a rollback must still find the old shape present.
  3. Set the window from the slowest legitimate consumer's release cadence, not from your calendar, and decide separately what to do for a consumer with no release process at all, such as an external webhook endpoint you can only email.
  4. Convert silence into evidence before you rely on it: a short, low-traffic removal window that makes a still-dependent consumer fail visibly and loudly while you are watching, rather than at three in the morning after you have moved on.
Follow-up
  • How would you detect a consumer that reads the field only during a monthly export?
  • One caller refuses to move and has a commercial relationship behind it. What changes in your plan and what does not?

Narrate an outage you owned from page to postmortem

hard
incident responseblast radiuspostmortems

Pick an incident you personally drove, ideally one where writes were affected rather than reads. In six to eight minutes: state the symptom as it first appeared on a dashboard, the blast radius you established before you knew the cause, the mitigation you applied and when, the mechanism you eventually proved, and the follow-up that would prevent a repeat. Bring numbers: error rate, tenants affected, minutes to mitigate, minutes to resolve. If you cannot name what you measured, choose a different incident.

Approach
  1. Open on the signal rather than the cause: which metric at which percentile moved, on which service, at what time, so the listener follows the same evidence you had rather than a conclusion you already reached.
  2. Separate mitigation from diagnosis out loud. State what you did to stop the bleeding (flag off, shed traffic, drain a lease, roll back a deploy) and say plainly that you did it before the mechanism was known, because those are two jobs with different deadlines.
  3. Establish blast radius in countable terms: how many tenants, how many writes, and crucially whether the effect was loss or only delay. An append-only revision table or a pending outbox row means the change survived and the projection was merely behind, which is a repair rather than a data-loss incident.
  4. Prove the mechanism instead of asserting it. Name the trace span that grew, the plan that flipped to a sequential scan, the lease that expired, plus one alternative you ruled out and the signal that stayed flat while you ruled it out.
Follow-up
  • What would you do differently in the first five minutes, given the same dashboard and no more information?
  • Which follow-up action did you deliberately not take, and why was dropping it the right call?

Reverse your own decision and price the reversal

medium
reversibilitymeasurementmigrations

Describe a technical decision you made and later reversed. Pick one that cost something: a service you split and merged back, a cache you added and removed, an index you created that pushed the planner onto a worse plan, a projection you rebuilt from scratch. State what you believed when you decided, the measurement that changed your mind, how long the wrong version ran in production, and what the reversal cost in migrations, dual writes, and a deprecation window for callers you did not own.

Approach
  1. State the original rationale without irony, in the version you would still defend given what was known then. If it is not defensible, the story is about carelessness rather than judgement, and a different example serves you better.
  2. Give the measurement that moved with a before and after: the p99 that did not improve, the cache hit rate that sat at 40%, the plan that flipped to a sequential scan once the table passed a size you can name.
  3. Cost the reversal in steps, not adjectives: expand-and-contract deploys, the dual-write window, the callers who had to be notified, the rows already written in the wrong shape that had to be backfilled or abandoned.
  4. Distinguish reversal from rewrite by naming what you kept. Most good reversals preserve the schema or the interface and undo one decision inside it, which is also why they were affordable.
Follow-up
  • What in that decision was irreversible, and did you know it was irreversible when you made it?
  • How did you tell the people who had already built on top of the original decision?
  • 01

    Walk through a backend project you owned: what you built, which design decisions were yours, and what you would change now.

  • 02

    Tell me about a technical challenge you handled, such as a latency or scaling problem, and how you found the cause.

  • 03

    Describe a disagreement with a teammate over a technical approach: what each side argued, how you settled it, and what happened afterwards.

  • 04

    Tell me about a time priorities shifted in the middle of a project and how you adjusted your plan.

  • 05

    Describe a bottleneck or risk in a system you noticed before it caused an incident, and what you did about it.

PracHub preparation framework ↗
How should I split my preparation between system design and coding?

Candidates describe both as part of the loop, with system design reported most often, so give design the larger share. A workable split is to build one full notification design first, then use the remaining days to cover distributed-systems theory, DSA practice in one language, and project stories. Adjust once your recruiter tells you which stages include coding.

District by Zomato Software Engineer candidate reports ↗
Is the interview process strictly technical?

Technical stages dominate what candidates report, but you should also be ready to discuss past projects, how you dealt with technical challenges and disagreements with teammates. Prepare two or three stories with a specific decision and result.

District by Zomato Software Engineer candidate reports ↗
How should I approach the notification system design question?

Start with requirements: which events trigger messages, peak throughput, per-channel latency and tolerance for duplicates. Define the API (with an idempotency key), then sketch the pieces: an API service, a durable queue, per-channel workers, a store for preferences and delivery status. Finish by walking through failure and scale: retries with backoff, dead-letter handling, a provider outage, and a ten-times traffic spike.

District by Zomato Software Engineer candidate reports ↗
What topics do candidates report for District by Zomato?

Reported topics are notification system design, high-level design, multi-channel notifications, data structures and algorithms, and general scalability and architecture. Within design, candidates mention distributed systems (CAP theorem, load balancing, database design) and API design between services.

District by Zomato Software Engineer candidate reports ↗
Which programming language should I use?

The role requirements candidates describe name Java, Go or Python as examples of a major backend language. Choose the one you write fastest and can explain data-structure complexity in, rather than switching to match the list.

PracHub Software Engineer practice ↗
What technologies are worth knowing for this role?

Candidates list proficiency in a backend language, strong data structures and algorithms, and experience with both relational and NoSQL databases as must-haves. Cloud infrastructure (AWS or GCP), containers (Docker or Kubernetes) and real-time data processing are listed as extras, so be ready to mention where a queue, a cache or a database sits in your designs even if you do not go deep on tooling.

PracHub Software Engineer practice ↗
Sources & methodology 3 sources ↗

No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.