What Is Performance Testing? Types, Metrics, and How It Works
Performance Testing vs Functional Testing
Functional testing checks that software does the right thing: submitting the form creates the record, the total adds up, the login rejects a bad password. Performance testing checks that software does the right thing fast enough, at scale, without falling over. The two are independent. A checkout flow can pass every functional test and still collapse when 400 people hit it during a sale, and a blazing fast API can still calculate the wrong totals.
The practical difference shows up in how tests run. A functional test sends one request or clicks one button, then asserts on the result. A performance test sends thousands of requests from dozens or hundreds of simulated users at once, then asserts on statistics: the 95th percentile response time, the requests per second, the percentage of errors. One functional test failing points at a specific broken behavior. A performance test failing points at a systemic limit, and finding the cause usually means correlating the test output with server metrics like CPU, memory, and database load.
Both belong in a complete quality strategy, and they complement each other in pipelines: functional suites gate correctness on every commit, while lighter performance checks catch speed regressions and heavier load tests run before releases and traffic events. Our QA automation guide covers how the pieces fit together.
What Performance Testing Measures
Every performance test, whatever the tool, produces a handful of core measurements.
Response time is how long the system takes to answer a request, measured from send to last byte received. It is reported in percentiles: p50 (the median, a typical request), p95 (the slowest 1 in 20), and p99 (the slowest 1 in 100). Percentiles matter because averages hide problems. If 99 requests take 100 milliseconds and one takes 10 seconds, the average of roughly 200 milliseconds describes no actual request. Serious teams set targets on p95 or p99, for example "p95 under 500 milliseconds at expected peak load."
Throughput is how many requests the system completes per second. It defines capacity: a system that processes 800 requests per second with stable response times has a higher ceiling than one that saturates at 200. In test results, throughput and response time move together in a telling pattern: as load rises, throughput climbs while response times stay flat, until the system saturates, at which point throughput flattens and response times climb instead. That inflection point is the number capacity planning is built on.
Error rate is the fraction of requests that fail, through 5xx status codes, timeouts, or dropped connections. Under normal load it should be zero. The load level where errors first appear defines the hard limit of the current setup, and how the system fails matters too: returning clean "try again later" responses is a very different outcome from hanging every request for 30 seconds.
Resource utilization covers what the servers themselves are doing during the test: CPU, memory, disk and network I/O, database connections, thread pools. These metrics explain the others. Response times that degrade exactly as CPU reaches 95% tell you the bottleneck is compute. Errors that appear when the connection pool hits its cap tell you where to look instead. Running a load test without watching server metrics gets you a symptom report with no diagnosis.
The Six Main Types of Performance Testing
Performance testing splits into named test types, each designed to answer one question. The names get used loosely in casual conversation, but the distinctions are worth keeping because each type finds problems the others miss.
Load testing checks behavior at expected traffic. You simulate the concurrency your analytics predict, hold it steady for 15 to 30 minutes, and verify response times and errors stay within targets. It is the default test, the one meant by "we should load test this before launch."
Stress testing increases load beyond expectations until the system degrades, to find the capacity ceiling and observe the failure mode. Load testing proves you can handle Tuesday. Stress testing tells you what happens on the day you get ten times Tuesday.
Spike testing applies sudden jumps in traffic rather than gradual ramps, simulating flash sales and viral moments. It specifically tests whether autoscaling and load shedding react in seconds rather than minutes.
Soak testing runs sustained moderate load for hours or days to expose time-dependent failures: memory leaks, connection leaks, disk-filling logs, and degradation from long-running processes. Systems that pass every short test can still fail after eight quiet hours.
Scalability testing measures whether adding resources adds capacity proportionally. If doubling servers only adds 20% capacity, a shared bottleneck, often the database, caps your growth, and it is better to learn that in a test than in an emergency purchase.
Volume testing holds request rates steady but grows the data: millions of rows instead of thousands, to catch queries and jobs whose cost grows with table size. It matters most for products expecting data to accumulate for years. The full breakdown of when to use each type lives in our load vs stress testing comparison.
Backend and Frontend Performance
Everything above describes backend testing, where tools fire synthetic requests at servers. The other half of performance is the frontend: what happens in the browser after the server responds. A server can answer in 80 milliseconds while the page still takes six seconds to become usable, because rendering, JavaScript execution, and asset loading all happen client-side.
Frontend performance has its own measurements, standardized by Google as Core Web Vitals: Largest Contentful Paint for loading speed, Interaction to Next Paint for responsiveness, and Cumulative Layout Shift for visual stability. These are measured for real users and affect search rankings, which makes them the frontend metrics with direct business consequences. Lab tools like Lighthouse diagnose the causes, and speed test services measure pages from outside.
The two halves need each other. Backend load tests at production concurrency plus frontend audits on key pages cover the full journey from request to rendered pixel, which is what the user actually experiences.
How a Performance Test Actually Runs
A concrete example makes the mechanics clear. Suppose an online store expects 250 concurrent users at peak and wants checkout to stay under one second at p95.
The engineer writes a script in a load testing tool, k6 for example, that simulates a realistic session: load the home page, browse two category pages, view a product, add it to the cart, and check out, with a few seconds of think time between steps, using varied product IDs so caching does not mask real behavior. The tool's configuration ramps from 0 to 250 virtual users over five minutes, holds 250 for twenty minutes, and ramps down.
During the run, the tool records every request's timing and outcome while dashboards capture server CPU, memory, and database metrics on the same timeline. Afterward, the results show p95 checkout time at 1.4 seconds, over target, with response times bending upward at around 180 virtual users just as database CPU saturates. Query analysis finds an unindexed lookup on the inventory table. After adding the index, a rerun shows p95 at 420 milliseconds with database CPU peaking at 60%. The test passes, and the before-and-after numbers document exactly what the fix bought.
That loop, measure, diagnose, fix, remeasure, is the whole practice. Tools and scale vary, but every performance testing effort from a solo project to an enterprise program follows it.
When to Performance Test
Before launch is the classic moment: establish that the system meets targets at expected traffic, and learn the ceiling with a stress test. Before known traffic events, marketing pushes, product launches, seasonal peaks, rerun against updated traffic estimates with enough lead time to act on findings.
After significant architecture changes, new database, new framework, new hosting, retest even if features are unchanged, because performance characteristics do not survive migrations automatically. And continuously, in lightweight form: short threshold-based checks in CI catch regressions per-commit, covered in our CI/CD test automation guide, while production monitoring, covered under website monitoring, watches the metrics that matter between test runs.
The common thread is testing before the answer is needed, with time to fix what surfaces. Performance findings tend to require real work, index changes, caching layers, infrastructure resizing, and none of that fits into the afternoon before a launch.
Performance testing measures speed, capacity, and stability rather than correctness: how fast the system responds, how much traffic it handles, and what breaks first. Its core metrics are response time percentiles, throughput, error rate, and resource utilization, and its main types, load, stress, spike, soak, scalability, and volume testing, each answer one specific question. Start with a load test at expected traffic against defined targets, watch p95 rather than averages, and always correlate results with server metrics so findings come with diagnoses.