Lesson 78: Integrating Performance in Code
The Junior Trap: “Just Run It by Hand”
Here is the first thing a manual QA engineer does when they need to performance-test an API:
# The junior approach: click-ops performance testing
ab -n 1000 -c 10 http://localhost:8080/api/products
Or maybe they fire up JMeter, drag some elements around a GUI, click “Run,” get a pretty bar chart, and email a screenshot to the team.
This feels productive. It isn’t. Here’s why it falls apart the moment you try to scale your quality pipeline:
It lives nowhere. JMeter
.jmxfiles are XML nightmares that no one reviews in a pull request.abcommands get typed once and forgotten. There is no version history, no diff, no code review.It produces no machine-readable signal. CI pipelines speak exit codes. If your load test produces a PDF or a screenshot, your pipeline cannot decide whether the build should pass or fail. A
0exit code means “I ran,” not “the system is healthy.”It runs against whatever is in front of you. Manual tests target
localhost. They don’t run automatically when a developer merges a PR that adds a slow database join to the checkout path.It enforces nothing. If the p95 response time goes from 120ms to 1200ms between sprints, nobody knows until a customer complains. The manual tester ran the test last Tuesday and it was fine.
The failure mode is subtle: the test exists, but the information it produces doesn’t flow into the feedback loop that controls what ships.
The Failure Mode: Silent Performance Regressions
Imagine this sequence:
Sprint 3: checkout endpoint averages 180ms. Passes all functional tests.
A developer adds eager-loading of product images in the checkout response. Looks great in review — no bugs, no broken assertions.
Sprint 4: checkout endpoint averages 2,400ms. All functional tests still pass.
Sprint 5: customers are abandoning carts. An alert fires. Engineers spend a day bisecting commits.
The bug was never a functional bug. It was a performance regression — invisible to any assert response.status_code == 200 check. The only way to catch it is to define an SLA as code and enforce it on every merge.


