<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Oleh Koren</title>
    <description>The latest articles on Forem by Oleh Koren (@oleh_koren).</description>
    <link>https://forem.com/oleh_koren</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3757399%2F53ebb113-e65e-442e-ae64-84431a479e62.jpg</url>
      <title>Forem: Oleh Koren</title>
      <link>https://forem.com/oleh_koren</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/oleh_koren"/>
    <language>en</language>
    <item>
      <title>Hidden Problem That Makes Most Load Tests Unrealistic</title>
      <dc:creator>Oleh Koren</dc:creator>
      <pubDate>Wed, 18 Mar 2026 09:45:02 +0000</pubDate>
      <link>https://forem.com/oleh_koren/hidden-problem-that-makes-most-load-tests-unrealistic-2o33</link>
      <guid>https://forem.com/oleh_koren/hidden-problem-that-makes-most-load-tests-unrealistic-2o33</guid>
      <description>&lt;p&gt;You execute a load test using 100 virtual users.&lt;/p&gt;

&lt;p&gt;The test generates 1000 requests per second.&lt;/p&gt;

&lt;p&gt;In production, the same system only receives around 80 requests per second.&lt;/p&gt;

&lt;p&gt;So what happened?&lt;/p&gt;

&lt;p&gt;The answer is simple — &lt;strong&gt;think time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you don't use it, your load test might act like &lt;strong&gt;robots instead of real users&lt;/strong&gt;, and the results could be totally wrong.&lt;/p&gt;

&lt;p&gt;Let’s break down why think time is important and how to use it correctly during performance testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Think Time?
&lt;/h2&gt;

&lt;p&gt;Think time is the amount of time a real user takes between performing actions in an application.&lt;/p&gt;

&lt;p&gt;In real life, users don't immediately perform the next request after receiving a response. &lt;/p&gt;

&lt;p&gt;They usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;read the page&lt;/li&gt;
&lt;li&gt;scroll through content&lt;/li&gt;
&lt;li&gt;think about what to click&lt;/li&gt;
&lt;li&gt;enter data&lt;/li&gt;
&lt;li&gt;compare options&lt;/li&gt;
&lt;li&gt;navigate through menus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these actions take time.&lt;/p&gt;

&lt;p&gt;Performance tests that ignore this behavior produce &lt;strong&gt;unrealistic load patterns.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Without Think Time
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;User opens a page&lt;br&gt;
User clicks a button&lt;br&gt;
User searches for a product&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your script runs without pauses, the virtual user will send requests &lt;strong&gt;as quickly as it can.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Without think time:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;100 virtual users → ~1000 requests per second (RPS)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But real users behave differently.&lt;/p&gt;

&lt;p&gt;With realistic pauses:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;100 real users → ~80 requests per second&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s more than a 12× difference.&lt;/p&gt;

&lt;p&gt;You can think about it using a simple model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;RPS ≈ Users / (Response Time + Think Time)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When think time increases, the number of requests per second naturally drops — even with the same number of users.&lt;/p&gt;

&lt;p&gt;The same number of users produces completely different load depending on think time:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Users&lt;/th&gt;
&lt;th&gt;RPS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No think time&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;~1000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;With think time&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;~80&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is why tests that don't include time for thinking often show more system traffic than there really is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ignoring think time can lead to incorrect conclusions.&lt;/p&gt;

&lt;p&gt;You might think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;system cannot handle the load&lt;/li&gt;
&lt;li&gt;infrastructure needs scaling&lt;/li&gt;
&lt;li&gt;performance is worse than expected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In reality, the test was simply &lt;strong&gt;unrealistic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Virtual users perform actions continuously without any human behavior.&lt;/p&gt;

&lt;p&gt;Real users don’t behave like that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Does Think Time Come From?
&lt;/h2&gt;

&lt;p&gt;Good performance tests aim to mimic how real people behave when using an application.&lt;/p&gt;

&lt;p&gt;Think time values can be gathered from various sources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. User Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User analytics tools offer important information about how people use your application.&lt;/p&gt;

&lt;p&gt;Examples of such tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Analytics&lt;/li&gt;
&lt;li&gt;Mixpanel&lt;/li&gt;
&lt;li&gt;Amplitude&lt;/li&gt;
&lt;li&gt;Pendo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools allow you to look at several metrics, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Average time spent on a page&lt;/li&gt;
&lt;li&gt;Session duration&lt;/li&gt;
&lt;li&gt;Click intervals&lt;/li&gt;
&lt;li&gt;Page navigation patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These metrics can help estimate how long a user usually stays on a page before taking another action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Real User Monitoring (RUM)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real User Monitoring tools track how users interact with the application in production.&lt;/p&gt;

&lt;p&gt;They can provide data such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time between user interactions&lt;/li&gt;
&lt;li&gt;Navigation timing&lt;/li&gt;
&lt;li&gt;User session behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This type of data is often one of the most reliable source for defining think times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Business Knowledge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In some cases, the most effective source of think time information comes from understanding the product and its typical use scenarios.&lt;/p&gt;

&lt;p&gt;For instance:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Login page → 2–5 seconds&lt;br&gt;
Search page → 5–10 seconds&lt;br&gt;
Checkout → 15–30 seconds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Users require time to read, compare, and make decisions.&lt;/p&gt;

&lt;p&gt;Different user journeys naturally involve different think times.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Think Time Is Implemented in Performance Tests
&lt;/h2&gt;

&lt;p&gt;Performance testing tools often offer various methods to simulate think time, which represents the time users take between actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JMeter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Common timers available in JMeter include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constant Timer&lt;/li&gt;
&lt;li&gt;Uniform Random Timer&lt;/li&gt;
&lt;li&gt;Gaussian Random Timer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Random timers are generally preferred because real users do not wait the exact same amount of time between actions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An example of a random pause would be a delay between 3 and 8 seconds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;k6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In k6, think time is typically simulated using the sleep() function.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;randomBetween&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Gatling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Gatling includes built-in pause functions to simulate think time.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pause(3,8)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a random delay between actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Think Time Mistakes
&lt;/h2&gt;

&lt;p&gt;Even experienced engineers can sometimes use think time incorrectly.&lt;/p&gt;

&lt;p&gt;Here are some common problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No think time at all&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The script runs without any pauses.&lt;/p&gt;

&lt;p&gt;This creates traffic patterns that don't match real-world behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixed pauses&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real users don't wait the same amount of time each time.&lt;/p&gt;

&lt;p&gt;Random delays are typically more accurate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unrealistic pause values&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pauses that are too short or too long can affect the test results in an unrealistic way.&lt;/p&gt;

&lt;p&gt;Think time should be based on how real users actually behave.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Key Idea
&lt;/h2&gt;

&lt;p&gt;Virtual users execute scripts.&lt;/p&gt;

&lt;p&gt;Real users think.&lt;/p&gt;

&lt;p&gt;If your performance test does not simulate this thinking time, the results may not represent real-world traffic.&lt;/p&gt;

&lt;p&gt;A realistic load test is not just about the number of users.&lt;/p&gt;

&lt;p&gt;It is about how those users behave.&lt;/p&gt;

&lt;p&gt;If you're interested in learning more about realistic load modeling, think time, and performance testing in practice — I cover these topics in detail in my course.&lt;/p&gt;

&lt;p&gt;You can check it out here: &lt;br&gt;
👉 &lt;a href="https://www.udemy.com/course/performance-testing-fundamentals-from-basics-to-hands-on/?couponCode=DEV-COMMUNITY-COUPON" rel="noopener noreferrer"&gt;Performance Testing Fundamentals: From Basics to Hands-On (Udemy)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>softwaretesting</category>
      <category>loadtesting</category>
    </item>
    <item>
      <title>What Does a Performance QA Engineer Actually Do?</title>
      <dc:creator>Oleh Koren</dc:creator>
      <pubDate>Mon, 09 Mar 2026 11:37:00 +0000</pubDate>
      <link>https://forem.com/oleh_koren/what-does-a-performance-qa-engineer-actually-do-311</link>
      <guid>https://forem.com/oleh_koren/what-does-a-performance-qa-engineer-actually-do-311</guid>
      <description>&lt;p&gt;When I tell people that I work as a Performance QA Engineer, the reaction is often the same:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Do you always have tasks in that role?"&lt;/li&gt;
&lt;li&gt;"Isn’t it mostly functional testing and only partly performance?"&lt;/li&gt;
&lt;li&gt;"Or is it closer to DevOps and infrastructure work?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The confusion is understandable.&lt;/p&gt;

&lt;p&gt;Performance QA engineers are relatively rare. In many companies, there’s no dedicated role, and developers only run quick load tests before big releases.&lt;/p&gt;

&lt;p&gt;But in teams where performance really matters, there are specialists responsible for making sure the system can actually handle real-world traffic.&lt;/p&gt;

&lt;p&gt;As someone working in this area, I can say one thing clearly: &lt;strong&gt;there is always work to do.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Performance QA Engineers Are Rare
&lt;/h2&gt;

&lt;p&gt;When I started learning QA automation during my company’s training program, I hardly heard anyone mention performance testing.&lt;/p&gt;

&lt;p&gt;Most discussions were about manual testing, UI automation, frameworks, and CI/CD.&lt;/p&gt;

&lt;p&gt;Performance testing felt occasional at first, but over time I realized it’s not just QA — it’s a mix of automation, backend, frontend, and infrastructure skills that lets you see the system as a whole.&lt;/p&gt;

&lt;p&gt;To work effectively, you need to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs and system architecture&lt;/li&gt;
&lt;li&gt;Backend and frontend behavior&lt;/li&gt;
&lt;li&gt;Infrastructure and monitoring&lt;/li&gt;
&lt;li&gt;Data analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This combination explains why there are fewer specialists in this field.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Performance QA Engineers Actually Do
&lt;/h2&gt;

&lt;p&gt;Many think performance testing is just running a load test and generating a report. &lt;/p&gt;

&lt;p&gt;In reality, it’s a continuous process that touches multiple areas. &lt;br&gt;
Typical tasks include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementing and maintaining test scenarios — designing realistic user flows and scripts.&lt;/li&gt;
&lt;li&gt;Running different types of performance tests — load, stress, spike, endurance.&lt;/li&gt;
&lt;li&gt;Investigating test results — identifying bottlenecks, such as slow database queries or caching issues.&lt;/li&gt;
&lt;li&gt;Analyzing metrics and presenting insights — interpreting response times, throughput, and errors; presenting findings to developers, DevOps, and stakeholders.&lt;/li&gt;
&lt;li&gt;Collaborating across teams — working with backend, frontend, QA, and infrastructure teams to improve system performance.&lt;/li&gt;
&lt;li&gt;Monitoring test environments — ensuring environments can handle realistic traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance testing isn’t a solo task — it’s a mix of technical investigation, communication, and collaboration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backend and Frontend Performance Testing
&lt;/h2&gt;

&lt;p&gt;When we begin performance testing, the journey almost always starts behind the scenes — in the &lt;strong&gt;backend&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Much of our work focuses on API testing, because APIs handle the majority of system load.&lt;/p&gt;

&lt;p&gt;To understand how the backend behaves under load, we use JMeter, Gatling, and k6.&lt;/p&gt;

&lt;p&gt;But backend testing is only half the story.&lt;/p&gt;

&lt;p&gt;User experience also depends on &lt;strong&gt;frontend&lt;/strong&gt; performance — page load, rendering, and responsiveness matter. &lt;/p&gt;

&lt;p&gt;Tools like PageSpeed Insights and Sitespeed.io help us measure this, because even if the server responds immediately, users might still be waiting on a loading screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Infrastructure Matters a Lot
&lt;/h2&gt;

&lt;p&gt;One of the biggest challenges in performance testing is &lt;strong&gt;environment setup.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ideally, performance tests should run in an environment that is as close to production as possible.&lt;/p&gt;

&lt;p&gt;In practice, this often means creating a &lt;strong&gt;dedicated performance testing environment&lt;/strong&gt; that mirrors the real system architecture.&lt;/p&gt;

&lt;p&gt;In projects where this is done properly, we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scale services up and down during testing&lt;/li&gt;
&lt;li&gt;simulate realistic traffic&lt;/li&gt;
&lt;li&gt;avoid impacting production systems&lt;/li&gt;
&lt;li&gt;turn environments off outside working hours to save infrastructure costs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without a realistic environment, performance testing results can be misleading.&lt;/p&gt;

&lt;h2&gt;
  
  
  CI/CD and Automation
&lt;/h2&gt;

&lt;p&gt;Modern performance testing is rarely manual. We integrate tests into CI/CD pipelines (&lt;strong&gt;Jenkins, TeamCity, GitHub Actions, GitLab CI&lt;/strong&gt;) to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run tests regularly&lt;/li&gt;
&lt;li&gt;Detect regressions early&lt;/li&gt;
&lt;li&gt;Ensure performance testing is continuous&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Collecting and Visualizing Results
&lt;/h2&gt;

&lt;p&gt;Running a test is just the beginning.&lt;/p&gt;

&lt;p&gt;The real value comes from &lt;strong&gt;analyzing results.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In many projects, we store performance metrics in &lt;strong&gt;time-series databases&lt;/strong&gt; such as &lt;strong&gt;InfluxDB or Prometheus&lt;/strong&gt;, and then visualize them using &lt;strong&gt;Grafana dashboards.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This setup allows us to track things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;response times&lt;/li&gt;
&lt;li&gt;throughput&lt;/li&gt;
&lt;li&gt;error rates&lt;/li&gt;
&lt;li&gt;hardware resource usage — both on the load generator and the application servers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having all this data in one place makes it much easier to understand how the system behaves under load and identify performance trends over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Communication Is Key
&lt;/h2&gt;

&lt;p&gt;One thing that many people underestimate is &lt;strong&gt;how much communication is involved.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Performance engineers often act as a bridge between different teams.&lt;/p&gt;

&lt;p&gt;We regularly work with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;developers&lt;/li&gt;
&lt;li&gt;DevOps engineers&lt;/li&gt;
&lt;li&gt;QA teams&lt;/li&gt;
&lt;li&gt;architects&lt;/li&gt;
&lt;li&gt;product/delivery managers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes the hardest part is not running the test — it’s &lt;strong&gt;explaining the results.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, telling the team that the system handles 5,000 users instead of the expected 10,000 can have serious business implications. So it’s important to explain not only the numbers but also &lt;strong&gt;why the system behaves that way and what can be improved.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How Performance Teams Are Organized
&lt;/h2&gt;

&lt;p&gt;Team structures can vary a lot.&lt;/p&gt;

&lt;p&gt;In some companies, a performance engineer works directly inside a product team together with developers and QA engineers.&lt;/p&gt;

&lt;p&gt;But quite often there are &lt;strong&gt;dedicated performance testing teams&lt;/strong&gt; that support multiple projects at once.&lt;/p&gt;

&lt;p&gt;I’ve seen setups where a single performance team works across several systems, helping different teams prepare for production traffic or major releases.&lt;/p&gt;

&lt;p&gt;In that case, the role becomes somewhat similar to an internal consultant who helps teams understand and improve system performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Work Never Really Stops
&lt;/h2&gt;

&lt;p&gt;One thing I quickly realized about performance engineering is that the work never really ends.&lt;/p&gt;

&lt;p&gt;Applications are constantly changing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;new features are added&lt;/li&gt;
&lt;li&gt;traffic grows&lt;/li&gt;
&lt;li&gt;infrastructure evolves&lt;/li&gt;
&lt;li&gt;architecture becomes more complex&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every change introduces new performance risks.&lt;/p&gt;

&lt;p&gt;That’s why performance testing is not just something you do before a release — it’s something that needs to happen continuously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Performance QA Engineers might not be the most common role, but their impact can be huge. This role uniquely combines testing, automation, database knowledge, backend and frontend understanding, DevOps practices, data analysis, and collaboration.&lt;/p&gt;

&lt;p&gt;And for me personally, that’s exactly what makes this role interesting.&lt;/p&gt;

&lt;p&gt;If this resonates and you want to dive deeper — I have a &lt;a href="https://www.udemy.com/course/performance-testing-fundamentals-from-basics-to-hands-on/?couponCode=DEV-COMMUNITY-COUPON" rel="noopener noreferrer"&gt;course on Udemy&lt;/a&gt; that covers performance testing from scratch.&lt;/p&gt;

</description>
      <category>career</category>
      <category>performance</category>
      <category>testing</category>
    </item>
    <item>
      <title>Black Friday: Would You Choose the Right Performance Test?</title>
      <dc:creator>Oleh Koren</dc:creator>
      <pubDate>Fri, 27 Feb 2026 09:50:40 +0000</pubDate>
      <link>https://forem.com/oleh_koren/black-friday-would-you-choose-the-right-performance-test-4j80</link>
      <guid>https://forem.com/oleh_koren/black-friday-would-you-choose-the-right-performance-test-4j80</guid>
      <description>&lt;p&gt;I recently ran a poll on LinkedIn in a Software Testing group.&lt;/p&gt;

&lt;p&gt;Here are the results:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ffuw5wen4p0w3kq5h8i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ffuw5wen4p0w3kq5h8i.png" alt=" " width="798" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spike Testing — ~55% ✅&lt;/p&gt;

&lt;p&gt;Which means:&lt;/p&gt;

&lt;p&gt;👉 ~45% of respondents chose the wrong answer.&lt;/p&gt;

&lt;p&gt;And that’s not surprising.&lt;/p&gt;

&lt;p&gt;Many engineers mix up load, volume, scalability, endurance, and spike testing — especially when the scenario sounds “real production-like”.&lt;/p&gt;

&lt;p&gt;Let’s break it down.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Spike Testing?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Spike testing&lt;/strong&gt; is a type of performance testing where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load increases &lt;strong&gt;suddenly and significantly&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;System behavior is observed during the spike&lt;/li&gt;
&lt;li&gt;System recovery is measured after the spike drops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1ogua7d8exesytp0h4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1ogua7d8exesytp0h4p.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It answers questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can the system handle a sudden traffic burst?&lt;/li&gt;
&lt;li&gt;Does it crash or degrade gracefully?&lt;/li&gt;
&lt;li&gt;Does it recover automatically?&lt;/li&gt;
&lt;li&gt;Are there cascading failures?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Black Friday traffic jumping 4x in minutes?&lt;br&gt;
That’s a textbook spike scenario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It’s NOT Volume Testing
&lt;/h2&gt;

&lt;p&gt;Volume testing checks how the system behaves with &lt;strong&gt;large amounts of data&lt;/strong&gt; (e.g., millions of records in the database).&lt;/p&gt;

&lt;p&gt;It’s about &lt;strong&gt;data size&lt;/strong&gt;, not sudden traffic bursts.&lt;/p&gt;

&lt;p&gt;Black Friday is not about data growth.&lt;br&gt;
It’s about concurrent users arriving fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It’s NOT Endurance Testing
&lt;/h2&gt;

&lt;p&gt;Endurance (soak) testing verifies system stability over long periods of sustained load.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpsfr3mh27nksrejkh2wm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpsfr3mh27nksrejkh2wm.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50-70% expected load&lt;/li&gt;
&lt;li&gt;6–14 hours&lt;/li&gt;
&lt;li&gt;Monitoring memory leaks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Black Friday spike is short-term chaos, not long-term stability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It’s Not Primarily Scalability Testing
&lt;/h2&gt;

&lt;p&gt;Scalability testing evaluates how well the system scales when load increases gradually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojme4eep1yulxuudv4k6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojme4eep1yulxuudv4k6.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linear resource growth&lt;/li&gt;
&lt;li&gt;Auto-scaling behavior (rules)&lt;/li&gt;
&lt;li&gt;Cost efficiency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But Black Friday is not gradual.&lt;br&gt;
It’s explosive.&lt;/p&gt;

&lt;p&gt;That difference matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Insight
&lt;/h2&gt;

&lt;p&gt;In real production systems, spike failures often happen because of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cold caches&lt;/li&gt;
&lt;li&gt;Connection pool limits&lt;/li&gt;
&lt;li&gt;Thread pool exhaustion&lt;/li&gt;
&lt;li&gt;DB lock&lt;/li&gt;
&lt;li&gt;Autoscaling delays&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here’s the critical part:&lt;/p&gt;

&lt;p&gt;Many teams test average load.&lt;br&gt;
Some test peak load.&lt;br&gt;
Very few test sudden load jumps.&lt;/p&gt;

&lt;p&gt;That’s where production incidents live.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>loadtesting</category>
      <category>softwaretesting</category>
      <category>testing</category>
    </item>
    <item>
      <title>How to Find Your API’s Breaking Point (Before Your Users Do) - Capacity Testing with JMeter</title>
      <dc:creator>Oleh Koren</dc:creator>
      <pubDate>Thu, 19 Feb 2026 06:45:45 +0000</pubDate>
      <link>https://forem.com/oleh_koren/how-to-find-your-apis-breaking-point-before-your-users-do-capacity-testing-with-jmeter-1jma</link>
      <guid>https://forem.com/oleh_koren/how-to-find-your-apis-breaking-point-before-your-users-do-capacity-testing-with-jmeter-1jma</guid>
      <description>&lt;p&gt;When you build an API service, it’s crucial to know how many users or requests it can handle before things start breaking. This is where capacity testing comes in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Capacity Testing?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Capacity testing identifies the maximum load your system can handle before performance degrades or errors appear.&lt;/p&gt;

&lt;p&gt;It helps detect bottlenecks and verify performance requirements under heavy load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capacity Testing an E-Commerce API with Apache JMeter
&lt;/h2&gt;

&lt;p&gt;Let’s say we have a REST API for an online store. We want to see how many requests it can handle before it starts failing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Organize Thread Groups
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Option 1:&lt;/strong&gt; Separate Thread Groups per endpoint&lt;/p&gt;

&lt;p&gt;Why? Because if one endpoint starts to degrade (high response time or errors), it can affect the throughput of other endpoints if tested together in the same group.&lt;/p&gt;

&lt;p&gt;Separate Thread Groups allow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Independent load for each endpoint&lt;/li&gt;
&lt;li&gt;Clear identification of which endpoint is the bottleneck&lt;/li&gt;
&lt;li&gt;Easier reporting and analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Option 2:&lt;/strong&gt; Mixed workload in one Thread Group&lt;/p&gt;

&lt;p&gt;In this case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple endpoints are executed together&lt;/li&gt;
&lt;li&gt;Load is distributed based on user behavior percentages&lt;/li&gt;
&lt;li&gt;The goal is to identify overall system capacity under real-world conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In this example, we use Option 1.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Load Configuration
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Number of Threads (Users)&lt;/strong&gt;&lt;br&gt;
Set per Thread Group based on expected usage (e.g., browsing endpoints typically require more users than checkout).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ramp-Up Period&lt;/strong&gt;&lt;br&gt;
Defines how quickly users are added.&lt;br&gt;
Short ramp-up creates spikes; longer ramp-up simulates gradual traffic growth (10 minutes).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loop Count and Duration&lt;/strong&gt;&lt;br&gt;
Loop Count = Infinite, with a 10-minute test duration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Startup Delay&lt;/strong&gt;&lt;br&gt;
Used for sequential Thread Groups to allow system recovery before applying the next load stage (the first Thread Group starts immediately).&lt;/p&gt;

&lt;p&gt;Increase users step-by-step to determine the capacity limit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Add Configuration Elements
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Add User-Defined Variables&lt;/strong&gt;&lt;br&gt;
Create a User-Defined Variables element to store values you’ll use across your test plan:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhpkfc1houpw9m2ro4kf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhpkfc1houpw9m2ro4kf.png" alt=" " width="713" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use variables?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Makes it easy to adjust load or URLs without editing each Thread Group&lt;/li&gt;
&lt;li&gt;Supports parameterization for multiple environments (dev, staging, production)&lt;/li&gt;
&lt;li&gt;Keeps the test plan organized and maintainable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now pass the created variables into the Thread Groups (example):&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh83hm4wqzlu5crv2u6nc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh83hm4wqzlu5crv2u6nc.png" alt=" " width="773" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Add HTTP Request Defaults&lt;/strong&gt;&lt;br&gt;
Add an HTTP Request Defaults element to set common request parameters, so you don’t have to repeat them in every HTTP Request sampler:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq163nwbu9yzpegzcgf8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq163nwbu9yzpegzcgf8a.png" alt=" " width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Add HTTP Requests
&lt;/h2&gt;

&lt;p&gt;Add an HTTP Request sampler to each Thread Group.&lt;br&gt;
Set the API endpoint and HTTP method (GET, POST, etc.) accordingly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thread Group 1 → &lt;code&gt;GET /products&lt;/code&gt; – browse products&lt;br&gt;
Thread Group 2 → &lt;code&gt;GET /products/{id}&lt;/code&gt; – view product details&lt;br&gt;
Thread Group 3 → &lt;code&gt;GET /products/search?q={searchPhrase}&lt;/code&gt; – search products by phrase&lt;br&gt;
Thread Group 4 → &lt;code&gt;GET /orders/{orderId}&lt;/code&gt; – order details&lt;br&gt;
… and so on&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Current Test Plan structure:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F10r4hb1pqe496grh168i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F10r4hb1pqe496grh168i.png" alt=" " width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Add Think Time
&lt;/h2&gt;

&lt;p&gt;Think Time simulates real user pauses between actions. &lt;br&gt;
In other words, it simulates the time a real user spends "thinking," reading, or interacting with a page before making the next request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why It Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without think time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JMeter sends requests back-to-back, which is not realistic&lt;/li&gt;
&lt;li&gt;The load pattern may overwhelm the system compared to real users&lt;/li&gt;
&lt;li&gt;Metrics like response time, throughput, and error rate can be misleading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With think time, the test more accurately reflects real user behavior, helping identify bottlenecks under realistic traffic conditions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Implement in JMeter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use Timers such as Constant, Uniform Random, or Gaussian Random.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Placement:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Place the Timer at the same hierarchical level as configuration elements in your Test Plan (above all Thread Groups).&lt;/li&gt;
&lt;li&gt;When positioned here, the Timer applies globally to all Thread Groups.&lt;/li&gt;
&lt;li&gt;This ensures consistent think time across all endpoints without repeating the Timer in each group&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9hjr8b85vbjz58mxhlv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9hjr8b85vbjz58mxhlv.png" alt=" " width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constant Delay Offset = 2000 ms → every request waits at least 2 seconds before executing.&lt;/li&gt;
&lt;li&gt;Random Delay Maximum = 4000 ms → adds a random delay between 0 and 4 seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each request will randomly wait somewhere between 2 and 6 seconds&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Add Listeners
&lt;/h2&gt;

&lt;p&gt;Listeners in Apache JMeter are used to collect, display, and export test results. They help you analyze performance metrics during and after test execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Add Aggregate Report&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggregate Report&lt;/strong&gt; – summary metrics (avg, min, max, throughput, error %).&lt;br&gt;
Useful for quick performance evaluation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Add View Results Tree&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;View Results Tree&lt;/strong&gt; – debugging only (inspect requests and responses).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Add Backend Listener&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend Listener&lt;/strong&gt; – send metrics to storage (InfluxDB) and analyze in Grafana for real-time dashboards and historical comparison.&lt;/p&gt;

&lt;p&gt;This approach allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitor performance in real time&lt;/li&gt;
&lt;li&gt;Store historical test data&lt;/li&gt;
&lt;li&gt;Build dashboards for trend analysis&lt;/li&gt;
&lt;li&gt;Compare multiple test runs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the Backend Listener with InfluxDB and Grafana provides a much more professional, production-ready analysis than basic JMeter listeners.&lt;/p&gt;

&lt;p&gt;Current Test Plan:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rhgfm5e98y6y4sy8p9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rhgfm5e98y6y4sy8p9n.png" alt=" " width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Run Test and Observe
&lt;/h2&gt;

&lt;p&gt;Start with a low number of users and increase gradually.&lt;/p&gt;

&lt;p&gt;Monitor server resources (CPU, memory, database connections) while testing.&lt;/p&gt;

&lt;p&gt;Capacity is reached when:&lt;/p&gt;

&lt;p&gt;When throughput stops increasing, response times spike, or errors appear, this indicates the capacity limit for that endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Example Result
&lt;/h2&gt;

&lt;p&gt;This example shows a 10-minute test with a 10-minute ramp-up to 100 users for the first endpoint: &lt;br&gt;
&lt;strong&gt;GET /products&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgaoshloo9sbzexr5fnt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgaoshloo9sbzexr5fnt.png" alt=" " width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since ramp-up equals test duration, users were added gradually throughout the entire test. Throughput increased steadily as concurrency grew.&lt;/p&gt;

&lt;p&gt;However, 500 errors appeared and increased with higher load, indicating endpoint degradation before reaching a stable throughput plateau. As a result, the capacity point could not be clearly determined, and a defect should be created for further investigation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvh2b405b88t0i9d18sy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvh2b405b88t0i9d18sy4.png" alt=" " width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This graph represents the response time metrics for the same 10-minute test.&lt;/p&gt;

&lt;p&gt;At the beginning of the test, response time is higher (~1 second) due to warm-up and cache initialization.&lt;/p&gt;

&lt;p&gt;After the initial minute, response time stabilizes around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P50 ≈ 510 ms&lt;/li&gt;
&lt;li&gt;P90 ≈ 540 ms&lt;/li&gt;
&lt;li&gt;P95 ≈ 580 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although latency remained relatively stable, the increasing error rate indicates system instability under higher concurrency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In summary:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Errors were present from the early stage of the test and increased with higher load&lt;/li&gt;
&lt;li&gt;Although response times remained relatively stable, the growing error rate indicates system instability&lt;/li&gt;
&lt;li&gt;A clear capacity point could not be determined&lt;/li&gt;
&lt;li&gt;Further investigation and defect creation are required before continuing capacity validation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Capacity testing should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Incremental&lt;/li&gt;
&lt;li&gt;Endpoint-specific&lt;/li&gt;
&lt;li&gt;Data-driven&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Testing endpoints separately provides clearer insights and prevents one bottleneck from hiding another.&lt;/p&gt;

&lt;p&gt;Only after stabilizing individual endpoints should you move to mixed workload testing for full system capacity validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to Go Further?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you’d like to dive deeper into other performance testing types and learn how to build a complete testing stack using JMeter, InfluxDB, and Grafana for real-time monitoring and analysis, you can explore the full course here:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.udemy.com/course/performance-testing-fundamentals-from-basics-to-hands-on/?couponCode=DEV-COMMUNITY-COUPON" rel="noopener noreferrer"&gt;Performance Testing Fundamentals: From Basics to Hands-On (Udemy)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>performance</category>
      <category>jmeter</category>
      <category>grafana</category>
    </item>
    <item>
      <title>Behind the Scenes: Why I Created a Performance Testing Course</title>
      <dc:creator>Oleh Koren</dc:creator>
      <pubDate>Fri, 13 Feb 2026 23:18:42 +0000</pubDate>
      <link>https://forem.com/oleh_koren/behind-the-scenes-why-i-created-a-performance-testing-course-22i0</link>
      <guid>https://forem.com/oleh_koren/behind-the-scenes-why-i-created-a-performance-testing-course-22i0</guid>
      <description>&lt;p&gt;&lt;strong&gt;Performance testing&lt;/strong&gt; is one of those skills many engineers think they understand.&lt;/p&gt;

&lt;p&gt;Until production says otherwise.&lt;/p&gt;

&lt;p&gt;Over the years, I kept seeing the same pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load test reports showing "PASSED"&lt;/li&gt;
&lt;li&gt;Average response time within limits&lt;/li&gt;
&lt;li&gt;Zero errors during the test&lt;/li&gt;
&lt;li&gt;And then… production incidents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem wasn’t tools.&lt;br&gt;
The problem was understanding.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gap I keep noticing
&lt;/h2&gt;

&lt;p&gt;When I looked at available learning materials, I saw a few common issues.&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;Outdated content disguised as "updated"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some courses are technically refreshed — new thumbnail, new title, small edits.&lt;/p&gt;

&lt;p&gt;But then you open the video and see a MS Word document on the screen for 15 minutes while the instructor reads text aloud.&lt;/p&gt;

&lt;p&gt;Performance testing is practical.&lt;/p&gt;

&lt;p&gt;It requires scenarios, metrics interpretation, trade-offs, and production context.&lt;/p&gt;

&lt;p&gt;Not just theory.&lt;/p&gt;

&lt;p&gt;2️⃣ &lt;strong&gt;Too tool-focused&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A lot of courses focus heavily on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Here’s how to use Tool X."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Buttons. Config fields. How to run a test.&lt;/p&gt;

&lt;p&gt;But very little about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to design a meaningful workload model&lt;/li&gt;
&lt;li&gt;How to connect performance metrics to real user experience&lt;/li&gt;
&lt;li&gt;How to interpret test results correctly&lt;/li&gt;
&lt;li&gt;How to prevent false confidence from "green" reports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools change.&lt;br&gt;
Principles don’t.&lt;/p&gt;

&lt;p&gt;If you only learn the tool, you’re limited.&lt;br&gt;
If you understand performance engineering thinking, you can use any tool.&lt;/p&gt;

&lt;p&gt;3️⃣ &lt;strong&gt;Limited structured material&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Performance testing isn’t as popular as automation testing or manual testing.&lt;/p&gt;

&lt;p&gt;Finding structured, end-to-end material is surprisingly hard.&lt;/p&gt;

&lt;p&gt;You’ll find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blog posts&lt;/li&gt;
&lt;li&gt;Isolated tutorials&lt;/li&gt;
&lt;li&gt;Tool documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But rarely a complete path from fundamentals → metrics → workload modeling → test executions → result analysis → reporting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The turning point
&lt;/h2&gt;

&lt;p&gt;After multiple production-related discussions and post-incident analyses, I realized something:&lt;/p&gt;

&lt;p&gt;Many teams don’t fail because they don’t run load tests.&lt;/p&gt;

&lt;p&gt;They fail because they don’t know how to think about performance correctly.&lt;/p&gt;

&lt;p&gt;That’s when the idea started forming — not to create “another tool course,” but to structure performance testing the way I believe it should be taught:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with core principles and the real purpose of performance testing in modern systems&lt;/li&gt;
&lt;li&gt;Explain why performance testing matters for business, not just for engineering&lt;/li&gt;
&lt;li&gt;Break down different types of performance tests and when to use each of them&lt;/li&gt;
&lt;li&gt;Dive deep into performance metrics and how to analyze results correctly&lt;/li&gt;
&lt;li&gt;Show how to choose the right tools instead of blindly following trends&lt;/li&gt;
&lt;li&gt;Demonstrate how to design and execute practical tests using JMeter and BlazeMeter&lt;/li&gt;
&lt;li&gt;Build a simple but complete performance testing setup with JMeter, InfluxDB, and Grafana&lt;/li&gt;
&lt;li&gt;Teach how to communicate results clearly to both technical and non-technical stakeholders&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it actually took
&lt;/h2&gt;

&lt;p&gt;It took around 3 months to create — evenings and weekends after my main job.&lt;/p&gt;

&lt;p&gt;The hardest part wasn’t just recording the videos.&lt;/p&gt;

&lt;p&gt;It was everything around it.&lt;/p&gt;

&lt;p&gt;I had to figure out recording tools, experiment with setups, and learn how to make the content look and sound professional. The first versions didn’t even pass the platform’s quality review because the audio wasn’t good enough. I had to invest in a proper microphone, re-record several lessons, adjust sound settings, and rethink the whole setup.&lt;/p&gt;

&lt;p&gt;Good audio matters more than most people expect.&lt;/p&gt;

&lt;p&gt;And while solving the technical side of recording, I was also trying to solve a different challenge — how to simplify complex topics without oversimplifying them.&lt;/p&gt;

&lt;p&gt;Performance testing sits at the intersection of infrastructure, backend architecture, system design, monitoring, and even statistics. Turning that into something structured, practical, and clear required a lot of iteration — reorganizing sections, refining explanations, replacing vague theory with concrete examples.&lt;/p&gt;

&lt;p&gt;Recording was just the visible part.&lt;/p&gt;

&lt;p&gt;The real work was making sure the content was both accurate and understandable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I’m sharing this
&lt;/h2&gt;

&lt;p&gt;Not as an announcement.&lt;/p&gt;

&lt;p&gt;But because performance testing deserves more attention.&lt;/p&gt;

&lt;p&gt;If you work in QA or backend engineering and you’ve ever seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"Average response time looks fine"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"It passed in staging"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"We didn’t see that coming"&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then you already know why this topic matters.&lt;/p&gt;

&lt;p&gt;I decided to organize my experience into a structured course. If you're curious, you can find it here:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.udemy.com/course/performance-testing-fundamentals-from-basics-to-hands-on/?couponCode=DEV-COMMUNITY-COUPON" rel="noopener noreferrer"&gt;Performance Testing Fundamentals: From Basics to Hands-On (Udemy)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Either way — I hope more engineers move beyond just running tests and start truly understanding performance.&lt;/p&gt;

&lt;p&gt;Because that’s where the real difference is made.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I’m Writing About This on Dev.to
&lt;/h2&gt;

&lt;p&gt;I’m not here just to publish a one-time announcement.&lt;/p&gt;

&lt;p&gt;My goal is to regularly share practical, sometimes uncomfortable topics related to performance testing.&lt;/p&gt;

&lt;p&gt;Performance testing is still a niche area compared to automation or backend/frontend development. But when systems fail, performance is often at the center of the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Through Dev.to, I want to:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break down real-world performance issues&lt;/li&gt;
&lt;li&gt;Explain concepts in a practical way&lt;/li&gt;
&lt;li&gt;Share lessons learned from production discussions&lt;/li&gt;
&lt;li&gt;Encourage deeper thinking beyond just “running a tool”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If performance engineering is relevant to your work, you’ll see more content here focused on fundamentals, interpretation, and real system behavior.&lt;/p&gt;

&lt;p&gt;Because the industry doesn’t need more button-click tutorials.&lt;/p&gt;

&lt;p&gt;It needs better performance thinking.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>performance</category>
    </item>
    <item>
      <title>Your Load Test Passed. Production Still Failed. Why?</title>
      <dc:creator>Oleh Koren</dc:creator>
      <pubDate>Wed, 11 Feb 2026 18:02:36 +0000</pubDate>
      <link>https://forem.com/oleh_koren/your-load-test-passed-production-still-failed-why-408</link>
      <guid>https://forem.com/oleh_koren/your-load-test-passed-production-still-failed-why-408</guid>
      <description>&lt;p&gt;Your load test report says:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;90th percentile&lt;/td&gt;
&lt;td&gt;1.7 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Errors&lt;/td&gt;
&lt;td&gt;0 %&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test result&lt;/td&gt;
&lt;td&gt;PASSED&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two weeks later — production incident.&lt;/p&gt;

&lt;p&gt;CPU spikes 🔺&lt;/p&gt;

&lt;p&gt;Users complain about 12-second response times ⏳&lt;/p&gt;

&lt;p&gt;What went wrong?&lt;/p&gt;

&lt;h2&gt;
  
  
  1️⃣ Unrealistic workload model
&lt;/h2&gt;

&lt;p&gt;In your test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;100% of users hit “Search”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No browsing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No login/logout mix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No background jobs impact&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In reality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Search + Login + Cart + Background jobs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scheduled tasks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Third-party API calls&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance issues rarely happen because of one endpoint.&lt;br&gt;
They happen because multiple flows compete for shared resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;DB connections&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thread pools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CPU&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Memory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I/O&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your workload model does not reflect real traffic distribution,&lt;br&gt;
you are not testing the system — you are testing a simplified demo.&lt;/p&gt;

&lt;p&gt;That’s not load testing&lt;/p&gt;
&lt;h2&gt;
  
  
  2️⃣ No think time
&lt;/h2&gt;

&lt;p&gt;🟥 Without think time, your test becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Request     │→│ Request     │→│ Request     │→│ Request     │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This artificially increases request rate per user.&lt;/p&gt;

&lt;p&gt;🟩 Real User:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Click       │→│ Read        │→│ Think       │→│ Click       │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without think time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You simulate robots, not humans&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You overload backend artificially&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU usage patterns&lt;/li&gt;
&lt;li&gt;DB lock behavior&lt;/li&gt;
&lt;li&gt;Thread scheduling&lt;/li&gt;
&lt;li&gt;Cache efficiency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Under realistic traffic, resource contention increases non-linearly.&lt;br&gt;
Once thread pools are saturated or DB connections are exhausted, response time doesn’t degrade gradually — it spikes.&lt;/p&gt;

&lt;p&gt;Most production incidents are not caused by load. They are caused by saturation.&lt;/p&gt;

&lt;h2&gt;
  
  
  3️⃣ No real production analytics
&lt;/h2&gt;

&lt;p&gt;Did you build your load model based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Real traffic distribution?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real endpoint usage ratios?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Peak hour data?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Seasonal spikes?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or just:&lt;/p&gt;

&lt;p&gt;“We expect around 1000 users.”&lt;/p&gt;

&lt;p&gt;Capacity planning without production analytics is guesswork.&lt;/p&gt;

&lt;p&gt;And guesswork doesn’t survive Black Friday traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  4️⃣ Test duration too short
&lt;/h2&gt;

&lt;p&gt;30 minutes ≠ production reality.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;0–30m&lt;/strong&gt; ✅ Everything looks fine&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2h&lt;/strong&gt; ✖ Memory pressure · Connection pool fragmentation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4h&lt;/strong&gt; ✖ Cache eviction thrashing · GC pauses grow longer&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6h&lt;/strong&gt; ✖ Thread pool starvation · Response times double&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12h+&lt;/strong&gt; ✖ OOM kills begin 🔴 · Silent data corruption&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you test only for 30 minutes, you only validate startup behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Load testing is not about running tests.&lt;/p&gt;

&lt;p&gt;It’s about modeling reality.&lt;/p&gt;

&lt;p&gt;And reality is always more complex than your script.&lt;/p&gt;

&lt;p&gt;If you want to move from “running load tests” to actually understanding system behavior under load, I cover workload modeling, performance criteria, monitoring, and real-world strategy step-by-step in my course:&lt;/p&gt;

&lt;p&gt;👉&lt;a href="https://www.udemy.com/course/performance-testing-fundamentals-from-basics-to-hands-on/?couponCode=DEV-COMMUNITY-COUPON" rel="noopener noreferrer"&gt;Performance Testing Fundamentals: From Basics to Hands-On (Udemy)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>loadtesting</category>
    </item>
    <item>
      <title>Why Percentiles Matter More Than Average Response Time in Performance Testing</title>
      <dc:creator>Oleh Koren</dc:creator>
      <pubDate>Mon, 09 Feb 2026 09:22:01 +0000</pubDate>
      <link>https://forem.com/oleh_koren/why-percentiles-matter-more-than-average-response-time-in-performance-testing-37d7</link>
      <guid>https://forem.com/oleh_koren/why-percentiles-matter-more-than-average-response-time-in-performance-testing-37d7</guid>
      <description>&lt;p&gt;When analyzing load test results, many teams highlight a single number:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Average response time = 1.2 seconds&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that number is often presented as the main indicator of system performance.&lt;/p&gt;

&lt;p&gt;The problem?&lt;br&gt;
&lt;strong&gt;Average response time can lie.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you rely only on the mean, you might completely miss serious performance issues affecting real users.&lt;/p&gt;

&lt;p&gt;Let’s break this down.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Average Response Time Is Misleading
&lt;/h2&gt;

&lt;p&gt;The average (mean) is calculated as:&lt;br&gt;
&lt;code&gt;Sum of all response times / Total number of requests&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Simple.&lt;/p&gt;

&lt;p&gt;But averages are highly sensitive to outliers.&lt;/p&gt;

&lt;p&gt;Imagine this response time distribution (in milliseconds):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csvs"&gt;&lt;code&gt;&lt;span class="mf"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;140&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;5000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rj40a5orw67p2ghavkv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rj40a5orw67p2ghavkv.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now calculate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Average&lt;/strong&gt; ≈ 821 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s a huge difference.&lt;br&gt;
One slow request (5000 ms) drastically shifts the average, even though most users experienced fast responses.&lt;/p&gt;

&lt;p&gt;Now imagine the opposite situation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csvs"&gt;&lt;code&gt;&lt;span class="mf"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;4620&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;4920&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiaranoc00gjcynrjguq2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiaranoc00gjcynrjguq2.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Average&lt;/strong&gt; ≈ 2060 ms&lt;/li&gt;
&lt;li&gt;But 3 out of 7 users waited 4+ seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Does the average really represent user experience?&lt;/p&gt;

&lt;p&gt;Not even close.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Percentiles Actually Show
&lt;/h2&gt;

&lt;p&gt;Percentiles answer a much more meaningful question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How fast were responses for most users?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Definition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The P95 response time means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;95% of all requests were completed in this time or faster.&lt;br&gt;
Only 5% were slower.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Similarly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P90 → 90% of requests are faster than this value&lt;/li&gt;
&lt;li&gt;P99 → 99% of requests are faster than this value&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Percentiles Are Calculated
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Sort all response times from smallest to largest.&lt;/li&gt;
&lt;li&gt;Determine the percentile position.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Basic intuition formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Position = (Percentile / 100) × N
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Percentile = for example 95 (for P95)&lt;/li&gt;
&lt;li&gt;100 = used to convert the percentage into a decimal (95% → 0.95)&lt;/li&gt;
&lt;li&gt;N = total number of requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
If you have 1000 requests:&lt;br&gt;
&lt;code&gt;P95 position = 0.95 × 1000 = 950&lt;/code&gt;&lt;br&gt;
The value around the 950th position in the sorted list represents your P95.&lt;/p&gt;

&lt;p&gt;In practice, different tools may use slightly different formulas and interpolation methods, but the core idea remains the same:&lt;/p&gt;

&lt;p&gt;Percentiles describe distribution, not averages.&lt;/p&gt;

&lt;p&gt;No magic. Just distribution awareness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Example from Load Testing
&lt;/h2&gt;

&lt;p&gt;Let’s say during a load test you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Average response time = 3981 ms&lt;/li&gt;
&lt;li&gt;Median (P50) = 3451 ms&lt;/li&gt;
&lt;li&gt;P90 = 7325 ms&lt;/li&gt;
&lt;li&gt;P95 = 9212 ms&lt;/li&gt;
&lt;li&gt;P99 = 12760 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyza6m6b96052894suvy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyza6m6b96052894suvy4.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn71h3la6ukbhk3vsbxfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn71h3la6ukbhk3vsbxfz.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you only report the average:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The system responds in about 4 seconds.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounds acceptable.&lt;/p&gt;

&lt;p&gt;But reality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10% of users wait more than 7.3 seconds&lt;/li&gt;
&lt;li&gt;5% wait more than 9.2 seconds&lt;/li&gt;
&lt;li&gt;1% wait more than 12.7 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now ask yourself:&lt;/p&gt;

&lt;p&gt;Would 1% of users waiting 12+ seconds be acceptable in your production system?&lt;/p&gt;

&lt;p&gt;For e-commerce during checkout?&lt;br&gt;
For login?&lt;br&gt;
For payment processing?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Percentiles Represent User Experience Better
&lt;/h2&gt;

&lt;p&gt;Users don’t experience averages. They experience their own request.&lt;/p&gt;

&lt;p&gt;If your P95 is high, that means a noticeable portion of users is suffering.&lt;/p&gt;

&lt;p&gt;In modern systems, especially:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High-concurrency APIs&lt;/li&gt;
&lt;li&gt;Distributed microservices&lt;/li&gt;
&lt;li&gt;Cloud-native environments&lt;/li&gt;
&lt;li&gt;Systems with auto-scaling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Latency spikes are normal.&lt;/p&gt;

&lt;p&gt;Percentiles help you detect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Queue buildup&lt;/li&gt;
&lt;li&gt;Thread pool saturation&lt;/li&gt;
&lt;li&gt;Garbage collection pauses&lt;/li&gt;
&lt;li&gt;Network bottlenecks&lt;/li&gt;
&lt;li&gt;Lock contention&lt;/li&gt;
&lt;li&gt;Cold starts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Average hides all of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Next time someone reports only the average response time, ask: &lt;/p&gt;

&lt;p&gt;What does P95 look like? &lt;br&gt;
What about P99?&lt;/p&gt;

&lt;p&gt;Because performance is about distribution —&lt;br&gt;
and users feel the slowest moments.&lt;/p&gt;

&lt;p&gt;If you want to better understand performance testing and go beyond just running tools, I cover this topic in more depth in my course:&lt;/p&gt;

&lt;p&gt;👉&lt;a href="https://www.udemy.com/course/performance-testing-fundamentals-from-basics-to-hands-on/?couponCode=DEV-COMMUNITY-COUPON" rel="noopener noreferrer"&gt;Performance Testing Fundamentals: From Basics to Hands-On (Udemy)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>loadtesting</category>
      <category>performancetesting</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
