Skip to content
academia.sh

Course Advanced

Performance Anti-Patterns and Monitoring

By the end of this course

Start course

01

Anti-Patterns

Ten diagnoses from symptom to cause: computation done in the wrong layer, heavy work piled onto the main thread, a large number of small calls, reading more than is needed, expensive clients being re-created, all the data piled into a single store, a repeated expensive computation left uncached, missing isolation on a shared resource, blocking calls' effect on capacity, and a retry loop that grows a failure.

  1. 01 Busy Database Separating two opposite causes of the same symptom with a single measurement: the store layer staying busy while the app layer sits idle, non-reducing work left in the store and reducing work moved to the app producing the identical symptom, the boundary ratio choosing the direction of the fix, and the condition under which a single number recommends the wrong plan.
  2. 02 Busy Front End The load the server sends growing the work on the client: the time visible to the user growing while server response time stays flat, load growth and client code growth producing the same symptom being separated by the work-per-record measurement, the 26.8-times gain from moving sorting to the server, and the price moving formatting pays against the cache key.
  3. 03 Chatty I/O The trade-off between call count and bytes moved: measuring the same panel open at three call granularities, splitting the useful share of bytes moved into an envelope share and an unused-payload share, the usage ratio below which a single large call is worse, and why a high cache hit rate does not mean fewer bytes.
  4. 04 Extraneous Fetching Measuring over-fetching end to end: a wide record lowering the number of entries that fit in cache, key variety producing the identical hit-rate drop, the measurement that splits the two into the working set's two factors, and the threshold where moving extra fields is justified being bounded by a call's envelope.
  5. 05 Improper Instantiation Expensive clients re-created on every request: the two opposite causes behind throughput not rising with concurrency, the creation ratio choosing the fix's direction, setup work eroding with repeat count, and the pool's held object-rounds weighed against waiting request-rounds.
  6. 06 Monolithic Persistence Recognizing all data classes piled into a single store from its symptom: separating two causes of the same slowdown, the read path showing nothing, the period scan crossing 801 times its own class's record count, a write consulting two indexes that do not serve its own query, and the write path stretching to two stores in exchange for splitting.
  7. 07 No Caching Measuring an expensive, repeated computation left without a cache: the period scan's read repeat of 1.00 turning into a computation repeat of 125.00, the key-building cost setting memoization's ceiling (2.53x), the break-even repeat computing to 1.63, memoization dropping to a 0.71x ratio and holding 119,365 entries under continuous weight, and the key not including the version making half the results wrong.
  8. 08 Noisy Neighbor Recognizing insufficient isolation on a shared resource from its symptom: separating the same latency growth's two causes via request share versus work share, the noise ratio climbing from 1.01 to 1.43, the work share jumping from 0.1702 to 0.2415 while the request share never moves, and fair share allocation's cost in the largest tenant's own delay rising from 0.47 to 2.96 rounds.
  9. 09 Synchronous I/O Measuring blocking calls' effect on capacity: separating the two causes of the same throughput ceiling by dependency utilization (0.9999 and 0.1819), the blocking design capping throughput at the concurrency limit divided by wait plus work time, the worker count needed to carry the same throughput growing 21-fold, and the fix's cost of in-flight requests rising from 8 to 46.
  10. 10 Retry Storm Recognizing from the outside a feedback loop that amplifies a failure: separating the same call-rate increase's two causes by edge rate, distinct request identity, and success ratio; the call rate climbing from 4.00 to 25.00 during the storm while distinct identity stays at 4.00; the product of call rate and success ratio staying constant at the capacity limit; and throttling the retry allowance costing 180 dropped requests.

02

Monitoring and Capacity

Making failure and slowness visible: building the monitoring categories completely as availability, health, performance, utilization, and security; turning which metric is worth collecting into an instrumentation decision; separating the decision-driving visualization from the alert threshold; load, soak, and spike tests asking separate questions; the move from measurement to resource estimate; and tying design decisions to operating cost with a resource unit.

  1. 01 Monitoring Categories Testing the completeness of a collected metric set with a coverage measure: separating monitoring from observability, defining the availability, health, performance, utilization, and security categories by the question each one asks, counting which diagnosis from the previous topic becomes impossible when a category is never collected, and showing that a diagnosis is built from a composition of metrics rather than a single metric.
  2. 02 Instrumentation Design Weighing both sides of whether a metric is worth collecting: computing its cost in records produced, bytes stored, and code path added; measuring on the same population the volume sampling and aggregation gain and the information they lose; comparing the percentile error of two similarly-priced forms; and choosing the aggregation form by the diagnosis it enables.
  3. 03 Dashboards and Alerts Turning a collected metric into a decision: showing that a dashboard and an alert answer separate questions; scanning threshold and window pairs over a month to count false alerts and missed events; measuring that raising the threshold misses events and that widening the window only cuts short-lived noise; and deriving the threshold from K01's monthly outage budget as a burn rate.
  4. 04 Load Testing Producing load instead of waiting for it: measuring that load, soak, and spike tests ask three separate questions and surface three separate symptoms, writing an open-loop load generator, showing that a long run at the same load reveals in tail latency a degradation invisible in the median, and counting that a spike's cost is larger than the spike itself.
  5. 05 Capacity Planning Turning measured utilization into a resource forecast: defining headroom as a utilization ceiling, computing node count as the greater of the load constraint and the failure constraint, counting how the redundancy premium shrinks with scale, the effect on node count of accumulation lowering effective capacity, and showing why improving performance does not lower the node count.
  6. 06 Cost Awareness Counting design decisions' operating cost in resource units: converting monthly resource consumption into a unit cost by dividing it by work volume, separating volume growth from unit-cost growth — which give the same total — using resource per unit of work, measuring how much of the purchased capacity does work, and showing that no fix removes cost, only shifts it between line items.

Start typing to search.

↑↓ Esc navigate · open · close