Back to Get Hired
Interview roundNail the interview11 min read

The backend interview: APIs, data, and concurrency

Backend rounds aren't testing whether you can code. They're testing whether your service stays correct when two requests arrive at once and the database is having a bad day. Here's what each round is really scoring, and how to prep for it.

On this page

What a backend loop is actually scoring

Who this is for

Anyone interviewing for a backend, platform, or API role and unsure what the rounds beyond "reverse a string" are looking for. Especially career switchers and new grads who can write code but haven't yet been graded on data integrity and concurrency.

Frontend interviews ask *can you build the thing users see?* Backend interviews ask *does your thing stay correct when nobody is watching?* The work is mostly invisible: a request comes in, data changes, a response goes out, and the test is whether that stays true under retries, partial failures, and two clients racing for the same row.

So the rounds skew toward state. You'll be judged less on clever algorithms and more on whether you reach for a transaction at the right moment, whether your endpoint is safe to call twice, and whether you can tell the difference between "slow" and "wrong." Knowing the shape of each round ahead of time is most of the battle.

Anyone can make a request succeed once. The job is making it succeed the second time it's accidentally sent, and fail loudly the time it shouldn't have been sent at all.

The rounds, and what each one is really assessing

Loops vary, but a backend loop is usually drawn from this menu. The wording on the schedule ("systems", "practical", "coding") hides what's actually being scored, so map the label to the signal before you walk in.

RoundWhat it assessesHow to prep
API designCan you model resources, pick status codes, and design an endpoint that's safe to retry and easy to evolve?Practice designing a small API out loud: resources, verbs, errors, pagination, versioning, auth.
Data modeling / SQLDo you understand schemas, indexes, joins, and the cost of a query? Can you spot an N+1?Write the schema for a feature, then write the queries. Explain why each index exists.
Concurrency + reliabilityDo you reason about race conditions, retries, timeouts, and idempotency? Do you know what breaks under load?Rehearse the failure modes: two writers on one row, a retried payment, a dropped network call.
DSA (sometimes)Baseline problem-solving. Often lighter than at product companies, but not skippable.Arrays, hash maps, two pointers, basic graph or tree traversal. Don't over-invest past medium.
Design this serviceCan you take a vague prompt to a coherent API, data model, and failure plan within an hour?Run timed mocks. Practice asking scoping questions before drawing anything.
A typical backend loop. Not every company runs all five, but most run three or four.

Pro tip

If the recruiter won't tell you which rounds you have, ask "how much of the loop is data and systems versus algorithms?" The answer tells you where to spend your last week.

API design: the signals interviewers listen for

An API-design round isn't a vocabulary quiz. The interviewer is listening for whether you make the boring-but-correct choices without being prompted. Each of these is a small signal, and they add up fast.

  • Resource modeling. Nouns as resources, verbs as HTTP methods. POST /comments, GET /comments/{id}, not POST /createComment. Collections are plural and consistent.
  • Status codes that mean something. 201 for a created resource, 400 for bad input, 401 vs 403 (not authenticated vs not allowed), 404 for missing, 409 for a conflict, 422 for valid-but-unprocessable. 500 is your fault, not the caller's.
  • Idempotency. A GET, PUT, or DELETE called twice should leave the same state. A naive POST does not, so for unsafe creates you offer an idempotency key (more on this below).
  • Pagination. Never return an unbounded list. Cursor-based ("give me the next 20 after this token") survives inserts better than offset-based ("page 5"), which skips and duplicates rows as data shifts.
  • Versioning. Decide how clients survive a breaking change: a version in the path, a header, or strict additive-only evolution. Have an answer; "we'd never break it" is not one.
  • Auth and authorization. Who is this caller (authentication) and are they allowed to touch this resource (authorization)? Confusing the two is a real-world security bug, and interviewers probe for it.

The trap

Reaching for 200 OK on every response, including errors, with a { "success": false } body. It works, but it tells the interviewer you haven't thought about clients, caches, or proxies that read the status line. Let the status code carry the meaning.

Data modeling: where correctness lives

This round rewards people who treat the database as the source of truth, not a bucket. The recurring themes:

IdeaWhat to say
Normalize vs denormalizeDefault to normalized (no duplicated data, updates touch one place). Denormalize deliberately for read-heavy paths, and name the cost: now you own keeping the copies in sync.
IndexesAn index makes reads fast and writes slightly slower, and costs storage. Index the columns you filter and join on. "Add an index" is the answer to a slow query, not to every query.
The N+1 problemOne query for a list, then one more per row to fetch a relation, is N+1 queries for N rows. Fix with a join or a single batched "fetch all children for these parents" query. Naming this unprompted is a strong signal.
Transactions + isolationWrap multi-step writes that must all-or-nothing in a transaction. Know that isolation levels trade consistency for concurrency, and that lower levels permit anomalies like dirty or non-repeatable reads.
SQL vs NoSQLRelational for structured data with relationships and transactions. Document or key-value for flexible shape, simple access patterns, and scale-out. Lead with the access pattern, not the brand name.
The data-modeling ideas interviewers expect you to weigh out loud.

Pro tip

When asked "would you use SQL or NoSQL?", never answer with a database name first. Answer with the access pattern: "reads are by user id and writes need a transaction, so I'd start relational." The choice falls out of the requirement.

Concurrency and reliability: the round people fumble

This is where backend interviews separate people. The setup is always the same: something happens more than once, or out of order, or halfway. Your job is to keep the data correct anyway. Walk through the core failure modes so none of them surprise you live.

  • Race condition. Two requests read the same value, both add to it, both write back, and one update is silently lost. The fix is to make the read-modify-write atomic: a single UPDATE ... SET count = count + 1, a transaction with the right locking, or an atomic operation in the store itself.
  • Locking. Pessimistic locking (SELECT ... FOR UPDATE) holds the row so nobody else can touch it, safe but it serializes and can deadlock. Optimistic locking (a version column you check on write) lets work proceed and retries on conflict, better under low contention. Name the trade-off.
  • Idempotency keys. The client sends a unique key with an unsafe request. The server records it; if the same key arrives again (a retry, a double-click), it returns the original result instead of doing the work twice. This is how you make "charge this card" safe to retry.
  • Retries + timeouts. Every network call needs a timeout, or one slow dependency stalls your whole service. Retries need backoff and a cap, or you turn a blip into a stampede. And retries are only safe on idempotent operations, which is why idempotency comes first.
  • At-least-once vs exactly-once. Most real systems deliver at-least-once: a message can arrive twice, so consumers must be idempotent. "Exactly-once" usually means "at-least-once delivery plus idempotent processing," not magic. Saying this plainly reads as experience.
"It worked when I tested it" is true of almost every concurrency bug. They only appear when two things happen at the same time, which your single-threaded test never does.

Worked example: design the API for a comments feature

Here's the design round in miniature. The prompt is deliberately vague ("design the API for comments on a post"), and the first move is always to scope, not to draw. Follow the flow.

  1. 1

    Scope before you design

    Ask the boring questions. Threaded replies or flat? Edit and delete allowed? Roughly how many comments per post, ten or ten million? Who can read versus write? You're showing you don't build for scale nobody asked for, and don't miss scale they did.

  2. 2

    Model the resources

    Comments belong to a post: GET /posts/{postId}/comments to list, POST /posts/{postId}/comments to create, PATCH /comments/{id} to edit, DELETE /comments/{id} to remove. Plural collections, ids in the path, verbs as methods.

  3. 3

    Design the create path to be safe to retry

    POST isn't naturally idempotent, so accept an Idempotency-Key header. If the same key returns, hand back the original comment instead of inserting a duplicate. Now a flaky network or a double-tap can't create two comments.

  4. 4

    Page the list, don't dump it

    A popular post can have thousands of comments. Return a bounded page with a cursor: GET /posts/{postId}/comments?limit=20&after={cursor}. Cursor over offset, so new comments arriving mid-scroll don't shift or duplicate rows.

  5. 5

    Pick status codes and errors deliberately

    201 with the created comment on success, 400 for a malformed body, 401 if not signed in, 403 if signed in but not allowed to comment, 404 if the post is gone, 409 if an idempotency key collides with a different request.

  6. 6

    Name what you'd watch in production

    Close by mentioning the operational view: a created_at index for ordered reads, rate limiting on the create endpoint to blunt spam, and soft-delete (a deleted_at column) so a removed comment doesn't orphan its replies. This signals you've operated a service, not just shipped one.

Pro tip

Narrate the trade-offs as you go. "I'll use cursor pagination here because the list changes while users scroll" is worth more than silently drawing the correct thing. The round scores your reasoning, not just your diagram.

Common failures, and a weak-to-strong endpoint rewrite

Most rejections in backend rounds aren't exotic. They're the same few misses, over and over:

  • No error handling. The happy path works and the interview ends there. They wanted to see what happens when the input is bad, the dependency times out, or the row already exists.
  • Ignoring data consistency. Two writes that should be one transaction, left as two. A retry that double-charges. A counter updated with read-then-write instead of an atomic increment.
  • Designing for scale nobody asked for. Sharding and a message queue for a feature that will have a hundred users. Over-engineering reads as poor judgment, the same as under-engineering.

Weak endpoint design

POST /createComment Body: { postId, text } Response: 200 OK { success: true, comment } - Inserts a row, returns it. - No idempotency: a retry creates a duplicate. - GET /allComments?postId=1 returns every comment. - On any failure: 200 OK { success: false }.

Strong endpoint design

POST /posts/{postId}/comments Headers: Idempotency-Key: <uuid> Body: { text } Response: 201 Created { id, text, authorId, createdAt } - Idempotency-Key makes a retry safe: same key returns the original comment, no duplicate. - GET /posts/{postId}/comments?limit=20&after={cursor} returns a bounded, cursor-paginated page. - Errors carry real status codes: 400 bad body, 403 not allowed, 404 missing post, 409 key conflict.

  • Resource-based path (/posts/{postId}/comments) instead of an RPC verb (/createComment). The post id moves out of the body and into the URL where it belongs.
  • 201 for a created resource, not 200 for everything. Errors stop hiding inside a { success: false } body and use the status line.
  • The idempotency key turns an unsafe create into a retry-safe one. This single change is often the difference between a pass and a fail.
  • The list is paginated. "Return everything" is the answer that gets followed up with "and when there are a million rows?", and now you have an answer.

Walk in remembering this

  • Backend rounds score correctness under retries and races, not clever algorithms.
  • API design: resources as nouns, real status codes, idempotency, pagination, versioning, auth-vs-authz.
  • Data modeling: normalize by default, index what you filter on, and name the N+1 before they do.
  • Concurrency: make read-modify-write atomic, give unsafe writes an idempotency key, put a timeout on every call.
  • In a design round, scope before you draw, and narrate every trade-off out loud.
  • Don't build for scale you weren't asked about. Good judgment cuts both ways.

Reading is step one. Now do it for real.

When you're ready, the platform has live mock interviews and portfolio-grade capstone projects you can actually talk about.

This is general, educational career guidance, not legal, financial, immigration, or professional advice. Examples are illustrative and simplified. Norms vary widely by country, company, role, and over time, so always verify what applies to your own situation. Nothing here guarantees an interview, an offer, or any particular outcome.