পাঠ ৩৩ · ৫৭-এর মধ্যে · মডিউল ৮
Home / Courses / Software Testing & Quality Assurance / পারফরম্যান্স টেস্টিং

রেসপন্স টাইম, থ্রুপুট ও পার্সেন্টাইল

Response time, throughput & percentiles
১০ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • রেসপন্স টাইম ও থ্রুপুটের সুনির্দিষ্ট সংজ্ঞা
  • পার্সেন্টাইল কী এবং কীভাবে হাতে-কলমে গণনা করা হয় (সর্ট-অ্যান্ড-ইনডেক্স পদ্ধতি, numpy ছাড়াই)
  • কেন গড় একা পারফরম্যান্স বিচারের জন্য যথেষ্ট নয় — টেইল-লেটেন্সি সমস্যা ধরার জন্য p95/p99 কেন দরকার
  • একটি বাস্তব সংখ্যাভিত্তিক উদাহরণে গড় ও p99-এর মধ্যে বিশাল ফারাক প্রত্যক্ষ করা

১ · রেসপন্স টাইম বনাম থ্রুপুট

রেসপন্স টাইমResponse Timeএকটি একক রিকোয়েস্ট পাঠানো থেকে শুরু করে তার সম্পূর্ণ উত্তর ফিরে পাওয়া পর্যন্ত যে সময় লাগে। পরিমাপ করে একটি একক রিকোয়েস্টের অভিজ্ঞতা — মিলিসেকেন্ডে (ms)। অন্যদিকে থ্রুপুটThroughputএকটি সিস্টেম প্রতি একক সময়ে (সাধারণত প্রতি সেকেন্ডে) কতগুলো রিকোয়েস্ট সফলভাবে প্রসেস করতে পারে। পরিমাপ করে সিস্টেমের সামগ্রিক ক্ষমতা — সাধারণত requests/second (RPS) এককে। একটি সিস্টেমের রেসপন্স টাইম ভালো থাকলেও থ্রুপুট কম হতে পারে (একবারে একটি রিকোয়েস্ট দ্রুত সামলায়, কিন্তু একসাথে অনেকগুলো এলে সামলাতে পারে না) — তাই দুটো মেট্রিকই আলাদাভাবে ট্র্যাক করা জরুরি।

২ · কেন গড় যথেষ্ট নয়

ধরা যাক ১০০টি রিকোয়েস্টের মধ্যে ৯৮টি ১০০ মিলিসেকেন্ডে শেষ হয়, কিন্তু ২টি রিকোয়েস্ট (হয়তো একটি ধীর ডেটাবেজ কোয়েরি বা গার্বেজ-কালেকশন পজের কারণে) ৫ সেকেন্ড সময় নেয়। গড় তখনও তুলনামূলক কম দেখাতে পারে, কারণ সেই ২টি ভয়াবহ মান বাকি ৯৮টি ভালো মানের মধ্যে "গড়ে মিশে" যায় — অথচ ঐ ২ জন ব্যবহারকারীর অভিজ্ঞতা ছিল সম্পূর্ণ ভিন্ন, অগ্রহণযোগ্য রকম খারাপ। পার্সেন্টাইল এই লুকানো তথ্যকে প্রকাশ করে দেয়।

পার্সেন্টাইল কীভাবে গণনা করা হয়

একটি ডেটাসেটের p-তম পার্সেন্টাইল বের করতে প্রথমে ডেটা ছোট থেকে বড় ক্রমে সাজাতে হয়, তারপর একটি নির্দিষ্ট ইনডেক্সের মান নিতে হয়। $N$টি সর্ট করা মানের জন্য একটি সহজ, সাধারণভাবে ব্যবহৃত (nearest-rank) সূত্র:

$$\text{index} = \Big\lceil \frac{p}{100} \times N \Big\rceil - 1$$

যেমন $N = 50$ এবং $p = 99$ হলে, index $= \lceil 0.99 \times 50 \rceil - 1 = \lceil 49.5 \rceil - 1 = 49$ (০-ইনডেক্সড) — অর্থাৎ সর্ট করা তালিকার ৫০তম (সবচেয়ে বড়) মান। নিচের কোড সেলে ঠিক এই সূত্রই ব্যবহার করা হয়েছে।

৩ · বাস্তব সংখ্যায় গড় বনাম p99

নিচের কোড সেলে ৫০টি সিন্থেটিক রেসপন্স-টাইম তৈরি করা হয়েছে — ৪৯টি স্বাভাবিক মান (১০০ থেকে ১৩০ মিলিসেকেন্ডের মধ্যে, একটি ছড়ানো প্যাটার্নে) এবং একটি মাত্র চরম আউটলায়ার (৫০০০ মিলিসেকেন্ড — যেমন একটি GC পজ বা স্লো ডেটাবেজ কোয়েরির কারণে ঘটতে পারে)। গড়, মিডিয়ান (p50), p95 ও p99 — সবগুলোই sorted() ও একটি সাধারণ ইনডেক্স-হিসাব দিয়ে সত্যিকারভাবে গণনা করা হয়েছে, কোনো লাইব্রেরি (যেমন numpy) ছাড়াই।

Python
import math

# ৪৯টি স্বাভাবিক রেসপন্স টাইম (১০০-১৩০ ms রেঞ্জে একটি পুনরাবৃত্ত প্যাটার্নে)
normal_times = [100 + (i % 7) * 5 for i in range(49)]

# একটি মাত্র মারাত্মক ধীর রিকোয়েস্ট (যেমন একটি GC পজ বা স্লো DB কোয়েরি)
response_times = normal_times + [5000]

def percentile(data, p):
    data_sorted = sorted(data)
    n = len(data_sorted)
    idx = math.ceil((p / 100) * n) - 1
    idx = max(0, min(idx, n - 1))  # সীমার মধ্যে রাখা
    return data_sorted[idx]

average = sum(response_times) / len(response_times)
median = percentile(response_times, 50)
p95 = percentile(response_times, 95)
p99 = percentile(response_times, 99)

print(f"মোট রিকোয়েস্ট সংখ্যা: {len(response_times)}")
print(f"গড় (average):   {average:.1f} ms")
print(f"মিডিয়ান (p50):  {median} ms")
print(f"p95:            {p95} ms")
print(f"p99:            {p99} ms")

    
লক্ষ্য করুন গড় (~২১৩ মিলিসেকেন্ড) এবং এমনকি p95 (১৩০ মিলিসেকেন্ড) দুটোই মোটামুটি স্বাভাবিক দেখায় — একজন পর্যবেক্ষক এই দুটো সংখ্যা দেখে ভাবতেই পারেন সিস্টেম ঠিকঠাক কাজ করছে। কিন্তু p99 হঠাৎ ৫০০০ মিলিসেকেন্ডে (৫ সেকেন্ড!) লাফ দেয় — কারণ ৫০টি রিকোয়েস্টের মধ্যে মাত্র ১টি (মাত্র ২%) ছিল ভয়াবহ রকম ধীর, আর $N=50$-এর জন্য উপরের সূত্র অনুযায়ী p99 ঠিক সর্ট করা তালিকার ৫০তম (সর্বশেষ) মানের সাথে মিলে যায় — অর্থাৎ ঠিক সেই আউটলায়ারটাই ধরে ফেলে। p95 (৪৮তম মান) তখনও স্বাভাবিক ক্লাস্টারের মধ্যেই থাকে, তাই সেটি এই সমস্যা ধরতে পারে না।
মূল কথা · Key takeaway

গড় বলে দেয় "গড়ে" কেমন অভিজ্ঞতা হচ্ছে, কিন্তু কারও অভিজ্ঞতাই ঠিক "গড়" হয় না — কারও অভিজ্ঞতা ভালো, কারও খারাপ। পার্সেন্টাইল সরাসরি প্রশ্ন করে: "সবচেয়ে খারাপ অভিজ্ঞতা পাওয়া X% ব্যবহারকারীর অবস্থা কেমন?" — যা প্রোডাকশন সিস্টেমে বাস্তব ব্যবহারকারীর কষ্ট পরিমাপের জন্য অনেক বেশি কার্যকর। বেশিরভাগ পারফরম্যান্স SLA তাই গড়ের বদলে p95 বা p99-এর উপর ভিত্তি করে লেখা হয়।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ কোড সেলে p95 = ১৩০ ms দেখাচ্ছে যা মোটামুটি স্বাভাবিক, কিন্তু p99 = ৫০০০ ms — এই পার্থক্য এত বিশাল কেন?

কারণ ডেটাসেটে মোট ৫০টির মধ্যে ঠিক ১টি (২%) আউটলায়ার আছে। $N=50$-এর জন্য p95 সর্ট করা তালিকার ৪৮তম মানের সাথে মেলে, আর p99 মেলে একদম ৫০তম (সর্বশেষ) মানের সাথে। যেহেতু আউটলায়ারটি শুধু একেবারে সবচেয়ে উপরের ২% এর মধ্যে আছে, সেটি ৯৫তম পার্সেন্টাইল থেকে পুরোপুরি বাদ পড়ে যায়, কিন্তু ৯৯তম পার্সেন্টাইল ঠিক সেটাই ধরে ফেলে।

প্র ০২ যদি প্রোডাকশনে প্রতিদিন ১০ লক্ষ রিকোয়েস্ট আসে আর p99 = ৫০০০ ms হয়, বাস্তবে কতজন ব্যবহারকারী এই ধীর অভিজ্ঞতা পাচ্ছেন?

মোটামুটি ১% রিকোয়েস্ট, অর্থাৎ $1{,}000{,}000 \times 0.01 = 10{,}000$ — প্রতিদিন দশ হাজার রিকোয়েস্ট এই ৫ সেকেন্ড বা তার বেশি ধীর অভিজ্ঞতা পাচ্ছে। "মাত্র ১%" শুনতে ছোট মনে হলেও, বড় স্কেলে এটি একটি বিশাল, বাস্তব সংখ্যক ব্যবহারকারীকে প্রভাবিত করে — এটিই দেখায় কেন টেইল-লেটেন্সি উপেক্ষা করা যায় না।

প্র ০৩ কেন p99.9 বা p99.99-এর মতো আরও উঁচু পার্সেন্টাইলও কখনো কখনো ট্র্যাক করা হয়?

অত্যন্ত উচ্চ-ট্রাফিক সিস্টেমে (প্রতিদিন কোটি কোটি রিকোয়েস্ট), এমনকি p99-ও লাখ লাখ ব্যবহারকারীর জন্য একটি গুরুতর, বাস্তব সমস্যা লুকিয়ে ফেলতে পারে — যেহেতু p99-এর নিচে থাকা "মাত্র ১%"-ও পরম সংখ্যায় বিশাল হতে পারে। সমালোচনামূলক (critical) সিস্টেমগুলো তাই আরও গভীরে গিয়ে p99.9 বা p99.99 ট্র্যাক করে বিরল কিন্তু বাস্তব ডিগ্রেডেশন ধরতে।

অনুশীলন

  1. চিন্তা করুন: যদি ৫০টির বদলে ৫০০০টি রিকোয়েস্টের মধ্যে মাত্র ১টি (০.০২%) ধীর হতো, p99 কি সেই আউটলায়ারটি ধরতে পারবে?

    না। $N=5000$-এর জন্য p99 ইনডেক্স $= \lceil 0.99 \times 5000 \rceil - 1 = 4949$ (০-ইনডেক্সড), অর্থাৎ সর্ট করা তালিকার ৪৯৫০তম মান — যা সেরা ১% (৫০টি স্লট)-এর একদম শুরুর দিকের একটি মান। একটিমাত্র আউটলায়ার (৫০০০-এর মধ্যে ১টি) তালিকার একদম শেষে (৫০০০তম অবস্থানে) থাকবে, ৪৯৫০তম অবস্থানে নয় — তাই p99 সেটি ধরতে পারবে না। এমন বিরল আউটলায়ার ধরতে হলে p99.98 বা তার বেশি উঁচু পার্সেন্টাইল লাগবে।

  2. পরীক্ষা করুন: কোড সেলে response_times-এর শেষে [5000]-এর বদলে [5000, 4800, 5200] যোগ করে (মোট ৩টি আউটলায়ার, N হবে ৫২) Run চাপুন — p95-এর মান কীভাবে পরিবর্তন হয় লক্ষ্য করুন।

    এখন $N=52$, আর p95 ইনডেক্স $= \lceil 0.95 \times 52 \rceil - 1 = \lceil 49.4 \rceil - 1 = 49$ (০-ইনডেক্সড), অর্থাৎ সর্ট করা তালিকার ৫০তম মান। যেহেতু এখন ৩টি আউটলায়ার (৫২টির মধ্যে প্রায় ৫.৮%) তালিকার একদম উপরের দিকে বসে, ৫০তম অবস্থানটি এখন একটি আউটলায়ারই (৪৮০০ ms) হয়ে যায় — অর্থাৎ এবার p95-ও সমস্যাটি ধরে ফেলে, কারণ আউটলায়ারের অনুপাত এখন যথেষ্ট বড় হয়ে গেছে যে সেটি ৯৫তম পার্সেন্টাইলের মধ্যেও ঢুকে পড়েছে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • পরের পাঠ L34 পারফরম্যান্স বটলনেক শনাক্তকরণ — "পরিমাপ করুন, অনুমান করবেন না" নীতি ও একটি সত্যিকারের প্রোফাইলিং ডেমো।
  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ টেস্ট ডিজাইন টেকনিক, ইউনিট টেস্টিং, টেস্ট ডাবলস, ইন্টিগ্রেশন টেস্টিং, কভারেজ, অটোমেশন, পারফরম্যান্স ও সিকিউরিটি টেস্টিং, অ্যাডভান্সড টেকনিক ও CI/CD ইন্টিগ্রেশন — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks, Mobile App Development, Ethics in Computing & AI Safety ও Software Testing & Quality Assurance — সব এক জায়গায়।
আগের পাঠ
লোড, স্ট্রেস, সোক ও স্পাইক টেস্টিং