How to Do Performance Testing
Performance testing answers one question: will the system stay fast and stable when real users arrive? It isn't a single button you press — it's a process that starts with clear goals and ends with evidence the team can act on. This guide walks through the seven steps, then shows a real ramp-up test so you can see what "finding the limit" actually looks like in the numbers.
Step 1 — Understand the System and Environments
- Architecture: web servers, APIs, databases, caches, queues, third-party services — each can be the bottleneck.
- Test vs production environment: CPU, memory, number of instances, database size and network. Results from a small test environment don't scale linearly to production, so record the differences.
- Monitoring: how you'll see CPU, memory, database and application metrics during the test (APM tools, Grafana, cloud dashboards).
Step 2 — Define Acceptance Criteria
Without numbers agreed up front, nobody can say whether a test passed. Typical criteria:
| Metric | Example target |
|---|---|
| Response time | Search: 95% of requests under 800 ms (p95 < 800 ms) |
| Throughput | At least 300 orders per minute |
| Error rate | Below 1% at peak load |
| Resource use | CPU below 75% at expected peak, leaving headroom |
| Stability | No memory growth over a 4-hour soak test |
Use percentiles, not averages: an average of 300 ms can hide 5% of users waiting 4 seconds. Targets come from product owners, SLAs, current production metrics or competitor benchmarks — testers often have to drive this conversation because requirements rarely include them.
Step 3 — Plan the Workload
- Key journeys: the flows that matter most and are used most — login, search, product page, checkout.
- Mix: for example 60% browse, 25% search, 10% cart, 5% checkout — based on analytics, not guesses.
- Load levels: normal, expected peak (sale day), and beyond peak.
- Test types: load (expected peak), stress (beyond peak until it breaks), spike (sudden jump), soak/endurance (hours at normal load), scalability (does adding servers help?).
- Test data: enough unique users, products and orders — reusing one account creates unrealistic caching and locking.
More on the types: Non-Functional & Performance Testing.
Step 4 — Prepare the Environment
- An isolated, production-like environment — never run load tests against production or shared environments without explicit agreement.
- Production-sized data (a query that's fast on 1,000 rows may crawl on 10 million).
- Load generators with enough capacity — an overloaded test machine produces false "slow" results.
- Monitoring switched on for every tier.
Step 5 — Build the Test Scripts
- Record or write each journey in the tool — JMeter, k6, Gatling or Locust.
- Correlate dynamic values (session IDs, CSRF tokens, order IDs) so each virtual user behaves like a real one.
- Parameterize data (different users and search terms from a CSV).
- Add think time between steps — real users pause.
- Add assertions so a fast error page doesn't count as a success.
- Run each script with one user first to prove it works.
See how JMeter thread groups, samplers, timers and listeners fit together — and how load ramps up — in the JMeter Visualizer. For API-level load testing: API Performance & Load Testing.
Step 6 — Run the Tests
- Ramp up gradually so you can see the point where behavior changes.
- Hold each level long enough to stabilize (several minutes in real tests).
- Watch errors and server metrics live — stop if the system is clearly failing.
- Keep a log: build version, configuration, time, anything unusual.
Step 7 — Analyze, Fix and Retest
- Compare results against the acceptance criteria.
- Find the knee — the load where response times start climbing and throughput stops growing.
- Correlate with server metrics to locate the bottleneck: CPU, memory, database, connection pools, thread pools, a slow external call.
- Report the finding with evidence; developers or operations fix it (a query index, a larger pool, caching).
- Retest with the same scenario and compare. Keep a baseline so future releases can be checked for regressions.
Stop tuning when the targets are met with headroom — not simply when the CPU becomes the bottleneck. A CPU-bound system may still be efficient; the question is whether it meets the agreed goals at the expected load.
What a Ramp-Up Test Looks Like: Real Numbers
We ran a small ramp-up test with the open-source tool autocannon against a test service that can process 20 requests at a time, each taking about 40 ms of work. Each level ran for 8 seconds:
| Concurrent users | Throughput (req/s) | p50 | p90 | p99 | Errors |
|---|---|---|---|---|---|
| 10 | 114 | 83 ms | 84 ms | 87 ms | 0 |
| 20 | 238 | 84 ms | 85 ms | 90 ms | 0 |
| 50 | 483 | 87 ms | 119 ms | 123 ms | 0 |
| 100 | 479 | 169 ms | 200 ms | 1,311 ms | 0 |
| 200 | 490 | 227 ms | 243 ms | 1,388 ms | 0 |
How to read it:
- Up to 50 users, throughput grows with load and response times barely move — the system has spare capacity.
- Beyond 50 users, throughput stops growing at about 480 requests/second. More users only means more waiting: the median doubles and the p99 jumps to over 1.3 seconds. That's the knee — the system has hit a bottleneck (here, the 20-slot processing limit; in a real system, perhaps a thread pool or database connection pool).
- No errors were recorded — which is exactly why error rate alone isn't enough. Users would still experience the system as slow.
- The average hides the problem; the p99 column shows the 1% of users having a bad time.
Absolute numbers depend on hardware and aren't comparable to a real application — the shape of the results is what you learn to recognize.
From Real Projects
My testing experience centers on functional, integration, system and regression testing on Apkope, Canolog and Testsigma. Performance testing builds on the same foundation — you need to understand the business flows before you can load them realistically. Agree on measurable targets before running any test — otherwise nobody can say whether it passed.
📚 Official documentation: Apache JMeter user manual · ISTQB Glossary of testing terms
FAQs
What are the steps of performance testing?
Understand the system and environments, define acceptance criteria, plan the workload, prepare the environment, build the scripts, run the tests, then analyze, fix and retest.
What are performance acceptance criteria?
Agreed, measurable targets — response-time percentiles, throughput, error rate, resource use and stability — against which test results are judged.
Why use percentiles instead of averages?
Averages hide slow outliers. A p95 or p99 tells you how the slowest users experience the system.
How do you find the bottleneck?
Ramp up load gradually, find the point where throughput stops growing and latency climbs, and match it with server metrics (CPU, memory, database, pools).
When should you stop tuning?
When the agreed targets are met with enough headroom for growth — and keep the results as a baseline for future releases.
Which tools are used for performance testing?
JMeter, k6, Gatling and Locust are common open-source choices; LoadRunner and cloud services are used in larger organizations.