Skip to content
Preptima

Performance Diagnosis and Optimisation Interviews: A Masterclass

How senior interviewers grade the question every backend loop eventually asks: why is this slow, and how would you find out. Percentiles, queueing, profiling, the slow-query path, tail latency in a fan-out, metastable collapse, autoscaling that browns out, and how to report a finding a business can decide on.

Masterclass·104 min read

What it is

A performance interview is a reasoning interview wearing a systems costume. The interviewer says some version of "it got slow, what do you do", and everything they learn about you in the next forty minutes comes from the order in which you do things rather than from the list of things you know. Two candidates can name the same eight causes. One of them names them as a checklist and starts guessing; the other establishes what the symptom already rules out, picks the measurement that separates the surviving hypotheses, and only then says a word about fixes. The second candidate gets the offer, and frequently the first one had deeper knowledge of the individual mechanisms.

That is the whole subject. Performance work is not a body of tricks about indexes and caches. It is the discipline of finding out where time is spent, in a system that will not tell you unless you ask correctly, and then proving that a change moved the thing you claimed it would move. The tricks are real and you need them, but they are the second half. Candidates fail this round overwhelmingly on the first half, and the failure is almost never "did not know about connection pooling". It is "started optimising before establishing what was slow".

The subject has a stable shape that is worth holding in your head as a shape rather than as a list, because under interview pressure a list collapses and a shape does not. A symptom arrives, usually from someone who is not an engineer and whose description is not reliable. You establish what is actually true and reproduce it, or find a way to observe it in production if it will not reproduce. You localise it to a layer, which mostly means ruling layers out. Inside that layer you find where time is going, which means separating time spent working from time spent waiting. You form a hypothesis specific enough to be wrong, and you test it. You change one thing. You verify against the original measurement, in the same units, on the same population. And when the change did not help, which is common and is not a failure, you go back and re-measure rather than stacking a second change on top of the first.

The edge worth looking at is the loop back from verification to measurement, not the straight run down the middle. Everyone can describe the straight run; the candidates who are trusted with a real production problem are the ones who say out loud what they do when the fix did not work, because that is the branch the job spends most of its time in.

Measurement before change, and what that phrase actually commits you to

"Measure before you change" is repeated so often that it has stopped carrying information. It is worth unpacking into the three commitments it makes, because interviewers probe each of them separately.

The first commitment is that you have a number before you touch anything, and that the number is of the thing the complainant cares about. If the report is "the dashboard is slow", the baseline is time to a usable dashboard for the users complaining, not average server-side handler duration across all endpoints. Those can move in opposite directions. A candidate who baselines the wrong quantity will later demonstrate an improvement nobody experiences, which is a specific and common professional embarrassment.

The second commitment is that the measurement is repeatable. A single observation of a slow request is an anecdote. You need to be able to take the measurement again, later, after the change, under comparable conditions, and know that the difference between the two numbers is the change rather than the hour of day. This is why load-test-based performance work has such a strong pull despite its many problems: it buys repeatability. It is also why production measurement has to be paired with a stated population and window, because "the p99 last Tuesday" and "the p99 this morning" may be measuring two different traffic mixes.

The third commitment, and the one candidates skip, is that you can attribute the change. If you deploy an index, a cache and a pool-size bump together and latency halves, you have learned that one of three things worked and you now carry two changes of unknown value for the life of the system. One of them may be actively harmful in a way that will surface in six months under a different load shape. Changing one thing at a time is slower and it is the only way the second change is ever grounded in evidence rather than in the momentum of the first.

The vocabulary that keeps a diagnosis honest

A handful of terms do most of the work in this domain, and using them precisely is itself a graded signal because imprecision here is how people talk themselves into the wrong fix.

Service time is how long an operation takes when it is being worked on, with no contention. Wait time, or queueing delay, is how long it sat before anyone touched it. Response time, which is what your user experiences and what your latency metric usually records, is the sum. These are three different quantities and they respond to completely different interventions: service time falls when you make the work cheaper, and wait time falls when you reduce arrival rate, add servers, or shorten the queue. Optimising code to reduce service time when the problem is a queue is the single most common wasted week in this field.

Utilisation is the fraction of time a resource is busy. Saturation is the extent to which work is queued for it. The two are related but a resource can be at high utilisation with no queue and be perfectly healthy, and a resource can be at moderate utilisation with a growing queue because the work arrives in bursts. Reporting utilisation and calling it saturation is how a team concludes that a CPU at seventy per cent is fine while requests are visibly waiting to be scheduled.

Throughput is completed work per unit time. Goodput is completed work that somebody still wanted by the time it completed. A service under overload can have healthy-looking throughput and near-zero goodput, because every response arrives after the caller has timed out and retried. That distinction is the hinge of the metastable-failure discussion later, and volunteering it early marks you as someone who has been in one.

Concurrency is how many things are in the system at once. It is not a rate, and confusing it with a rate is a specific error with a specific cost, because limits expressed in requests per second do not adapt when service times change and limits expressed in in-flight requests do.