Performance & Security Resilience Testing
Resilience is what a product does when conditions stop being ideal: traffic doubles, a payment provider times out, a bot hammers the login form, a token is replayed after it expired. Functional tests prove the product works; resilience testing proves it keeps working, degrades safely, and recovers — under load, under failure and under attack.
This guide covers the three parts together because they fail together in production. It defines the test types, sets out what to measure and what "good" looks like as a number, walks through the OWASP baseline for web applications and APIs, and ends with a one-page plan a team can run before a launch.
What is resilience testing?
Resilience testing is the group of activities that measure how a system behaves outside its normal operating conditions. ISO/IEC 25010 covers it under three quality characteristics — performance efficiency (time behaviour, resource use, capacity), reliability (availability, fault tolerance, recoverability) and security (confidentiality, integrity, authenticity, accountability). A product can score well on functional suitability and badly on all three.
The three families of tests are different in method but share one rule: each needs a target written as a number before the test runs. "The API should be fast" is not a target; "p95 latency under 400 ms at 200 requests per second with an error rate below 0.1%" is. Without the number, a test produces a report that nobody can pass or fail.
- Performance — load, stress, soak and spike tests: how the system behaves as demand rises, past its limit and over time.
- Failure — what happens when a dependency is slow, wrong or gone, and whether the system recovers by itself.
- Security — whether the common weaknesses catalogued by OWASP are present, and whether the controls (authentication, sessions, headers, input handling) hold.
Performance testing: load, stress, soak and spike
A load test applies the expected traffic — the workload model — and measures latency, throughput and error rate against the targets. A stress test raises the load past the expected peak until something breaks, to find the limit and see how the system fails: slowly and safely, or all at once. A soak (endurance) test holds a realistic load for hours to expose leaks, growing queues and connection exhaustion that a ten-minute test never sees. A spike test jumps from idle to peak in seconds, which is what a marketing campaign or a news mention does.
- Load testThe expected traffic (the workload model); latency, throughput and error rate measured against targets.
Reference line:expected peak
- Stress testPast the expected peak until something breaks: does it fail slowly and safely, or all at once?
Reference line:expected peak
something breaks
- Soak (endurance) testA realistic load held for hours: leaks, growing queues, connection exhaustion.time · hours
Reference line:expected peak
- Spike testFrom idle to peak in seconds, as after a marketing campaign or a news mention.
Reference line:expected peak
Schematic shapes on one shared load scale: the heights and time spans are illustrative.
The workload model matters more than the tool. It should come from real traffic — which endpoints, in what mix, with what data, at what concurrency — not from a single endpoint hit in a loop. Apache JMeter, k6 and similar tools all take a data file of users, tokens and payloads; generating that data with the right variety (different users, different record sizes, invalid inputs mixed in) is most of the preparation. Run against an environment sized like production, or the numbers describe the wrong system.
- Record p50, p95 and p99 latency, not the average — the average hides the slow tail users actually feel.
- Record error rate and error type separately: a system that stays fast by returning 500s has not passed.
- Measure before and after a change with the same workload, so the comparison is honest.
- For web front-ends, add the Core Web Vitals (LCP, INP, CLS) measured on real devices; server latency is only part of what a user waits for.
Try it: Load Test Data Generator Try it: JMeter Test Data Generator Try it: Concurrent Request Test Generator Try it: HTTP Request Benchmark Try it: Response Time Analyzer Try it: API Performance Comparator
Failure and recovery: testing what happens when a dependency dies
Most outages are not caused by the system under test but by something it depends on: a database that becomes slow, a third-party API that starts returning 503, a queue that fills. The patterns that keep a failure local are well documented — timeouts on every outbound call, retries with exponential backoff and a cap, circuit breakers that stop calling a failing dependency, bulkheads that keep one exhausted pool from taking the rest down, and graceful degradation that serves a reduced result instead of an error page. Michael Nygard's Release It! remains the standard reference for these stability patterns.
Testing them means causing the failure on purpose. At the API level that is simple: point the system at a mock that returns 500, 503 or 429 with a Retry-After header, that answers after 30 seconds, or that returns a malformed body, and check the system's behaviour — does it time out, retry sensibly, return a clear error to its own caller, and recover when the mock comes back? Rate limiting deserves its own test: RFC 6585 defines 429 Too Many Requests, and a client that retries a 429 immediately makes the problem worse.
- Every outbound call has a timeout shorter than the caller's own timeout.
- Retries are bounded, use backoff, and never retry non-idempotent requests blindly.
- A failing dependency produces a specific, logged error — not a generic 500 and not a hang.
- Recovery is automatic: when the dependency returns, traffic resumes without a restart.
Try it: API Status Code Simulator Try it: Mock Error Response Generator Try it: Mock Error Payload Generator
Security testing: the OWASP baseline
Security testing before launch is not a penetration test by a specialist team — that comes later and goes deeper. It is a baseline: checking that the weaknesses found most often in real breaches are absent. The OWASP Top 10 lists them for web applications (broken access control, security misconfiguration, injection, authentication failures and software supply-chain failures, among others) and the OWASP API Security Top 10 for APIs, where broken object-level authorisation — one user reading another's record by changing an id — is the most common finding. The OWASP Application Security Verification Standard (ASVS) turns these into testable requirements, and the Web Security Testing Guide (WSTG) into test procedures.
A useful share of the baseline can be checked from the outside with no special access. Response headers show whether HSTS, Content-Security-Policy, X-Content-Type-Options and frame protection are set. Cookies show whether the session cookie carries Secure, HttpOnly and SameSite. Tokens show whether the algorithm is pinned, whether expiry is short and whether the audience is checked. CORS shows whether an origin policy exists or a wildcard is doing its job for it. Each of these is a ten-minute check and each has caused real incidents.
- Access control — every endpoint tested with a valid token for the wrong user and for the wrong role.
- Injection — inputs that reach SQL, shell, LDAP or templates tested with hostile values; parameterised queries confirmed.
- Authentication and sessions — password rules, lockout, token lifetime, logout that actually invalidates.
- Configuration — security headers present, verbose errors off, default credentials gone, TLS current.
- Data — personal data encrypted in transit and at rest, and never present in logs or test environments.
Try it: Security Header Analyzer Try it: Cookie Analyzer Try it: API Authentication Tester Try it: JWT Decoder Try it: CORS Tester
Measuring: SLOs, error budgets and what to keep
A service level objective (SLO) is the target written down — "99.9% of requests succeed within 400 ms over 30 days" — and the error budget is the failure it allows. The site reliability engineering practice described in Google's SRE book uses these to decide when a team ships features and when it stops to fix reliability; the same numbers are what a performance test is checked against before launch and what monitoring watches after it.
Caching is the cheapest performance work and one of the least tested. A response that carries the right Cache-Control and ETag headers is served by browsers and CDNs without touching the origin; one that carries none is fetched every time. Checking the caching headers of the heaviest endpoints belongs in the same session as the load test, because it changes what load the origin sees.
- Keep the workload model, the environment description and the raw results of every run; a number without its context cannot be compared next quarter.
- Alert on the SLO, not on CPU: users experience latency and errors, not resource graphs.
- Re-run the resilience suite on every release that touches infrastructure, authentication or a hot path — not only before the first launch.
Try it: Cache Header Analyzer Try it: Response Size Analyzer
Regulatory context in Saudi Arabia
For organisations in the Kingdom, resilience testing is also a compliance activity. The National Cybersecurity Authority's Essential Cybersecurity Controls (ECC) include controls on vulnerability management, penetration testing and secure configuration for systems in scope, and the Personal Data Protection Law governs how personal data may be used — which rules out copying customer data into a load-testing dataset. Synthetic data of the right shape (Saudi phone formats, national addresses, IBANs) satisfies both the test and the law.
- Map each resilience activity to the ECC control it evidences; the test report is the evidence.
- Generate load-test and security-test data; never derive it from production records.
Try it: Saudi Address Test Data Try it: Test IBAN Generator Try it: Fake Phone Number Generator
A resilience test plan in one page
- Targets: p95 and p99 latency, throughput and error rate at expected and peak load, written before testing.
- Workload model: endpoint mix, data variety and concurrency taken from real traffic or the business forecast.
- Load test at expected load; stress test to the breaking point; soak test for at least two hours; spike test from idle to peak.
- Failure injection: each critical dependency made slow, wrong and unavailable; recovery observed.
- OWASP baseline: access control, injection, authentication and sessions, headers and cookies, CORS, data exposure.
- Caching headers verified on the heaviest endpoints.
- Results kept with their context; SLOs and alerts configured from the same numbers; suite scheduled for every infrastructure or authentication change.
Frequently asked questions
What is the difference between load testing and stress testing?
A load test applies the expected traffic and checks the system meets its targets. A stress test increases the load past the expected peak until the system fails, to find the limit and to see whether it fails safely — slower responses and clear errors — or catastrophically. Both are needed: the first proves the promise, the second finds the margin.
How many virtual users do we need?
Derive it from real numbers: peak concurrent sessions from analytics, or the business forecast for a launch, plus a margin. A virtual user in JMeter or k6 sends requests in a loop with think time, so "200 virtual users" means little on its own; state the target as requests per second per endpoint mix and size the users to reach it.
Is a vulnerability scanner enough for security testing?
A scanner finds known patterns — missing headers, outdated components, some injection points — quickly and cheaply, and it belongs in the pipeline. It does not find broken access control, the most common weakness in both OWASP lists, because that requires knowing which user should see which record. Baseline testing adds those checks by hand; a penetration test goes further.
Should performance tests run against production?
Load and stress tests should not — they degrade the service for real users and can trip fraud or rate-limit controls. Run them against an environment sized like production. Read-only synthetic checks (a single request per minute measuring latency) are safe and useful in production as monitoring.
How often should resilience testing be repeated?
Before the first launch in full, then on every release that changes infrastructure, authentication, data access or a high-traffic path, and on a fixed schedule — quarterly is common — because dependencies and traffic change even when the code does not.
References
- Apache JMeter User's ManualHow to build, parameterise and run load tests with JMeter, and how to read its listeners and reports.
- Web VitalsThe Core Web Vitals (LCP, INP, CLS): what they measure and the thresholds for a good user experience.
- Release It! Second Edition: Design and Deploy Production-Ready Software (Michael T. Nygard)Stability patterns — timeouts, circuit breakers, bulkheads, back-pressure — and the failure modes load testing is meant to find.
- Site Reliability Engineering: How Google Runs Production SystemsService level objectives, error budgets, monitoring the "four golden signals" and handling overload — the operational side of resilience.
- OWASP Top 10:2025The ten most critical web application security risks, with how to test for and prevent each.
- OWASP API Security Top 10 (2023)The ten most common API weaknesses: broken object-level authorization, broken authentication, unrestricted resource consumption and more.
- OWASP Application Security Verification Standard (ASVS)A checklist of verifiable security requirements for web applications, grouped in three assurance levels.
- OWASP Web Security Testing Guide (WSTG)The reference methodology for testing web applications and APIs for security weaknesses, test by test.
- NIST SP 800-115: Technical Guide to Information Security Testing and AssessmentHow to plan and run security assessments: review, target identification, vulnerability validation and reporting.
- RFC 6585: Additional HTTP Status CodesDefines 428, 429 Too Many Requests, 431 and 511, including the Retry-After header for rate limiting.
- National Cybersecurity Authority — Regulatory documents and controls (Essential Cybersecurity Controls)The Saudi national cybersecurity controls that organisations in the Kingdom test against, including application security and vulnerability management.
- ISO/IEC 25010:2023 — Systems and software Quality Requirements and Evaluation (SQuaRE) — Product quality modelThe product quality model: functional suitability, performance efficiency, compatibility, interaction capability, reliability, security, maintainability and flexibility.
Practice exercise
Judge a ticket sale’s resilience before it opens
You are the QA engineer of a ticketing platform (fictional) with a web site and a mobile app. Tickets for the season-opening football match go on sale on Thursday 22 October 2026 at 20:00 Riyadh time, and a push notification reaches every app user in the same minute. Today is Tuesday 13 October. The material below gives the forecast and the targets the product owner agreed, a colleague’s draft resilience plan, and the results of the first dry runs on staging-perf, a performance environment sized like production: four performance runs, five failure-injection checks against a mock of the payment gateway, and five security baseline observations.
Work on paper and use the guide’s one-page plan as your checklist. For every result, write a verdict (pass, fail, or not judged against the targets) with the number or the rule behind it. The Security Header Analyzer and the Cookie Analyzer help with S1, and the Unix Timestamp Converter with S2. Allow 60–90 minutes.
The security checks in the material were run on the platform’s own staging environment with its owner’s written permission. Run such checks only on systems you own or have written permission to test.
Ticketing platform (fictional) - web site and mobile app
Sale: season-opening football match, Thu 22 Oct 2026, 20:00-24:00 Riyadh time.
A push notification reaches every app user at 20:00. Today: Tue 13 Oct 2026.
Forecast (business)
Normal evening: 40 requests per second (req/s).
Sale: 450 req/s from the first minute after 20:00; 300 req/s from 21:00 to 24:00.
Endpoint mix: seat map 55 %, sign-in with SMS code 10 %, hold seats 20 %,
pay 10 %, order status 5 %.
Targets agreed with the product owner on 1 Oct
T1 Seat map, GET /api/events/{id}/seatmap: p95 <= 800 ms and p99 <= 1,500 ms
T2 Pay, POST /api/orders/{id}/pay (includes the payment gateway): p95 <= 3,000 ms
T3 Error rate below 0.1 % (5xx, timeouts, and 429 sent by the platform)
T1-T3 hold with the endpoint mix from the first minute of the sale to its end.
Draft resilience plan v0.1 (written by a colleague)
1 Goal: the site must be fast and must not crash during the sale.
2 Load test: 200 virtual users call GET /api/events/77/seatmap in a loop, 10 min.
3 Run it on production at 03:00, when nobody is buying, so the numbers are real.
4 Pass if the average response time is under 1 second.
5 Test data: export last season’s 50,000 customers from production.
6 Soak test: 15 minutes.
7 Security: run the vulnerability scanner on the night before the sale.
Dry runs on staging-perf (sized like production, endpoint mix, synthetic data)
Seat map latency and pay p95 in ms; errors as a share of all requests.
Run Type Load and length avg p50 p95 p99 Pay p95 Errors
R1 load 450 req/s, 30 min 240 180 620 1,350 2,400 0.04 %
R2 spike 40 to 450 req/s in 30 s 520 210 2,900 7,800 5,100 2.1 %
R3 soak 300 req/s, 4 h: hour 1 170 150 540 1,100 2,300 0.02 %
hour 4 410 230 1,450 3,900 4,800 0.9 %
R4 stress 450 req/s, +50 req/s every 5 min until it breaks (see note)
Error types: R1 all 503; R2 500 and 504.
R2: figures for the first 5 min after the jump; from minute 6 the values match R1.
R3: database connections in use 60 of 200 in hour 1, 200 of 200 in hour 4.
R4: errors stay below 0.1 % up to the 800 req/s step; it breaks at 850 req/s, where
41 % of responses are 503 (a generic HTML page) and seat map p95 falls to 95 ms.
Back at 450 req/s, errors are below 0.1 % within 2 min, without a restart.
Failure injection on staging-perf: the payment gateway is replaced by a mock
F1 Mock returns a malformed JSON body: the payment service logs "gateway response
invalid"; the app shows "Payment failed, you were not charged"; order unpaid.
F2 Mock answers after 30 s. The API gateway in front of the platform times out at
20 s and the app shows "Something went wrong"; the payment service waits up to
60 s, and the order turns "Paid" 31 s after the request.
F3 Mock returns 503: the payment service resends POST /charges 3 times at once,
without an idempotency key. Mock log: 4 charge requests for one order.
F4 Mock returns 429 with Retry-After: 30. The payment service retries 10 times
within 1 s, then returns 500 Internal Server Error to the app.
F5 Mock unavailable for 5 min, then back: payments keep failing until the payment
service is restarted 25 min later.
Security baseline on staging (with the platform owner’s written permission)
S1 Response headers of GET https://staging.tickets.example/
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
X-Content-Type-Options: nosniff
Set-Cookie: sid=7f3c9a51e2; Path=/; Secure
S2 Mobile app access token after sign-in, decoded
header {"alg":"HS256","typ":"JWT"}
payload {"sub":"u-1042","role":"customer","iat":1791874800,"exp":1794466800}
S3 Token of customer u-1042: GET /api/orders/88213 (an order of customer u-2210)
200 OK with that customer’s name, mobile number and seats
S4 OPTIONS /api/orders with Origin: https://unknown-site.example
Access-Control-Allow-Origin: https://unknown-site.example
Access-Control-Allow-Credentials: true
S5 Body of the 500 responses during R2
{"error":"TimeoutError: pool exhausted at /srv/app/db/pool.js:41"}- Review the draft plan against the guide: write what is wrong with each item and what is missing, then rewrite it as a one-page resilience plan for this sale.
- Judge R1–R4 against T1–T3, target by target, and write what each run tells you beyond the numbers. Would the draft’s pass criterion have caught the problems?
- For F1–F5, decide whether the behaviour is acceptable; if it is not, name the stability rule from the guide that it breaks and write the expected behaviour.
- For S1–S5, write each finding, the part of the OWASP baseline it belongs to and the expected result. Then list the baseline checks the material does not cover yet.
- Write the go/no-go note for the release manager: what must be fixed and re-tested before the sale, what else to fix, what to run again after the fixes, and what to keep from these runs.
Show the model answer
The draft plan, item by item. 1: "fast" and "must not crash" are not targets; a test needs a number before it runs, and T1–T3 already give percentiles, a load and an error rate. 2: one endpoint in a loop is not the workload model, which here is 450 req/s with the agreed endpoint mix. "200 virtual users" says little on its own, because a virtual user waits a think time between requests: state the load in req/s and size the virtual users until the tool reaches it. 3: load tests do not run on production, at 03:00 or at any other hour: they degrade the service for real customers and can trip fraud or rate-limit controls, including the payment gateway’s. Use staging-perf; production gets only read-only synthetic checks as monitoring. 4: the average hides the slow tail; record p50, p95 and p99, and the error rate and the error type separately. 5: copying 50,000 real customers breaks the Personal Data Protection Law and the guide’s rule; generate synthetic data of the right shape (names, Saudi mobile numbers, many different accounts and seat choices, some invalid requests). 6: a 15-minute soak test sees nothing a load test does not; the sale lasts four hours, so the soak test runs at 300 req/s for at least four hours. 7: a scanner finds known patterns but not broken access control, and the night before the sale leaves no time to fix anything; it belongs in the pipeline now, next to the manual baseline checks.
Missing altogether: a spike test, although the push notification takes the platform from about 40 to 450 req/s within seconds; a stress test to find the margin; failure injection on the payment gateway and the SMS provider; a caching check; and a rule for keeping results. A one-page plan for the sale. Targets: T1–T3 with the endpoint mix at 450 req/s and at 300 req/s, for the whole sale from 20:00 to 24:00, written before testing. Workload model: the forecast mix, synthetic users and tokens, seat holds spread over the stadium with competition for the same seats, and a share of invalid requests. Runs on staging-perf: load at 450 req/s for 30 minutes; spike from 40 to 450 req/s in under a minute; stress from 450 req/s up to the breaking point; soak at 300 req/s for at least four hours. Failure injection: the payment gateway and the SMS provider each made slow, wrong (malformed body, 500, 503, 429 with Retry-After) and unavailable, with recovery observed. OWASP baseline: access control with a valid token of the wrong user and of the wrong role, injection, sign-in and sessions, headers and cookies, tokens, CORS, verbose errors, personal data in logs. Caching: Cache-Control and ETag on the heaviest responses (event pages, images, the seat layout), checked against how fresh each one must be. Records: the workload model, the environment description and the raw results of every run; SLO alerts set from T1–T3; the suite run again on every release that touches infrastructure, authentication or the sale path.
R1: pass. Seat map p95 620 ≤ 800 and p99 1,350 ≤ 1,500 (T1), pay p95 2,400 ≤ 3,000 (T2), errors 0.04 % < 0.1 % (T3): the platform keeps its promise at a steady peak. R2: fail on all three targets. Seat map p95 2,900 and p99 7,800 against 800 and 1,500, pay p95 5,100 against 3,000, errors 2.1 % against 0.1 %. T1–T3 apply from the first minute, and the notification turns the first minutes into a spike, so R2 is what the opening of the sale will look like: it blocks the launch. From minute 6 the values match R1, so the platform catches up, but too late for the buyers who come first. The draft’s criterion would have passed this run: the average of 520 ms is under 1 second while one request in twenty takes 2.9 seconds or more.
R3: pass in hour 1, fail in hour 4. Seat map p95 1,450 and p99 3,900, pay p95 4,800 and errors 0.9 % all break their targets although the load did not change, and the database connections in use climb from 60 to the pool maximum of 200. That is the pattern of connections that are taken and never given back, which only a test that lasts hours shows. It blocks the launch too, because the sale lasts four hours; the draft’s 15-minute soak and its average criterion (410 ms in hour 4) would both have missed it. R4: not judged against T1–T3, because the load is above the target; a stress test answers two other questions. Where is the limit? Errors stay below 0.1 % up to 800 req/s and jump at 850 req/s, so the limit lies between the two; record the last step that held, 800 req/s, about 1.8 times the forecast peak, as the margin. How does it fail? Badly: one step of 50 req/s takes the errors from below 0.1 % to 41 % although the load grew by only about 6 %, so it fails all at once instead of slowly and safely. The good half is that it recovers by itself within 2 minutes, without a restart. The p95 of 95 ms is not good performance either: it is low only because 41 % of the answers are fast errors, and a system that stays fast by returning errors has not passed. A generic HTML page is also the wrong answer for an API; expected: a clear 503 that the app can show, with a Retry-After header (RFC 9110 allows it on 503), and errors that grow with the excess load instead of jumping.
F1: acceptable. A malformed answer produces a specific, logged error, a clear message and an unpaid order. F2: fail. The payment service waits up to 60 s for the gateway, longer than its own caller, the API gateway, waits (20 s), so the customer sees an error while the payment goes through 11 seconds later, and may pay a second time. Expected: an outbound timeout well under 20 s; when the outcome is unknown, the order says that the payment is being confirmed and the app checks the order status instead of offering to pay again. F3: fail, and it blocks the launch. A non-idempotent request is retried blindly, three times at once with no backoff; with the real gateway, a charge that went through but whose answer was lost or late would be charged again. Expected: no automatic retry of POST /charges, or a bounded retry with backoff only with an idempotency key that the gateway supports. F4: fail. Ten retries within a second ignore Retry-After: 30; RFC 6585 defines 429 and lets the server say when to come back, and retrying at once adds load to a gateway that has just asked for less. The app then gets a generic 500. Expected: no new request before the Retry-After time, and a specific error the app can show, for example that payments are busy and the customer can try again in 30 seconds. F5: fail, because recovery is not automatic. Expected: when the gateway is back, payments resume without a restart, which is what a circuit breaker that tries the dependency again after a pause provides. Not tested yet: the same checks for the SMS provider; without the code, nobody can sign in.
S1: X-Content-Type-Options: nosniff and the cookie’s Secure attribute are correct. Missing (configuration): Strict-Transport-Security, Content-Security-Policy and frame protection (X-Frame-Options or the CSP directive frame-ancestors). The session cookie has no HttpOnly, so any script on the page can read it, including one injected through a cross-site scripting (XSS) defect, and no SameSite (sessions); set both explicitly instead of relying on browser defaults, which differ. S2 (authentication and sessions, token lifetime): exp - iat is 2,592,000 seconds, that is 30 days, from 13 October to 12 November 2026, 07:00 UTC. A leaked access token works for a month; expected: a short lifetime agreed with the team, in minutes, renewed with a refresh token. There is no aud claim, so no API can check that the token was issued for it. The token cannot show whether the server pins the algorithm: test that on staging with a token whose header says none and that has no signature; expected 401.
S3 (access control): broken object-level authorisation, API1:2023 in the OWASP API Security Top 10 and broken access control in the OWASP Top 10. A customer reads another customer’s personal data by changing an id. Severity Critical; it blocks the launch. Expected: 403 or 404 for an order that is not the caller’s. Repeat the check on every endpoint that takes an id (orders, tickets, seat holds) and with the wrong role, a customer token on staff endpoints; a scanner would not have found it. S4 (CORS): the API reflects any origin and allows credentials, so the origin policy does nothing. It is worse than a wildcard: browsers refuse * together with credentials, but they accept a reflected origin. Expected: an allow-list of the platform’s own origins, and no Access-Control-Allow-Origin for any other origin. S5 (configuration): verbose errors are on, and an exception with a file path tells anyone how the system is built. Expected: a generic error body with a correlation id, and the details only in the log. It is also a clue for R2 and R3: the database connection pool runs out under the spike and drains during the soak. Not covered yet: injection on every input that reaches the database; limits on SMS-code attempts and resends; logout that really invalidates the session and the token; the TLS configuration; personal data in logs.
The note to the release manager. No-go for the sale as tested. Must be fixed and re-tested before 22 October: R2 (the opening minutes break every target), R3 (connections run out by hour 4), F2 and F3 (customers can be charged twice), F5 (no recovery without a restart) and S3 (customers can read each other’s orders). Also to fix before the sale, each with a quick re-check: F4, S1, S2, S4, S5 and the overload response seen in R4. Still to run before the sale: failure injection on the SMS provider and the baseline checks not covered yet. After the fixes: confirmation testing of every failed item, including the full four-hour soak; R1 again as a regression test with the same workload, because the fixes touch the sale path and the comparison must be honest; and R4 again to record the new margin. Keep the workload model, the description of staging-perf and the raw results of R1–R4 with the note, set the alerts for the sale evening on T1–T3, and, if the platform is in scope of the NCA’s Essential Cybersecurity Controls (ECC), file the report as evidence for the related controls.
To check your work: R1 is the only run that passes and R4 the only one not judged against the targets; among F1–F5 only F1 is acceptable, and in S1–S5 only the nosniff header and the cookie’s Secure attribute are correct. If you passed R2 or R3 because the average stays under a second, reread the guide’s bullet on percentiles; if you read the 95 ms of R4 as good news, reread the bullet on systems that stay fast by returning errors. Another split between blockers and the other fixes is fine when each decision has its reason; a verdict without a number or a rule behind it is not.
Your progress on this topic
Not started
Mark the topic complete when you have studied it and done the exercise.
Sign in to track your progress
Mark topics complete, continue where you left off and unlock specialisation exams.
Part of the QA Roadmap
Before this topic
Next topics
Tools mentioned in this guide
Generate large parameter datasets (users, tokens, ids, payloads) for k6, JMeter, Gatling and Locust load tests.
Generate JMeter-ready test data (CSV Data Set Config files and User Defined Variables) from a field schema.
Generate CSV files for JMeter CSV Data Set Config with correct quoting, delimiters and encodings.
Generate concurrency test scripts (k6, JMeter JMX, Locust, Artillery, Node.js) with safe defaults for a target endpoint.
Run a small, safe benchmark against a public endpoint (bounded requests and concurrency) and get throughput and latency percentiles.
Measure an endpoint's response time over several samples: min, max, average, median and p95.
Compare response times and sizes of two endpoints (e.g. v1 vs v2, staging vs production) side by side.
Analyze response size: raw vs compressed bytes, headers size, JSON structure weight and largest fields.
Get a public endpoint that returns any HTTP status code, with optional delay and custom JSON body, to test client error handling.
Generate structured error responses (validation, auth, not found, rate limit, server error) in popular formats.
Grade HTTP security headers (CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy, COOP/CORP) from pasted headers or a public URL.
Parse Set-Cookie headers and check Secure, HttpOnly, SameSite, Domain, Path, expiry and size best practices.
Test Bearer, Basic, API-key and custom-header authentication against an endpoint and compare authorised vs unauthorised responses.
Decode JWT header and payload, inspect claims and check expiration — entirely in your browser.
Test CORS configuration: send preflight and simple requests from a given origin and inspect the Access-Control-* headers.
Analyze Cache-Control, Expires, ETag, Last-Modified, Vary and Age headers and explain how browsers and CDNs will cache the response.