🔥 0
0
Lesson 9 of 10 25 min +200 XP

Results Analysis & Bottlenecks

Running a load test is easy. Understanding the results is where real performance engineering happens.

This lesson teaches you to read JMeter results like a detective - finding the performance problems hiding in the numbers.

Key Performance Metrics

The Big Four

MetricWhat It MeasuresGood vs Bad
Response TimeHow long requests takeLower is better
ThroughputRequests processed per secondHigher is better
Error RatePercentage of failed requestsLower is better (< 1%)
Concurrent UsersActive users at any momentDepends on your goals

Response Time Breakdown

Response Time Breakdown

Total Response Time = Network Connect + Server Processing + Data Transfer. The Server Processing portion is the part your code controls - this is where optimization efforts should focus.

In JMeter, look at:

  • Latency: Time until first byte received (network + server start processing)
  • Connect Time: TCP connection establishment
  • Response Time: Total from request sent to response complete

Why Averages Lie

Consider this test result:

1000 requests total:
- 950 requests: 100ms
- 50 requests: 5000ms

Average: (950 * 100 + 50 * 5000) / 1000 = 345ms

345ms average sounds acceptable. But 5% of your users waited 5 seconds. On a site with 10,000 daily users, that's 500 frustrated people.

Always look at percentiles.

Understanding Percentiles

P50
Median - half faster, half slower
P90
90% faster than this
P95
95% faster - common SLA
P99
99% faster - worst 1%

Real Example

Response times for "Get Product" (1000 samples):

P50 (Median):  85ms   ← Half your users see this or better
P90:           145ms  ← 90% see this or better
P95:           280ms  ← 95% see this or better
P99:           1250ms ← 99% see this or better
Max:           4500ms ← Your worst case

Average:       165ms  ← Hides the P99 problem!
SLA Recommendation: Base SLAs on P95 or P99, not average.

JMeter Listeners for Analysis

Summary Report

Quick overview of all samplers:

LabelSamplesAverageMinMaxStd DevError%Throughput
Get Products50001454523401890.2%85.3/sec
Add to Cart30002347845004121.5%51.2/sec
Checkout100089032089007563.2%17.1/sec
Red flags in this data:
  • Add to Cart: High Std Dev (412) indicates inconsistent performance
  • Checkout: 3.2% error rate is too high, and Max of 8900ms is problematic

Aggregate Report

Includes percentile data:

LabelP90P95P99ThroughputKB/sec
Get Products18024589085.3/sec1024.5
Add to Cart340580210051.2/sec156.8
Checkout12002400650017.1/sec89.2
Red flag: Checkout P99 of 6500ms means 1% of checkout attempts take over 6.5 seconds.

Identifying Bottlenecks

Pattern 1: Throughput Plateau

Time     Threads   Throughput   Avg Response
0:00     50        100/sec      150ms
0:05     100       195/sec      160ms
0:10     150       280/sec      180ms
0:15     200       295/sec      340ms    ← Plateau starts
0:20     250       300/sec      580ms    ← Throughput stuck
0:25     300       298/sec      890ms    ← Response time climbing
0:30     350       295/sec      1200ms   ← Queue building up
Diagnosis: System hit capacity at ~300 req/sec. Adding threads just increases queue time. Common causes:
  • CPU saturation on application server
  • Database connection pool exhaustion
  • Network bandwidth limit
  • Thread pool size limit

Pattern 2: Error Spike at Threshold

Time     Threads   Throughput   Error Rate
0:00     50        100/sec      0.1%
0:05     100       198/sec      0.2%
0:10     150       290/sec      0.3%
0:15     200       310/sec      0.5%
0:20     250       315/sec      5.2%     ← Sudden spike!
0:25     300       280/sec      12.8%    ← Cascading failures
Diagnosis: Resource exhaustion at 250+ threads. Likely connection pool or memory.

Pattern 3: Gradual Degradation (Soak Test)

Hour     Throughput   P95 Response   Memory (App Server)
1        500/sec      200ms          2.1 GB
2        498/sec      210ms          2.4 GB
4        495/sec      240ms          3.1 GB
6        480/sec      320ms          3.8 GB
8        450/sec      580ms          4.5 GB    ← Memory leak!
Diagnosis: Memory leak causing garbage collection pauses.

Database Bottleneck Indicators

Connection Pool Exhaustion

JMeter error:

Error: Unable to acquire connection from pool
Error: Connection pool exhausted (max: 50)

Application logs:

WARN  HikariPool - Connection pool is at 100% capacity
ERROR HikariPool - Connection not available, waited 30000ms
Solutions:
  • Increase pool size (temporary fix)
  • Optimize slow queries (real fix)
  • Add connection timeouts
  • Check for connection leaks

Slow Query Indicators

Request              Avg Response   P99 Response
Get Products         150ms          350ms        ← Fast
Get Product Detail   180ms          400ms        ← Fast
Search Products      850ms          3500ms       ← SLOW
Get Order History    1200ms         5500ms       ← SLOW
Actions:
  • Check database slow query log
  • Add missing indexes
  • Optimize or cache expensive queries

Lock Contention

Symptom: Response times increase dramatically under load, but CPU is not maxed.

Time     Threads   CPU%   Throughput   Avg Response
0:00     50        25%    100/sec      150ms
0:10     100       35%    180/sec      220ms
0:20     150       40%    200/sec      450ms      ← CPU not the limit
0:30     200       42%    195/sec      780ms      ← Throughput dropping
Diagnosis: Database lock contention. Threads waiting for locks, not CPU.

Reading JMeter Results Files

Generate HTML Report

jmeter -g results.jtl -o report-folder/

This creates a comprehensive HTML report with:

  • Dashboard overview
  • Response time graphs
  • Throughput over time
  • Error analysis
  • Top 5 errors by sampler

Key Report Sections

APDEX (Application Performance Index):
  • Score 0-1 (1 is perfect)
  • Based on satisfied/tolerating/frustrated thresholds
  • Quick pass/fail indicator
Response Time Percentiles:
  • Graph showing P50, P90, P95, P99 over time
  • Look for spikes correlating with thread increases
Throughput Over Time:
  • Should increase with threads until plateau
  • Drops indicate problems

Bottleneck Checklist

When Performance Degrades, Check:
  1. Application Server: CPU, memory, thread pools
  2. Database: Connection pool, slow queries, lock waits
  3. Network: Bandwidth, latency, connection limits
  4. External Services: Payment gateway, CDN, third-party APIs
  5. Load Balancer: Connection limits, health check failures
  6. JMeter Itself: Running in GUI mode? Too many listeners?

Common Mistakes in Analysis

Mistake: Ignoring Warm-up Period

First few minutes show JIT compilation, cache warming, connection pool filling. Exclude initial ramp-up from analysis. Look at steady-state results.

Mistake: Testing Against Wrong Environment

Staging has 1 server, production has 10. Results don't scale linearly. Test against production-like infrastructure or understand the differences.

Mistake: Only Looking at Happy Path

Error responses are often faster than successful ones (less processing). High error rates can make average times look good while the system is failing.

Key Takeaways

  • Use percentiles, not averages: P95 and P99 reveal what your worst-affected users experience.
  • Throughput plateau = bottleneck: When throughput stops increasing despite more threads, you've hit a limit.
  • Correlate metrics: Response time + throughput + error rate together tell the real story.
  • Check the database first: Connection pools and slow queries cause most e-commerce performance issues.

Next Lesson

You can analyze results. Now let's scale up: Distributed Testing and CI/CD - running tests from multiple machines, integrating with Jenkins and GitHub Actions, and avoiding common production testing mistakes.

🧠 Quick Quiz

Test your understanding of this lesson.

1

Why is average response time often misleading?

2

What does it mean when throughput plateaus while response time increases?

3

What typically causes 'Error: Connection pool exhausted'?

API Load Testing