Backend developer interview questions, with worked answers
Sixteen questions that backend developer interviews ask again and again, from first backend job to staff engineer, principal engineer and software architect. For each: what the interviewer is checking, a short answer, the full answer in plain words, a weak answer to avoid, and a likely follow-up.
Contents
- How to use these questions
- What a backend developer is expected to know
- APIs
- Databases and transactions
- Caching, queues and failures
- Security, scale and running in production
- Staff, principal and architect questions
- Your CV for these questions
- Key takeaways
- Frequently asked questions
- More on the backend developer role
How to use these questions
Read the short answer and say it out loud; that is your first half minute. Then take two or three points from the full answer and add one service you worked on: its load, what failed, what you measured and what you changed. Backend interviewers listen for failure cases; mention them before they ask.
What a backend developer is expected to know
- A language in depth: JavaAsked in 36% of backend developer ads (as of 5 Nov 2026).The most common backend language in large companies: the JVM, collections, threads and memory. with SpringAsked in 20% of backend developer ads (as of 5 Nov 2026).Spring Boot for services: dependency injection, data access, security and configuration., PythonAsked in 31% of backend developer ads (as of 5 Nov 2026).Services and APIs with Django or FastAPI, background jobs and scripts; typing helps large codebases., C#Asked in 18% of backend developer ads (as of 5 Nov 2026).C# with .NET for services, especially at Microsoft-centred companies, banks and industry., GoAsked in 2% of backend developer ads (as of 5 Nov 2026).Go: small, fast services and tools, with simple concurrency; common in platform and cloud teams. or Node.jsAsked in 4% of backend developer ads (as of 5 Nov 2026).JavaScript or TypeScript on the server; good at many small requests, weaker at heavy computing.: its memory, threads or async model, and its testing tools.
- Data: SQLAsked in 31% of backend developer ads (as of 5 Nov 2026).Joins, indexes, query plans and transactions; reading why a query is slow and fixing it., indexes and transactions in a database such as PostgreSQLAsked in 36% of backend developer ads (as of 5 Nov 2026).The most asked-for open-source database: indexes, locks, migrations and backups.; when a cache such as RedisAsked in 3% of backend developer ads (as of 5 Nov 2026).A fast in-memory store for caching, sessions, rate limits and small queues. or a document store helps.
- APIs: REST APIsAsked in 34% of backend developer ads (as of 5 Nov 2026).Design clear resources, status codes, pagination, versioning and error messages. that are clear, versioned and safe to retry.
- Between services: queues such as RabbitMQAsked in 4% of backend developer ads (as of 5 Nov 2026).A message broker that hands each job to one worker; for background tasks and retries., event logs such as KafkaAsked in 2% of backend developer ads (as of 5 Nov 2026).A log of events that many services read in order; for high volumes and replay., timeouts and retries.
- Running it: DockerAsked in 24% of backend developer ads (as of 5 Nov 2026).Package a service and its dependencies so it runs the same in testing and production., CI/CDAsked in 35% of backend developer ads (as of 5 Nov 2026).Every change is tested and deployed automatically, with a quick way back., logs, metrics with tools such as PrometheusAsked in 1% of backend developer ads (as of 5 Nov 2026).Collect metrics such as request rate, errors and latency, and alert on them., and being on call.
- Security: sign-in, access rules, secrets, and personal data under GDPRAsked in 8% of backend developer ads (as of 5 Nov 2026).EU data protection: store only the personal data you need, protect it, and delete it on time. (EU) and similar laws.
APIs
A mobile app retries a request when the network drops. How do you make sure the payment happens only once?
What they check: that you expect retries and design for them, the core of a safe API.
Short answer: "I make the request idempotent: doing it twice has the same effect as doing it once. The app sends a unique key with each payment; the server stores the key with the result, and a repeat with the same key gets the stored result instead of a second charge."
The full answer, in five steps:
- A key per action. The client creates an idempotency key, a unique value, when the user presses pay, and sends it with every retry of that one action.
- Store it first. The server saves the key in the same database transaction as the payment record, with a unique constraint, so two requests with the same key cannot both pass.
- Answer the repeat. If the key exists and the work is done, return the saved result. If it is still running, say so and let the client ask again.
- Protect the provider call. Pass the same key to the payment provider, which most providers accept, so a retry from your side does not charge twice either.
- Expire it. Keep keys long enough to cover retries, for example a day, then clean them up.
A weak answer: "I check whether the user paid in the last minute." Two requests arriving at once both see no payment and both charge.
Follow-up: "Which HTTP methods are idempotent already?" GET, PUT and DELETE are meant to be; POST is not, which is why creating a payment needs the key.
How do you change an API without breaking the apps that already use it?
What they check: respect for clients you do not control, such as old app versions.
Short answer: "I only add, never change or remove, in the same version: new optional fields and new endpoints are safe. A breaking change gets a new version, both run side by side, and the old one is switched off after its users have moved, with a date announced early."
The full answer: Mobile apps stay installed for years, so an API cannot assume every client updates. Versioning can sit in the path or in a header; the choice matters less than being consistent. Publish the API description, for example as an OpenAPI file, and test that changes keep old requests working (contract tests). Log which clients still call the old version, so you know when it is safe to switch off.
A weak answer: "We tell the frontend team to update." Follow-up: "A field must be renamed." Add the new name, keep sending the old one, and remove it only in the next version.
Databases and transactions
How does an index make a query fast, and when does adding one make things worse?
What they check: that you understand the database instead of adding indexes by habit.
Short answer: "An index is a sorted copy of some columns that points to the rows, so the database finds rows without reading the whole table. Every index makes writes slower and takes space, so I add one for a real slow query, check the query plan, and remove the ones nobody uses."
The full answer: The query plan, which the database shows when asked to explain a query, says whether it reads the whole table or uses an index. A combined index on two columns helps queries that filter on the first column; the order matters. An index on a column with few values, such as yes or no, rarely helps. A table that receives many writes, such as an event log, pays for every index on every insert. Creating an index on a large live table can lock it, so most databases offer a way to build it without blocking writes.
A weak answer: "Add an index on every column." Follow-up: "The index exists but the plan does not use it. Why?" The query wraps the column in a function, the types differ, or the database thinks reading the table is cheaper because the filter matches most rows.
Two users book the last seat at the same moment. How does your service make sure only one gets it?
What they check: transactions, isolation and locking, explained in plain words.
Short answer: "I let the database decide. Either the update is conditional, such as 'take the seat only if it is still free', and I check that one row changed; or I lock the row inside a transaction. A unique constraint on seat and event is a last safety net."
The full answer: A transaction groups changes so they all happen or none do. Isolation decides what one transaction sees of another that runs at the same time; the stronger the isolation, the fewer surprises and the more waiting. Most databases default to a level where two transactions can both read 'free' and both write. Options: optimistic locking (each row has a version number, and a write fails if the version changed), pessimistic locking (lock the row while you work), or a stricter isolation level for this one transaction. Keep transactions short, and never wait for a slow outside call inside one.
A weak answer: "I check in the code whether the seat is free, then save." Follow-up: "Your transaction now waits for a deadlock. What happened?" Two transactions locked rows in opposite order; lock in a fixed order and retry on deadlock.
How do you choose between a relational database and a document database for a new service?
What they check: that you choose by the data and its questions, not by fashion.
Short answer: "I start relational, with PostgreSQL, unless I have a reason not to. Related data, transactions and reports are its strength. A document database such as MongoDB fits data read and written as one piece, whose shape varies a lot."
The full answer: Ask what the data looks like, how it is read, and what must stay consistent. Orders, customers and payments relate to each other and need transactions: relational. A product catalogue with very different attributes per product, or event data read whole, can suit MongoDBAsked in 3% of backend developer ads (as of 5 Nov 2026).A document database: flexible records, but joins and transactions work differently.; many relational databases also store flexible JSON fields now. Consider the team: what it knows how to back up, monitor and fix at night. Changing database later is expensive, so the default should be the boring one.
A weak answer: "NoSQL scales better." Follow-up: "Reports need joins across orders and customers in your document store." Copy the data into a warehouse for reporting, or reconsider the choice.
Caching, queues and failures
Where would you add a cache, and how do you stop it serving old data?
What they check: that you know caching's cost: stale data and harder bugs.
Short answer: "I cache data that is read much more often than it changes, and where a few seconds of old data is acceptable, such as a product page. Each entry has an expiry time, and a change to the data deletes its entry. I measure the hit rate to see whether the cache helps."
The full answer: Caches sit in several places: the browser, a CDN (servers near the user that keep copies of pages), the service's memory, or a shared store such as RedisAsked in 3% of backend developer ads (as of 5 Nov 2026).A fast in-memory store for caching, sessions, rate limits and small queues.. The usual pattern: read from the cache, and on a miss read the database and fill the cache. The hard part is invalidation, removing entries when the data changes. Data that must be exact, such as a bank balance or stock in checkout, is read fresh. Watch for a stampede, when a popular entry expires and thousands of requests hit the database at once; refresh it early or let one request rebuild it.
A weak answer: "Cache everything for an hour." Follow-up: "Users see their old name after changing it." Delete their entry when the name changes, and read their own profile fresh.
When would you put work on a queue instead of doing it inside the request?
What they check: that you know what a queue buys and what it costs.
Short answer: "When the user does not need the result to continue, or the work is slow or may fail: sending email, making a PDF, calling a slow partner. The request saves the job and answers at once; a worker does the job, retries if it fails, and a failed job lands where we can see it."
The full answer: A queue such as RabbitMQAsked in 4% of backend developer ads (as of 5 Nov 2026).A message broker that hands each job to one worker; for background tasks and retries. hands each job to one worker. An event log such as KafkaAsked in 2% of backend developer ads (as of 5 Nov 2026).A log of events that many services read in order; for high volumes and replay. keeps events in order for many readers, who can replay them later. Either way, a job can arrive twice, so workers must be idempotent. Jobs that keep failing go to a dead-letter queue to be looked at, not retried forever. Watch the queue length: if it grows, the workers are too slow or broken. Saving to the database and publishing the job must not get out of step; the outbox pattern writes the job to a table in the same transaction, and a separate process publishes it.
A weak answer: "Queues make everything faster." They make the request faster; the work itself still takes as long. Follow-up: "The user wants to know when the PDF is ready." Give the job an ID they can check, or notify them when it is done.
A service you call becomes slow, and soon your service fails too. What do you do?
What they check: failure between services: timeouts, retries and circuit breakers.
Short answer: "Every outside call gets a timeout, so slow does not become stuck. Retries are few, with growing waits and some randomness, and only for safe requests. A circuit breaker stops calling a service that keeps failing, and I show a sensible fallback instead of an error page."
The full answer: Without a timeout, each slow call holds a thread or connection; when they run out, your service stops answering everyone, even requests that do not need the slow service. Retries without limits make the outage worse, because every client doubles its load. A circuit breaker counts failures and, past a limit, fails fast for a while, then lets a few requests through to test. Separate pools for each dependency (bulkheads) stop one from using up everything. Decide the fallback with the product manager: an old price from the cache, a message, or a queue for later.
A weak answer: "I retry until it works." Follow-up: "What timeout would you pick?" Based on that service's normal response time, a little above its slowest normal answers, and within the time your own caller allows.
Security, scale and running in production
How do users sign in to your API, and how do services prove who they are to each other?
What they check: authentication (who you are) and authorisation (what you may do), kept apart.
Short answer: "Users sign in through an identity provider using OAuth and OpenID Connect, and the API receives a signed token it can check without a database call. Every request then checks authorisation: may this user see this order? Services use their own credentials or tokens, with only the rights they need."
The full answer: Do not build password storage yourself if a tested provider can do it. Tokens are short-lived, and a refresh token gets a new one. The most common real flaw is broken access control: the API checks that the user is signed in, but not that order 1234 is theirs. Check ownership on every request, in one shared place. Keep secrets in a secret store, never in the code. Personal data is protected and kept no longer than needed under GDPRAsked in 8% of backend developer ads (as of 5 Nov 2026).EU data protection: store only the personal data you need, protect it, and delete it on time. (EU) and similar laws; securityAsked in 3% of backend developer ads (as of 5 Nov 2026).Know the common attacks on APIs, such as injection and broken access control, and prevent them. reviews look for exactly these points.
A weak answer: "We use HTTPS, so it is secure." HTTPS protects the connection, not the rules. Follow-up: "How do you log out a user whose token is valid for another ten minutes?" Keep tokens short, and keep a list of revoked sessions for sensitive actions.
Your service must handle ten times today's traffic in two months. How do you prepare?
What they check: scaling from measurements, and knowing where systems break first.
Short answer: "I measure where the limit is today with a load test, because it is usually the database, not the service. I make the service stateless so I can run more copies, take load off the database with caching and read copies, move slow work to queues, and test again at the new level."
The full answer, in five steps:
- Know the shape. Ten times on average, or ten times in one evening? Which endpoints? Peaks decide the design.
- Find the limit. Run a load test against a copy of production and watch what saturates first: database connections, CPU, memory, a partner's rate limit.
- Scale out. Keep no user state in the service's memory, so a load balancer can spread requests over more copies, and set up automatic scaling on KubernetesAsked in 12% of backend developer ads (as of 5 Nov 2026).Run services on a cluster: deployments, health checks, scaling and configuration. or the cloud.
- Protect the database. Add the missing indexes, cache what is read often, send reads to replicas, and pool connections. Only then consider splitting the data.
- Plan for overload. Rate limits, a queue for work that can wait, and a clear message when the service is full beat a slow collapse.
A weak answer: "We move to microservices." That changes the structure; it does not remove the database limit.
Follow-up: "The load test passes, but production fails on launch day." The test did not match real behaviour, such as everyone hitting one popular item; test with real traffic patterns and keep a quick way to switch features off.
Many requests arrive at once. How does your language handle them, and what runs out first?
What they check: that you know the concurrency model of the language you write in, not only its syntax.
Short answer: "In Java with Spring, each request traditionally gets a thread from a pool; Node.js and Python's async frameworks run many requests on one thread and switch while they wait. Either way, what usually runs out first is not the threads but the database connection pool, so I size that pool and keep work that holds a connection short."
The full answer: A thread per request is simple to reason about but uses memory per thread; Java's virtual threads now make many cheap threads possible. An event loop, as in Node.jsAsked in 4% of backend developer ads (as of 5 Nov 2026).JavaScript or TypeScript on the server; good at many small requests, weaker at heavy computing., handles thousands of waiting requests on one thread, but one slow computation blocks all of them, so heavy work goes to a worker. GoAsked in 2% of backend developer ads (as of 5 Nov 2026).Go: small, fast services and tools, with simple concurrency; common in platform and cloud teams. runs many light goroutines over a few threads. In every model, shared data needs care: two requests changing the same object in memory at once give wrong results. Watch pool sizes in the metrics: threads busy, connections in use, requests waiting.
A weak answer: "Async is always faster." It helps while requests wait; it does nothing for work that keeps the processor busy. Follow-up: "Requests time out, but CPU is low." They are waiting for something, usually connections from a pool that is too small or held too long.
What do you log, measure and alert on for a backend service?
What they check: observability: whether you can tell what is wrong in production, fast.
Short answer: "For every endpoint I measure request rate, error rate and how long requests take, including the slow ones. Logs are structured and carry a request ID through every service. Alerts fire on what users feel, such as errors or slowness, not on every high CPU reading."
The full answer: Metrics, for example in PrometheusAsked in 1% of backend developer ads (as of 5 Nov 2026).Collect metrics such as request rate, errors and latency, and alert on them., show trends; logs show single events; traces follow one request through several services. Measure the slowest requests too (the 95th or 99th percentile), because averages hide them. Agree a service level objective with the product owner, such as how many requests may fail in a month, and alert when it is being used up too fast. Never log passwords, tokens or full card numbers. Every alert should say what to do; an alert nobody acts on is noise.
A weak answer: "We log everything and search when needed." Follow-up: "A user says the app was slow at 3 pm. How do you find out why?" Find their requests by user or request ID, follow the trace, and compare with the metrics at that time.
Staff, principal and architect questions
An order touches the order, payment and stock services. How do you keep the data consistent without one shared transaction?
What they check: for senior and staff roles, consistency across services and honest trade-offs.
Short answer: "I accept that the services agree a little later, not at the same instant, and design for it. Each service changes its own data and publishes an event. A saga, a chain of steps each with an undo step, runs the order; if payment fails, the stock is released."
The full answer: A transaction across services, such as two-phase commit, is slow and fails badly, so most systems use eventual consistency: the data becomes consistent after a short while. A saga can be choreographed (each service reacts to events) or orchestrated (one service runs the steps); orchestration is easier to follow when there are many steps. Each step must be idempotent and its undo must exist. The outbox pattern makes sure an event is published when, and only when, the data changed. Show users the in-between states honestly, such as 'payment pending'.
A weak answer: "Use one database for all the services." Follow-up: "The undo step itself fails." Retry it, alert a person if it keeps failing, and keep a record so nothing is lost.
Design the backend for notifications that reach millions of users by email and push messages.
What they check: for senior and staff roles, a system design from requirements to failure cases.
Short answer: "Other services send a notification request to one API. It checks the user's settings, writes a job to a queue, and workers per channel send through the email and push providers, with retries and rate limits. Every message is recorded, so we can see what was sent and never send it twice."
The full answer: Start with the requirements: how many messages at peak, how fast they must arrive, which are urgent (a login code) and which can wait (a newsletter). Separate queues keep the newsletter from delaying the login code. Providers limit how fast you may send, so workers pace themselves. Store each message's status for support questions and for the unsubscribe and consent rules. A unique key per message stops duplicates when a worker retries. Templates and languages live with the notification service, not in every caller.
A weak answer: "Each service sends its own emails." Follow-up: "The email provider is down for an hour." The queue holds the messages; urgent ones fail over to a second provider.
You are asked to split a large monolith into services. How do you decide the service boundaries?
What they check: for staff, principal and software architect roles, design that follows the business and the teams.
Short answer: "I first ask what problem splitting solves: teams blocking each other, parts that need to scale differently, or release risk. Then I draw boundaries around business areas that own their data, such as billing or catalogue, and move one at a time, starting where the gain is clear and the coupling is low."
The full answer: Good service boundaries match business areas (domain-driven design calls them bounded contexts) and the teams that own them, so most changes touch one service. Each service owns its data; two services sharing tables are one service in disguise. Splitting the database is the hardest part, so begin by separating the code inside the monolith (a modular monolith) and watching which parts call each other. MicroservicesAsked in 29% of backend developer ads (as of 5 Nov 2026).Small services that deploy on their own; know when they help and what they cost. add network calls, partial failures and more to run, so the team needs good deployment and monitoring first. Some systems are best left as a well-structured monolith.
A weak answer: "One service per database table." Follow-up: "Two proposed services call each other for every request." The boundary is wrong; merge them, or move the data to the one that uses it.
How do you set backend standards that many teams follow without slowing them down?
What they check: for principal and architect roles, influence across teams.
Short answer: "I write down a few decisions that matter across teams, such as how APIs are versioned, how services sign in, and what every service must log and measure, and build them into a service template, so the right way is the easy way. Everything else stays with the teams."
The full answer: Standards nobody follows are worse than none. Write each decision as a short record with its reasons (an architecture decision record), so people can disagree with the reason and not the person. Offer a paved road: a template service with sign-in, logging, metrics, health checks and CI/CDAsked in 35% of backend developer ads (as of 5 Nov 2026).Every change is tested and deployed automatically, with a quick way back. already set up. Review new designs early, while change is cheap, and measure adoption. Accept exceptions with a reason written down.
A weak answer: "Every design must be approved by me." Follow-up: "A senior team wants to use a new language." Ask what problem it solves, who will run it at night, and agree a trial with an end date.
Your CV for these questions
The interviewer asks about what your CV says. Give each of these topics one line under a job, with a number, in the words the ads use:
| Skill | Weak line | Strong line, with proof |
|---|---|---|
| API design | Designed REST APIs. | Designed the public orders API with idempotency keys and versioning; duplicate charges from retries fell to zero. |
| Databases | Database optimisation. | Found the 5 slowest queries from the query plans; database CPU at peak down from 90% to 45%. |
| Queues | Asynchronous processing. | Moved invoice PDFs to a RabbitMQ worker; checkout response time down 600 ms. |
| Observability | Monitoring and logging. | Added request IDs, tracing and error-rate alerts to 12 services; time to find the cause of an incident down from hours to minutes. |
| Architecture | Microservices architecture. | Split billing out of the monolith with its own database; billing releases daily instead of monthly. |
Then score your CV against a real backend job: it shows which of these the service you would join depends on, and which your CV does not back with a number yet.
Key takeaways
- Design every write to be safe to repeat; clients and queues will retry.
- Let the database guard correctness with transactions, conditional updates and unique constraints.
- Give every outside call a timeout, few retries and a fallback.
- Measure before you scale: the limit is usually the database.
- Senior roles add data across services, system design and service boundaries that follow the business.
Frequently asked questions
- What do backend developer interviews ask most?
- API design, databases, indexes and transactions, caching, queues, failures between services, security, scaling and monitoring, and for senior roles system design and service boundaries.
- Is there a coding round?
- Usually: a coding task in your language, often with data structures, and sometimes a small API to build. Explain your reasoning and your tests as you go.
- Do I need to know microservices?
- Know what they solve and what they cost. Many teams run a well-structured monolith, and interviewers like candidates who can say when not to split.
- How deep should my database knowledge be?
- Deep enough to read a query plan, choose an index, explain a transaction and handle two writes at once.
- How should I prepare in a week?
- Say the two worked answers out loud, practise one system design out loud with a timer, read the query plan of a slow query of your own, and prepare one story each about an outage, a speed-up and a design you would now do differently.