Observability & Performance
Learn to understand what a production system is doing, find the bottleneck, explain why it is slow, and prove that your change improved it. The goal is not to know monitoring tools — it is to stop guessing.
What are you trying to diagnose?
Split request duration by endpoint and compare p50 against p99. One number for "the API" is not a measurement — it is an average over things that have nothing to do with each other.
The diagnostic loop
Every lesson and every lab returns to this chain. A fix that skipped a step is a guess that happened to work — or, more often, a guess that did not.
Flagship experiences
Learn → observe → measure → trace → profile → diagnose → optimize → validate → break → debug.
One 2.4-second checkout, peeled apart layer by layer until the bottleneck is exposed — then choose between five plausible fixes, only one of which addresses it.
A simulator with traffic, CPU, cache, pool, workers and retries. Find the knee, watch the bottleneck move, and cause a retry storm on purpose.
"Why is my system slow?" as a decision tree over measurements you can actually take, ending in a constraint and how to confirm it.
Six production incidents with timelines and evidence you pull up one item at a time. The first thing anyone noticed is never the cause.
Size a fleet from stated assumptions, then pick the load-test shape that answers the question you actually have.
Twelve sets of signals with no labels. Read the evidence, name the constraint, then check your reasoning against the path.
Learning modules
Understanding internal behavior from external signals. The measure-before-optimizing loop, what each signal type is actually good at, the golden signals, RED and USE, and how instrumentation reaches a backend at all.
Counters, gauges and histograms as different questions. Why the average hides the outage, how to read p50 against p99, and why a user id in a metric label can take down the monitoring system.
Discrete events with enough context to reconstruct a failure: structured fields over prose, levels that mean something, correlation ids that survive every hop, and the secrets that must never reach log storage.
Where a request spends its time across services. Spans and their relationships, context propagation through queues, the waterfall view, critical-path reasoning, and N+1 as a visible shape.
Where cost goes inside one process. CPU and allocation profiles, reading a flame graph without fooling yourself, and the CPU-bound versus I/O-bound distinction that decides which fix can possibly work.
The physics of a loaded system: tail latency, latency budgets, Little's Law as working intuition, why queueing makes systems slow long before they fail, and what saturation actually means.
The four resources a process competes for, the signal that identifies each as the constraint, and the difference between a memory leak and a cache nobody bounded.
Diagnosing the storage layer from the outside: slow-query workflow, scan versus index, lock waits with idle CPU, pool saturation, replication lag, hit rates that lie, stampedes and hot keys.
Arrival rate against service rate, why depth alone is the wrong alarm, oldest-message age as the honest signal, retry storms that feed themselves, and worker pools that saturate quietly.
Garbage collection, event-loop lag, interpreter overhead, allocation cost and warm-up — labelled per runtime, because none of this generalizes across JS, Python, Go, the JVM and C++.
The user's half of the latency budget: the browser waterfall, Core Web Vitals as user-experience signals, JavaScript cost beyond bytes, images, and layout work that blocks the first paint.
What changes when the work crosses machines: fan-out and tail amplification, sequential versus parallel dependency calls, cross-region propagation delay, jitter, and the cost of coordination.
How much load the system can take, how much headroom is left, whether autoscaling arrives in time, and what a request actually costs — capacity and efficiency as separate questions.
Producing numbers that mean something: load-test shapes, coordinated omission, benchmark hygiene, microbenchmark versus end-to-end, and telling a real regression from noise.
Turning user experience into a measurable objective: SLIs, SLOs and SLAs kept distinct, error budgets as a decision tool, alerts worth waking up for, burn rates, and dashboards built around questions.
Evidence-based diagnosis under pressure: reading a timeline, separating correlation from causation, watching the bottleneck move after every fix, and the trade-offs that make a system faster but worse.
The newest latency budget: time to first token, tool-call chains, step counts, retries and context size — where agent latency, cost and quality trade against each other.
Every number here is labelled
§163 — performance is workload-, runtime- and environment-sensitive, so a figure without conditions is folklore.
A real published measurement, with its conditions named.
Arithmetic from stated assumptions. Change one and the number changes.
Produced by a model in this app. Right shape, invented magnitudes.
Invented to teach a shape. The relationship is the lesson, not the number.
Simulated output is never presented as measurement. Runtime-, engine- and web-specific claims say which runtime, which engine, which platform — because "Python is slow" and "CPython's interpreter dispatch costs more per bytecode than a JIT" are not the same statement, and only one of them is useful.