Interview guide

Senior Backend Engineer Interview Questions (2026)

Over forty questions senior backend loops actually ask, each with a short senior-level answer and the mistake that sinks most candidates.

Last updated: October 2026

Senior backend interviews test judgement more than recall. The same question can be answered at a junior level (name the pattern) or a senior level (say when it fails, what it costs, and what you would monitor). Each answer below is deliberately short, followed by the mistake that most often separates the two.

Jump to a section: System design, Data and caching, Distributed systems and reliability, Debugging and operations, Code review, APIs and security, Concurrency, Behavioral.

System design

Senior rounds reward a clear sequence (requirements, estimate, API, data model, components, one deep dive) and honest tradeoffs over a perfect diagram.

Design a rate limiter for a public API. What happens when its store goes down?

Use a token bucket per API key held in a shared store, with the check-and-update done as one atomic operation so concurrent gateways cannot both spend the last token. For an outage, choose explicitly: fail open to protect availability, or fail closed to protect the backend. Most public APIs fail open with a local fallback limit.

Common miss: Naming an algorithm and never deciding what the limiter does when it is unavailable.

Design a URL shortener. How do you generate the short codes?

Estimate reads versus writes first (reads dominate by a wide margin). Generate codes from a counter encoded in base62, or from random strings with a uniqueness check on insert. Counters avoid collisions but need range allocation across servers. Put a cache in front of reads and keep the database as the source of truth.

Common miss: Hashing the URL and truncating it without handling collisions.

Design a news feed. Fan-out on write or on read?

Fan-out on write makes reads cheap by precomputing each follower's feed, but it breaks for accounts with millions of followers. Fan-out on read keeps writes cheap but makes reads slow. Real systems use a hybrid: push for normal accounts, pull for celebrity accounts, merged at read time.

Common miss: Picking one strategy for every account.

Design a ticket or seat booking system. How do you stop two people buying the same seat?

Make the claim one atomic conditional statement, so exactly one caller wins and the loser is told the seat is gone. Treat the reservation as a lease that expires, confirm the sale only if the same buyer still holds it, and control admission during a big on-sale instead of only scaling the database.

Common miss: Reading the seat's status in code and then writing it, which two requests can both pass. Ticket booking and inventory reservation →

Design a notification system that sends email, push and SMS.

Accept events onto a queue, fan out per channel with separate workers, and make each send idempotent with a key per user, event and channel. Add per-user preferences and rate limits, retry with backoff, and a dead-letter queue for permanent failures. Track delivery state so you can answer 'did this send'.

Common miss: Calling the provider inline from the request that triggered the notification. Queues and messaging →

Explain a consistency tradeoff you made in a real system.

State the data, who reads it, and what wrong costs. For example: a product page can show a stale price for seconds, but checkout must read the authoritative price. Name the mechanism (replica reads, TTL, read-your-writes) and what you monitored to know the staleness stayed acceptable.

Common miss: Reciting CAP theorem instead of describing a decision and its cost. Consistency and CAP →

How would you scale a database that is at its limit?

Diagnose first: slow queries and missing indexes before hardware. Then read replicas for read load, caching for hot reads, vertical scaling as the cheap step, and partitioning when writes or data size are the limit. Pick the partition key by access pattern, and expect hot keys.

Common miss: Jumping to sharding before checking indexes, query plans, and caching. Replication and partitioning →

How do you handle a multi-tenant system where one customer is far larger than the rest?

Scope tenant data below application code (for example row-level security), enforce per-tenant limits on traffic, jobs, and queries, and schedule background work fairly. Route through a tenant directory so a large tenant can be moved to dedicated capacity without a rewrite.

Common miss: Treating tenancy as a column and nothing else.

Data and caching

These come up in almost every design round and often as standalone questions.

SQL or NoSQL for this system?

Start from the access patterns and consistency needs, not preference. Relational stores fit relationships, transactions, and ad hoc queries. Key-value and wide-column stores fit very high write volume and predictable lookups. Many systems use both, each for what it does well.

Common miss: Choosing based on 'it scales' without naming a query or access pattern. Databases 101 →

A query got slow. How do you find out why?

Look at the query plan before changing anything. Check for a full scan, a missing or unused index, a poor join order, or a plan that changed after data growth. Add the index that matches the filter and sort, then confirm the plan and the latency actually improved.

Common miss: Adding indexes blindly, which slows writes and may not help the query.

How do you invalidate a cache?

Combine a TTL, which bounds staleness and self-heals, with explicit deletion on write. Delete rather than update the entry, so a racing reader repopulates from the source of truth. Choose the TTL from how wrong the data may be in business terms.

Common miss: Updating the cache in the write path, which races with concurrent readers. Caching basics →

What is a cache stampede and how do you prevent it?

A popular key expires and many requests miss at once and hit the database with the same query. Let one request rebuild the value while the others wait or read the stale copy, and add jitter to TTLs so keys do not expire together.

Common miss: Suggesting a bigger database instead of coordinating the rebuild. Caching basics →

How do you choose a partition key?

High cardinality, even access (not only even storage), and alignment with your main queries. A hash gives an even spread of keys but not of load, so watch for a hot key and have a plan: sub-keys merged on read, caching, or a separate path for the hot entity.

Common miss: Picking a key that spreads storage evenly while one key takes most of the traffic. Replication and partitioning →

A user updates their profile and then sees the old one. What happened?

The read hit a replica that had not yet received the write. Fix it with read-your-writes: route that user's reads to the primary for a short time after a write, or pass a version token and wait for a replica to reach it.

Common miss: Blaming the cache without checking replica lag. Replication and partitioning →

Distributed systems and reliability

This is where senior candidates separate from the rest, because the questions are about what happens when things fail.

How do you make a payment API safe to retry?

Require an idempotency key from the client, store the key with the result under a unique constraint, and return the stored result on a repeat. Handle the in-flight case, where a second request arrives while the first is still running, and scope keys to the caller and endpoint.

Common miss: Checking for an existing key and then inserting, which races under concurrent retries. Idempotency and exactly-once →

Is exactly-once delivery possible?

Not over an unreliable network. You get at-least-once delivery plus an idempotent consumer, which gives exactly-once effects. Deduplicate by a stable message or event id and make the side effect safe to repeat.

Common miss: Claiming the broker guarantees exactly-once without addressing consumer side effects. Idempotency and exactly-once →

How should retries work?

Retry only operations that are safe to repeat and only on errors that can succeed later. Use exponential backoff with jitter, cap attempts and total time, and respect a retry budget so a struggling dependency is not buried under retries from every client.

Common miss: Immediate retries in a tight loop, which turn a blip into an outage. Failures, timeouts and retries →

What does a circuit breaker do, and when does it hurt?

It stops calling a failing dependency after errors cross a threshold, then probes occasionally to see if it recovered. It protects your threads and the dependency. It hurts when thresholds are tuned badly and trip on normal noise, or when there is no fallback for the open state.

Common miss: Describing the states but not what the caller does while the breaker is open. Resilience patterns →

Saga or two-phase commit?

Two-phase commit gives atomicity but blocks on a coordinator failure and couples services. A saga runs local transactions with compensating actions for failure, trading isolation for availability. For microservices that cross a payment provider, sagas are the practical choice.

Common miss: Forgetting that compensations can fail too and need retries and monitoring. Sagas, outbox and CDC →

How do you write to your database and publish an event atomically?

Use the transactional outbox: write the event to an outbox table in the same database transaction as the data, and a separate relay publishes it, with consumers deduplicating. Writing to the database and then to the broker in code can lose the event on a crash between them.

Common miss: Publishing first or second and hoping nothing crashes in between. Sagas, outbox and CDC →

How do you implement a distributed lock safely?

A lock with an expiry can be held by a paused process that does not know it expired. Pair it with a fencing token, a number that increases on each acquisition, and have the protected resource reject writes carrying an older token.

Common miss: Relying on the lock's TTL alone for correctness.

Debugging and operations

Interviewers want to see method under uncertainty, not a lucky guess.

A read endpoint's p99 latency tripled overnight and nothing was deployed. Walk me through the first hour.

Confirm the metric is real and when it started. Then bisect by dimension: one endpoint or all, one region, one tenant, one dependency. Check dependency latency, saturation (connections, CPU, queue depth), recent data or config changes, and traffic shape. Form a hypothesis, test it, and mitigate before you fully explain.

Common miss: Guessing a cause immediately without confirming the metric or narrowing the scope. How to debug production incidents →

You inherit a service with no tests and a reputation for breaking. What do you do first?

Add visibility before changing behaviour: logs, metrics and alerts on the failure paths. Then write characterisation tests around the riskiest flows to pin current behaviour, and fix the top causes of incidents. Resist a rewrite until you understand why it breaks.

Common miss: Proposing a rewrite on day one.

How do you set up observability for a new service?

Structured logs with a request id, the golden-signal metrics (latency, traffic, errors, saturation), distributed traces across services, and SLOs with alerts on user-visible symptoms rather than on every internal metric. Write a runbook for each alert.

Common miss: Listing tools instead of the signals and the alerts that wake someone up. Observability basics →

Tell me about an incident you handled.

Structure it: impact, detection, mitigation, root cause, and what changed afterwards. Spend the time on the decisions you made under uncertainty and on the follow-up that prevented recurrence, not on a blow-by-blow timeline.

Common miss: Taking credit for the fix and skipping what you changed so it could not happen again.

A health check endpoint takes the service down. How?

A health check that calls the database or a third party can hang when that dependency is slow, so the orchestrator kills healthy instances or the check itself exhausts threads. Keep liveness cheap and local, and treat dependency health as readiness with timeouts.

Common miss: Making the health check depend on every downstream system. Free practice: payments health check PR →

Code review

Increasingly common in senior loops, because it tests judgement on real code.

What do you look for when reviewing a payments pull request?

Money as integers, not floats; idempotency on every external call; what is durable before the call and after; error paths that swallow failures; races in read-then-write; logging that leaks card or token data. Then tests that would fail if the logic broke.

Common miss: Commenting on style and naming while missing a double-charge path. Free practice: idempotency middleware PR →

How do you avoid false positives in a review?

Verify a suspected bug by tracing the actual behaviour, including what the library or framework guarantees, before commenting. Flag a concern with the evidence and the failing scenario. Calling idiomatic code a bug costs credibility and wastes the author's time.

Common miss: Reporting every possible issue instead of the ones you can demonstrate.

What is wrong with a retry loop around a non-idempotent call?

A timeout does not mean the first attempt failed, so the retry can perform the action twice. The call needs an idempotency key, or the loop must check the outcome before retrying.

Common miss: Approving the retry because it looks resilient. Failures, timeouts and retries →

A handler catches an exception and returns success. Is that a problem?

Usually, yes. It hides failures from callers and monitoring, and a caller may treat the work as done. Fail loudly, or return a result that distinguishes the outcome, and log with enough context to debug.

Common miss: Accepting a broad catch because it prevents a 500.

APIs and security

Expect at least one question about an API design decision you would defend.

Offset or cursor pagination?

Offset is simple but gets slower with depth and returns duplicates or skips rows when data changes between pages. Cursor (keyset) pagination is stable and fast because it continues from the last seen sort key, at the cost of no jumping to an arbitrary page.

Common miss: Using offset on a table that is written to while users page through it. API design basics →

How do you version an API?

Prefer additive, backward-compatible changes so most changes need no new version. When a breaking change is unavoidable, version explicitly (path or header), support the old version for a published period, and monitor who still uses it before removal.

Common miss: Bumping a version for every change, or breaking clients with no notice. API design basics →

What are common mistakes when verifying a JWT?

Not pinning the accepted algorithm, trusting the header's algorithm, skipping expiry and audience checks, and not rotating keys. Verify the signature with a key you choose, validate claims, and keep tokens short-lived.

Common miss: Decoding the token and reading claims without verifying the signature.

How do you prevent one user from reading another user's data?

Authorise on every request against the resource's owner, not just authenticate. Do not trust ids from the client alone, scope queries by the authenticated principal, and test with two users that each cannot reach the other's resources.

Common miss: Authenticating the user and assuming the id in the URL belongs to them.

How do you store passwords?

Hash with a slow, salted algorithm designed for passwords (Argon2id, scrypt, or bcrypt), never a fast hash, and never store or log the plain password. Add rate limiting and breach-password checks at sign-in.

Common miss: Suggesting SHA-256 with a salt.

Concurrency

The same few ideas appear in every language and every framework.

Optimistic or pessimistic locking?

Optimistic locking checks a version at write time and retries on conflict, which suits low contention. Pessimistic locking holds a lock while working, which suits high contention or work that is expensive to redo. On a single hot row, neither beats an atomic conditional update.

Common miss: Choosing one without discussing contention.

What causes a deadlock and how do you avoid it?

Two operations each hold a lock the other needs. Avoid it by acquiring locks in a consistent global order, keeping transactions short, and using timeouts with retry.

Common miss: Knowing the definition but not the ordering fix.

Two requests both read a balance of 100 and both withdraw 80. How do you stop it?

Make the check and the update one atomic operation, such as a conditional update that only succeeds if the balance is sufficient, or run both inside a transaction with the right locking. Reading in application code and then writing is the bug.

Common miss: Adding a check in application code before the write. Ticket booking and inventory reservation →

Behavioral

Senior loops weigh these heavily. Keep stories specific, with your own decisions and the result.

Tell me about a time you disagreed with a teammate or a decision.

Describe the technical disagreement, how you made the case with evidence, how you listened, and what happened. A strong answer includes a time you were wrong or compromised, and how the team moved on.

Common miss: Telling a story where you were simply right and the other person gave in.

Describe a project where the direction was ambiguous.

Explain how you reduced the ambiguity: the questions you asked, the smallest experiment you ran, how you got alignment, and the decision you made with incomplete information.

Common miss: Waiting for the requirements to become clear instead of creating clarity.

Tell me about a project you led and what you would do differently.

Cover scope, the key tradeoffs, how you worked with others, the outcome in numbers if you have them, and a real lesson. Naming a specific thing you would change is a strength, not a risk.

Common miss: Saying 'nothing' or giving a humble-brag.

How to use this list

Do not memorise the answers. Pick five questions you could not answer in two minutes, read the linked note for each, then answer them out loud again without looking. The goal is to be able to say what you would do, why, and what goes wrong, which is what the follow-up questions probe. For a week-by-week plan, see the senior backend interview prep guide.

Frequently asked questions

What candidates ask most often about senior backend interviews.

What are the most common senior backend engineer interview questions?+

System design (rate limiters, URL shorteners, feeds), data and caching, reliability under failure (idempotency, retries, sagas), production debugging, and behavioral questions about disagreement and ambiguity. Many loops now also include a code review round.

How are senior backend interviews different from mid-level ones?+

The questions look similar, but senior interviewers expect you to drive the conversation, justify tradeoffs with numbers, and explain what happens when things fail. A correct happy path is not enough.

How should I practice these questions?+

Answer out loud with a time limit, then compare against a rubric. Reading answers teaches recognition; producing them teaches recall. Senior Loop's code review, debugging, and design problems are graded against explicit answer keys, and several are free.

How long does preparation take?+

Most engineers with strong fundamentals need four to eight weeks of focused practice. Spend the time on weak areas rather than rereading what you already know. The senior backend interview prep guide has a week-by-week plan.

Related reading

Practice, do not just read

Try a free code review, a debugging exercise, or a system design problem, each graded against a rubric. Or start with the free system design roadmap. No card required.

Start free →