परसेंटाइल: p50, p95 और p99

Percentile बताता है कि measurements का एक set कैसे फैला हुआ है। 95th percentile, यानी p95, वह value है जिसके बराबर या उससे कम 95% measurements आते हैं: अगर किसी search API का p95 response time 600 ms है, तो हर 100 में से 95 searches ने 600 ms या उससे कम लिया और 5 ने ज़्यादा। p50 median है, यानी typical request; p95 और p99 धीमे सिरे को बताते हैं, जिसे testers tail कहते हैं।

Performance metrics वाले lesson ने response time, throughput और error rate से परिचय कराया। यह lesson response times को summarise करने के बारे में है: हज़ारों measurements कुछ numbers बन जाते हैं जिन्हें आप target से compare कर सकें, और average की जगह percentiles चुनना तय करता है कि धीमी requests आपकी report में दिखेंगी भी या नहीं।

यह क्यों ज़रूरी है

Users average को अनुभव नहीं करते; उन्हें अपनी धीमी requests याद रहती हैं। कुछ बहुत धीमी requests एक ठीक-ठाक दिखने वाले average के पीछे छिप सकती हैं, इसलिए "average 220 ms" ऐसे release को भी बता सकता है जिसमें दस में से एक request एक second से ज़्यादा लेती है।

Percentiles performance को testable बनाते हैं। "API तेज़ होना चाहिए" कभी fail नहीं हो सकता; "200 requests per second पर p95 500 ms से कम" fail हो सकता है। इनसे आप दो builds की ईमानदार तुलना कर पाते हैं और regression को ऐसी भाषा में बता पाते हैं जिस पर developer काम कर सके।

Percentile क्या है और इसे कैसे निकालें

किसी एक operation के लिए मापे गए सभी response times को सबसे तेज़ से सबसे धीमे तक sort करें। pth percentile वह value है जिसके बराबर या उससे कम उनका p प्रतिशत आता है। हाथ से निकालने के लिए nearest-rank method इस्तेमाल करें: rank = ceil(p / 100 × n), यानी count का p प्रतिशत ऊपर की ओर round करके, और उस rank की value पढ़ें।

20 measurements के साथ p50 rank 10 की value है, p95 rank 19 की और p99 rank 20 की, जो बस सबसे धीमी request है। Percentile उतना ही सटीक होता है जितना उसके पीछे का data: p99 सबसे धीमे 1% पर टिका है, यानी 200 में से सिर्फ़ 2 requests, इसलिए इसे सैकड़ों या हज़ारों samples चाहिए।

  • कुछ tools nearest rank इस्तेमाल करते हैं, कुछ पड़ोसी values के बीच interpolate करते हैं, इसलिए कम samples होने पर दो tools एक ही run के लिए अलग numbers दे सकते हैं। हज़ारों samples के साथ यह फ़र्क छोटा रहता है।
  • Labels भी अलग हैं: k6 p(95) लिखता है, और JMeter की Aggregate Report में 95% Line column होता है। देखें कि summary कौन-से percentiles दिखाता है; k6 में आप इन्हें summaryTrendStats option से चुनते हैं।
  • Percentiles हर operation के लिए अलग निकालें: 5 ms वाला health check और 400 ms वाला search एक list में हों तो ऐसा p95 बनता है जो किसी को नहीं दर्शाता।

आज़माएँ: रिस्पॉन्स टाइम एनालाइज़र

p50, p95 और p99 अलग-अलग क्या बताते हैं

हर percentile एक अलग सवाल का जवाब देता है, इसलिए reports कई percentiles साथ-साथ दिखाती हैं। और "सिर्फ़ 1%" जितना लगता है उससे ज़्यादा है: 50 requests per second पर इसका मतलब हर minute 30 धीमी requests है, और अगर कोई page 10 independent calls करता है जिनमें हर एक के अपने p99 से धीमा होने की संभावना 1% है, तो कम से कम एक के धीमा होने की संभावना 1 - 0.99^10, यानी लगभग 10% है।

  • p50, यानी median: आधी requests इससे तेज़ थीं, आधी धीमी। यह typical अनुभव बताता है और तब खिसकता है जब कोई change सब कुछ धीमा कर दे, जैसे किसी query का index खो जाना।
  • p95: हर 20 में से एक request इससे धीमी थी। Test targets और SLOs के लिए यह एक आम चुनाव है, क्योंकि यह लगभग हर request को cover करता है और p99 की तुलना में किसी एक outlier से कम प्रभावित होता है।
  • p99: हर 100 में से एक request इससे धीमी थी। यही tail है, जहाँ garbage collection pauses, lock contention, cold caches, retries और धीमी dependencies दिखती हैं। इसके लिए बहुत samples चाहिए, और load बढ़ने पर यह अक्सर median से पहले ऊपर चढ़ता है।
  • Maximum एक अकेली request है: timeouts के लिए उसे देखें, पर target बनने के लिए वह बहुत अस्थिर है। ज़्यादा traffic वाली services p99.9 भी track करती हैं।

Average क्यों गुमराह करता है

Response times skewed होते हैं: ज़्यादातर requests तेज़ सिरे के पास इकट्ठा होती हैं, और धीमी requests की एक लंबी tail बड़ी values की ओर खिंचती है। Mean हर value जोड़कर count से भाग देता है, इसलिए कुछ धीमी requests उसे ऊपर खींच लेती हैं, फिर भी वह यह नहीं बताता कि कितने users ने इंतज़ार किया।

दो services हर एक 100 requests handle करती हैं, दोनों का average 200 ms है। Service A 180, 190, 200, 210 और 220 ms में 20-20 requests का जवाब देती है। Service B 88 requests का जवाब 100 ms में, 7 का 600 ms में, 4 का 1,250 ms में और एक का 2,000 ms में देती है। A का p50 200 ms, p95 220 ms और p99 220 ms है; B का p50 100 ms, p95 600 ms और p99 1,250 ms है। B ज़्यादातर users के लिए तेज़ है और बदक़िस्मत users के लिए बहुत धीमी, और 500 ms का p95 target सिर्फ़ A पूरा करती है।

Services A और B दोनों का 100 requests पर average 200 ms है, लेकिन B का p95 600 ms और p99 1250 ms है, इसलिए 500 ms का p95 target सिर्फ़ A पूरा करती है।

Service A: 100 requests, सभी 180 से 220 ms के बीच

अक्ष 0 ms से 1250 ms तक
  • ≤ 500 msp95 target पूरा
  • > 500 msp95 target चूका
  1. 1200 ms p50 = averageआधी requests ने 200 ms या कम लिया, और mean भी 200 ms है: tail न हो तो दोनों मेल खाते हैं।
  2. 2220 ms p95 = p99500 ms target के अंदर: सबसे धीमी requests ने भी सिर्फ़ 220 ms लिया।पास

Service B: 88 requests 100 ms में, 12 requests 600 से 2000 ms के बीच

अक्ष 0 ms से 1250 ms तक
  • ≤ 500 msp95 target पूरा
  • > 500 msp95 target चूका
  1. 1100 ms p50 (median)Typical request A से दोगुनी तेज़ है।
  2. 2200 ms Averageबिल्कुल A जैसा: mean, 200 ms, दोनों services में फ़र्क नहीं कर पाता।
  3. 3600 ms p95500 ms target से ऊपर: 100 में से 12 requests ने 600 ms या ज़्यादा लिया।फ़ेल
  4. 41250 ms p99Tail: 5 requests ने 1250 ms या ज़्यादा लिया।

Percentiles nearest-rank method से निकाले गए हैं। B की सबसे धीमी request, 2000 ms, axis के अंत से आगे है।

  • Average ऐसी request बता सकता है जो कभी हुई ही नहीं: अगर 80% requests को cache में data 20 ms में मिल जाए और 20% को न मिले और वे 800 ms लें, तो mean 176 ms है, ऐसा समय जो किसी request ने नहीं लिया।
  • Percentiles का average नहीं निकाला जा सकता। दो servers का, या one-minute windows से बने दिन का p95 उनकी p95 values का mean नहीं है; इसे raw measurements से या merged histogram (हर latency range में requests की गिनती) से निकालें।
  • 5 ms में लौटा error average और percentiles को नीचे खींच सकता है और fail होते system को तेज़ दिखा सकता है। Successful requests की latency और error rate साथ-साथ report करें।

आज़माएँ: API परफ़ॉर्मेंस कंपेरेटर

Worked example: search की 20 requests

एक release के बाद tester staging पर search API को 20 sequential requests भेजता है, बिना किसी और load के, ताकि team का target जाँच सके: p95 500 ms या उससे कम। नीचे के block में raw times, sorted list और calculation हैं।

  • Mean: 4,400 / 20 = 220 ms। यह आरामदेह दिखता है, फिर भी 20 में से 17 requests average से तेज़ थीं और दो उससे बहुत धीमी।
  • p50: rank 10 → 125 ms। Typical search तेज़ है।
  • p95: rank 19 → 600 ms। Target पूरा नहीं हुआ, और इसे दूसरी सबसे धीमी request तय करती है।
  • p99: rank 20 → 1,400 ms, जो बस maximum है। बीस samples p99 को सहारा नहीं दे सकते, इसलिए उसे report न करें।
  • Report में sample size और load के साथ p50, p95 और maximum होते हैं, यह लिखा होता है कि target पूरा नहीं हुआ, धीमी requests (चौथी और दसवीं) जाँच के लिए नामित होती हैं, और किसी भी फ़ैसले से पहले तय load पर कई सौ requests के साथ दोबारा मापने की माँग होती है।
Search API, staging, 20 sequential requests, response time in ms
Target: p95 <= 500 ms

As measured:  128 113  96 600 122 136 104 150 117 1400
              110 131 194 101 125 240 142 108 163  120

Sorted:
  rank    1    2    3    4    5    6    7    8    9   10
  ms     96  101  104  108  110  113  117  120  122  125
  rank   11   12   13   14   15   16   17   18   19   20
  ms    128  131  136  142  150  163  194  240  600 1400

Mean  = 4400 / 20                   = 220 ms
p50   = rank ceil(0.50 x 20) = 10  -> 125 ms
p95   = rank ceil(0.95 x 20) = 19  -> 600 ms   (target 500 ms: not met)
p99   = rank ceil(0.99 x 20) = 20  -> 1400 ms  (= the maximum)

आज़माएँ: HTTP रिक्वेस्ट बेंचमार्क

Percentiles से latency targets और SLOs लिखना

Google की SRE book में service level indicator (SLI) service के किसी पहलू का ध्यान से परिभाषित measurement है, जैसे request latency, और service level objective (SLO) उसकी target value या range है। Service level agreement (SLA) एक contract है जिसमें objective चूकने के नतीजे तय होते हैं। Latency objectives percentiles में लिखे जाते हैं क्योंकि उन्हें लगभग सभी users पर खरा उतरना है, किसी average user पर नहीं।

पूरा target पाँच चीज़ें बताता है: कौन-सी requests (operation; सिर्फ़ successful या सभी), percentile, threshold, window या test की अवधि, और conditions, जैसे load। "95% requests 500 ms के अंदर पूरी होती हैं" और p95 ≤ 500 ms एक ही शर्त है। k6 में criterion thresholds बन जाता है: कोई threshold चूके तो run fail होता है और non-zero exit code के साथ ख़त्म होता है, ताकि CI pipeline वहीं रुक सके। इस section के अंत की script नीचे वाले load test criterion को k6 में बदलती है: उसका scenario हर second 200 requests शुरू करता है, response time चाहे जो हो, और उन्हें भेजने के लिए 100 से 400 virtual users का pool इस्तेमाल करता है (preAllocatedVUs, maxVUs); अगला lesson, कॉन्करेंट यूज़र्स और वर्कलोड मॉडल, इस open model को और pool का size तय करना समझाता है। {expected_response:true} filter latency thresholds को सिर्फ़ successful responses तक सीमित रखता है।

  • Production SLO: "successful GET /products/{id} requests में से 99% 300 ms के अंदर पूरी हों, rolling 28 दिनों में मापा गया।"
  • Checkout के लिए दो स्तर: "POST /checkout के लिए p95 ≤ 800 ms और p99 ≤ 2 s", ताकि typical धीमी request और tail दोनों पर सीमा रहे।
  • SLO से निकला load test criterion: "GET /search के लिए 200 requests per second पर 30 minutes तक: successful requests के लिए p95 ≤ 500 ms और p99 ≤ 1200 ms, और error rate 0.5% से कम।" इन examples के numbers सिर्फ़ उदाहरण हैं; असली numbers users की ज़रूरतों और product team से आते हैं, किसी standard से नहीं।
import http from 'k6/http';

export const options = {
  scenarios: {
    search: {
      executor: 'constant-arrival-rate', // 200 iterations a second, one request each
      rate: 200,
      timeUnit: '1s',
      duration: '30m',
      preAllocatedVUs: 100,
      maxVUs: 400,
    },
  },
  thresholds: {
    'http_req_duration{expected_response:true}': ['p(95)<=500', 'p(99)<=1200'],
    http_req_failed: ['rate<0.005'],
  },
};

export default function () {
  http.get('https://staging.example.com/search?q=lamp');
}

आम गलतियाँ

  • सिर्फ़ average response time report करना, या उसे percentiles से ऊपर headline में रखना।
  • 100 से कम samples से p99 बताना, जहाँ nearest-rank p99 बस सबसे धीमी request होता है।
  • Raw data से निकालने की जगह servers, endpoints या time windows के percentiles का average निकालना।
  • अलग-अलग operations को, या successful और failed requests को, response times के एक ही set में मिलाना।
  • Conditions के बिना target लिखना: एक user के साथ मापा गया p95 peak load पर p95 के बारे में कुछ नहीं बताता।
  • दो tools या runs के results की तुलना यह जाँचे बिना करना कि दोनों ने एक ही percentile method, requests और load इस्तेमाल किया।

QA का नज़रिया

Requirements review के दौरान latency targets percentiles में माँगें, और उन्हें product owner और service चलाने वाले developers या SREs के साथ पूरा करें: कौन-से operations, कौन-सा percentile, कहाँ और किस window में मापा जाएगा, किस load पर, और क्या failed requests गिनी जाएँगी। "Search तेज़ होना चाहिए" इस बातचीत के बाद ही testable बनता है।

हर report में हर operation के लिए p50, p95 और, जब sample काफ़ी बड़ा हो, p99 दिखाएँ, साथ में sample size, error rate, load, tool और percentile method। जब कोई percentile target चूके, तो developers को धीमी requests ख़ुद दें, timestamps और parameters के साथ, और हर build की पिछले build से उन्हीं conditions में तुलना करें, ताकि tail में regression users के महसूस करने से पहले पकड़ा जाए।

अभ्यास

Release को उसके percentile target पर जाँचें

आपका काम

एक colleague ने release 2.8 के बाद staging पर order-history API टेस्ट की और लिखा: "Average 190 ms, 400 ms target से काफ़ी नीचे। Pass।" नीचे के material से, कागज़-कलम या spreadsheet की मदद से, असली verdict निकालें।

उसके बाद, किसी ऐसे endpoint पर जो आपका है या जिसे टेस्ट करने की आपको अनुमति है, Response Time Analyzer के दिखाए average, median और p95 की तुलना करें।

सामग्री
Order history API, staging, release 2.8, 21 requests sent, no concurrent load
Target: p95 <= 400 ms and p99 <= 1000 ms, successful requests only

Successful (ms):  118  95 136  87 470 110 121 104 158  92
                  131 960 112  99 144 127 390 107 124 115
Failed:           1 request, HTTP 500 after 9 ms
चरण
  1. 20 successful response times sort करें और mean निकालें।
  2. Nearest-rank method से p50, p95 और p99 निकालें।
  3. हर result की target से तुलना करें, pass या fail तय करें, और लिखें कि 20 samples क्या नहीं बता सकते।
  4. तय करें कि failed request कैसे गिनी जाए, फिर result दो वाक्यों में लिखें।
मॉडल उत्तर दिखाएँ
मॉडल उत्तर

Sorted: 87, 92, 95, 99, 104, 107, 110, 112, 115, 118, 121, 124, 127, 131, 136, 144, 158, 390, 470, 960। जोड़ 3,800 ms है, इसलिए mean 190 ms है: colleague का हिसाब सही है।

p50 = rank 10 = 118 ms; p95 = rank 19 = 470 ms; p99 = rank 20 = 960 ms, जो maximum है।

Verdict: fail। p95 470 ms है जबकि target 400 ms है, और 20 में से 2 requests ने 400 ms से ज़्यादा लिया। p99 की शर्त कागज़ पर पूरी है, लेकिन 100 से कम samples पर p99 बस सबसे धीमी request है और कुछ साबित नहीं करता।

HTTP 500 latency figures से बाहर रहता है ("successful requests only"), पर उसे report करना ज़रूरी है: 21 में से 1 request fail हुई, यानी लगभग 4.8%। अगर उसे गिना जाता, तो उसके 9 ms average को लगभग 181 ms तक नीचे खींचकर fail होते release को बेहतर दिखाते।

Result: "Release 2.8 अपना latency target चूकता है: p95 470 ms जबकि target 400 ms है (p50 118 ms, maximum 960 ms; बिना concurrent load के 20 successful sequential requests), और 21 में से 1 request HTTP 500 के साथ fail हुई। तय load पर कई सौ requests के साथ दोबारा मापें और requests 5 और 12 व error की जाँच करें।"

अक्सर पूछे जाने वाले सवाल

क्या p50 और average एक ही हैं?

नहीं। p50 median है: measurements sort करने के बाद बीच की value। Average (mean) जोड़ को count से भाग देकर मिलता है। दोनों सिर्फ़ symmetric distribution में बराबर होते हैं; response times में आम तौर पर एक धीमी tail होती है जो average को median से ऊपर खींच लेती है।

मेरा target p95 हो या p99?

आम तौर पर दोनों, अलग-अलग कारणों से। p95 उस पर सीमा लगाता है जो लगभग हर request अनुभव करती है, और स्थिर होने के लिए p99 से कम samples चाहता है; p99 tail पर सीमा लगाता है, जो तब मायने रखती है जब users बहुत requests करते हैं या service दूसरी services के पीछे होती है। Maximum एक अकेली request है और target बनने के लिए बहुत अस्थिर, पर timeouts के लिए उसे हमेशा देखें।

भरोसेमंद p99 के लिए कितनी requests चाहिए?

100 से कहीं ज़्यादा। Nearest rank में 100 से कम measurements का p99 बस सबसे धीमी request है, और 1,000 measurements पर भी यह सबसे धीमी 10 पर टिका होता है। p99 को स्थिर number मानने से पहले हर operation के हज़ारों samples जुटाएँ, या लंबी window में मापें।

SLO और performance test target में क्या फ़र्क है?

SLO चल रही service का objective है, जो 28 दिन जैसी window में लगातार मापा जाता है। Performance test target तय conditions में एक test run पर लागू होता है। Testers आम तौर पर test target SLO से निकालते हैं, ताकि test pass करने वाला release production में SLO बनाए रखे, इसकी संभावना ज़्यादा हो।

संदर्भ

  • Site Reliability Engineering: How Google Runs Production SystemsGoogle / O'Reilly Media · 2016सर्विस लेवल ऑब्जेक्टिव, एरर बजट, "चार गोल्डन सिग्नल" की निगरानी और ओवरलोड संभालना — लचीलेपन का परिचालन पक्ष।
  • Monitoring Distributed Systems — Site Reliability Engineering (Rob Ewaschuk)Google / O'Reilly Media · 2016monitoring पर Google की SRE गाइडेंस: black-box बनाम white-box monitoring और चार golden signals — latency, traffic, errors और saturation।
  • Grafana k6 documentationGrafana LabsGrafana k6 का आधिकारिक दस्तावेज़ — एक open-source और extensible load व performance testing टूल।
  • Apache JMeter User's ManualApache Software FoundationJMeter से लोड टेस्ट कैसे बनाएँ, पैरामीटराइज़ करें और चलाएँ, और उसके लिसनर व रिपोर्ट कैसे पढ़ें।

Mutqan tools से अभ्यास करें

किसी सार्वजनिक endpoint पर छोटा, सुरक्षित बेंचमार्क चलाएँ (सीमित रिक्वेस्ट व concurrency) और throughput तथा latency percentile पाएँ।

परफ़ॉर्मेंस

दो endpoint के रिस्पॉन्स टाइम और साइज़ की आमने-सामने तुलना करें (जैसे v1 बनाम v2, staging बनाम production)।

परफ़ॉर्मेंस

और गहराई से

इस topic में आपकी प्रगति

QA रोडमैप का हिस्सा