Most performance work is guessing. And most guesses are wrong. Profiling replaces guessing with evidence.
Step 1: Define the Metric
- API response time (p95 / p99)
- CPU usage
- Memory usage
- Database query time
- Frontend load time (LCP, CLS)
Pick one primary metric or you’ll optimize randomly.
Step 2: Add Timing Around Key Steps
# Python example
import time
t0 = time.perf_counter()
result = do_work()
t1 = time.perf_counter()
print(f"do_work took {t1-t0:.3f}s")
Step 3: Use Real Profilers
Python: cProfile, py-spy
Node: –inspect + Chrome profiler
Java: JFR (Java Flight Recorder)
Go: pprof
Common Bottlenecks (In Order)
- Slow database queries (missing indexes, N+1 queries)
- Network calls (chatty services, sequential calls)
- Serialization overhead (huge JSON payloads)
- CPU-heavy loops (bad algorithms)
- Logging too much (yes, this happens)
What to Do When You Find a Hotspot
- If it’s DB: add indexes, batch queries, reduce joins, cache results
- If it’s network: parallelize, batch, add timeouts, cache responses
- If it’s CPU: pick better algorithms, avoid unnecessary work, use compiled libs
Profiling isn’t glamorous, but it’s one of the highest-leverage skills you can learn. The best performance fixes are boring: one index, one cache layer, one N+1 fix. Evidence beats intuition.
