<?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>DEV Community: Anton Moldovan</title>
    <description>The latest articles on DEV Community by Anton Moldovan (@antyadev).</description>
    <link>https://dev.to/antyadev</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%2F1128493%2Ff5de9d7b-8b50-437f-b564-f99e1e3b758f.jpeg</url>
      <title>DEV Community: Anton Moldovan</title>
      <link>https://dev.to/antyadev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/antyadev"/>
    <language>en</language>
    <item>
      <title>NBomber Studio 0.6.2</title>
      <dc:creator>Anton Moldovan</dc:creator>
      <pubDate>Wed, 18 Mar 2026 17:54:52 +0000</pubDate>
      <link>https://dev.to/nbomber/nbomber-studio-062-28al</link>
      <guid>https://dev.to/nbomber/nbomber-studio-062-28al</guid>
      <description>&lt;p&gt;The new 0.6.2 release introduces several powerful features: Compare Runs, Trend Analysis, Download HTML Report, and Stop Session.&lt;/p&gt;

&lt;p&gt;With these additions, NBomber Studio is evolving beyond being just a UI for NBomber metrics into a full-fledged load testing platform. We are also working on the upcoming Load Testing in Kubernetes feature, which we expect to release in April.&lt;/p&gt;

&lt;p&gt;To read the full blog post, please follow &lt;a href="https://nbomber.com/blog/2026/03/18/nbomber-studio-v0.6.2/" rel="noopener noreferrer"&gt;this link&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>fsharp</category>
      <category>loadtesting</category>
    </item>
    <item>
      <title>NBomber v6.2.0</title>
      <dc:creator>Anton Moldovan</dc:creator>
      <pubDate>Tue, 20 Jan 2026 19:26:32 +0000</pubDate>
      <link>https://dev.to/nbomber/nbomber-v620-1f16</link>
      <guid>https://dev.to/nbomber/nbomber-v620-1f16</guid>
      <description>&lt;p&gt;In the &lt;a href="https://github.com/PragmaticFlow/NBomber/releases/tag/v6.2.0" rel="noopener noreferrer"&gt;NBomber v6.2.0 release&lt;/a&gt;, we focused primarily on improvements to cluster mode, and we also introduced several useful enhancements to the HTML Report.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML Report improvements
&lt;/h2&gt;

&lt;p&gt;One of the invisible but important changes in the new HTML Report is that it has been completely rewritten in TypeScript. For a long time, we used vanilla JavaScript with Vue, but over time, it became difficult to manage complexity, reason about the code, and maintain correctness. Moving to TypeScript gives us type safety and makes future development more sustainable.&lt;/p&gt;

&lt;p&gt;Please &lt;a href="https://nbomber.com/blog/2026/01/20/nbomber-v6.2.0" rel="noopener noreferrer"&gt;follow this link&lt;/a&gt; to read the full blog post.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>fsharp</category>
      <category>loadtesting</category>
    </item>
    <item>
      <title>Load Testing Microservices</title>
      <dc:creator>Anton Moldovan</dc:creator>
      <pubDate>Fri, 02 May 2025 09:23:48 +0000</pubDate>
      <link>https://dev.to/nbomber/load-testing-microservices-4030</link>
      <guid>https://dev.to/nbomber/load-testing-microservices-4030</guid>
      <description>&lt;p&gt;When it comes to load testing microservices, we usually suggest applying two strategies:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Simulate User Journeys Across the Entire Application (End-to-End)
&lt;/h2&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%2F4tnhufynugi8cl1vsnbn.jpg" 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%2F4tnhufynugi8cl1vsnbn.jpg" alt="Image description" width="800" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One effective approach to load testing is simulating real-world user flows that interact with multiple services. These end-to-end tests replicate how users actually use your application—from logging in and browsing, to making purchases or performing other key actions.&lt;/p&gt;

&lt;p&gt;By executing these flows under load, you can assess how your microservices perform collectively. This helps identify bottlenecks in the orchestration of services, spot resource contention, and evaluate system behavior under realistic conditions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand how services interact under load.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uncover integration or orchestration issues&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Test autoscaling configuration to avoid unexpected overloads and ensure your system scales reliably under load.&lt;/li&gt;
&lt;li&gt;Validate that the system meets performance expectations from a user’s perspective.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High Infrastructure Cost&lt;/strong&gt;: Running load tests across the entire system typically requires spinning up all microservices, databases, caches, queues, and other dependencies. This can be resource-intensive, especially if you need to scale components just for the purpose of the test. For big companies this type of tests can lead to significant costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slower Feedback Loop&lt;/strong&gt;: Because of the orchestration involved, these tests take longer to set up, prepare data and run, making them less suitable for fast, iterative development cycles. As a result, your developers might only discover performance degradations at the last moment.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;We recommend using end-to-end strategy, as it can reveal issues that are difficult to identify&lt;/strong&gt; when testing microservices in isolation (we explain this in more detail later on this page). However, &lt;strong&gt;big companies typically run such tests less frequently&lt;/strong&gt; — often in preparation for major events like Black Friday or monthly releases. The main reason to run such tests less frequently is due to their cost — depending on the scale of the company, these tests can be expensive to run. For small and medium-sized companies, infrastructure costs may not be an issue — they often utilize their staging environments for this purpose.&lt;/li&gt;
&lt;li&gt;Usually this type of tests is writen by automation QA engineers, not developers.&lt;/li&gt;
&lt;li&gt;To write such tests based on user journeys, &lt;strong&gt;we recommend using the &lt;a href="https://nbomber.com/docs/nbomber/load-simulation#closed-model" rel="noopener noreferrer"&gt;Closed Model&lt;/a&gt; for simulating workload&lt;/strong&gt;, since the user flow is transactional and modeled as a sequence of dependent steps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Test Individual Microservices in Isolation
&lt;/h2&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%2F9xrzkqvzqo5iyyf1cwwx.jpg" 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%2F9xrzkqvzqo5iyyf1cwwx.jpg" alt="Image description" width="800" height="1409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While end-to-end testing provides a macro view, it’s equally important to test microservices in isolation. This strategy helps you pinpoint which services may struggle with performance independently of the rest of the system.&lt;/p&gt;

&lt;p&gt;In isolated tests, you can simulate the service's inputs—usually HTTP requests, message queue events, or gRPC calls—and measure how it handles increasing load. This allows you to fine-tune specific services, detect memory leaks, or assess how the service scales independently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Low infrastructure costs&lt;/strong&gt;: These tests are usually very easy to set up and run even on developer machine. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast feedback loop&lt;/strong&gt;: You can quickly identify performance degradation in a specific service. &lt;strong&gt;Isolated tests can be easily integrated into your CI/CD pipeline&lt;/strong&gt; and treated like regular unit or integration tests.&lt;/li&gt;
&lt;li&gt;Identify performance bottlenecks within individual services.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;These tests are not fully representative&lt;/strong&gt;: They typically cover only a single service. The worst-case scenario is when multiple services, each performing well in isolated tests but fail to handle the expected load when run together in a production environment.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;We recommend using this strategy as it is cheaper than full end-to-end load tests and provides an easy way for developers to run it locally and get quick results.&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Usually this type of tests are writen by developers and not automation QA engineers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prioritize services that interact directly with the database&lt;/strong&gt;. If these services perform well, upstream dependent services will typically also benefit. Database scalability is often the main bottleneck, so it's more effective to focus on services that work directly with the database rather than those that depend on other services in the chain.&lt;/li&gt;
&lt;li&gt;To write isolated load tests, &lt;strong&gt;we recommend using the &lt;a href="https://nbomber.com/docs/nbomber/load-simulation#open-model" rel="noopener noreferrer"&gt;Open Model&lt;/a&gt; for simulating workload&lt;/strong&gt;. From the perspective of an individual service, it may expose several endpoints that are partially used by different user flows concurrently. At this level, it's simpler to reason about the service in terms of request rate rather than number of concurrent users. Additionally, when defining your &lt;a href="https://cloud.google.com/blog/products/devops-sre/sre-fundamentals-slis-slas-and-slos" rel="noopener noreferrer"&gt;SLO/SLA&lt;/a&gt;, companies usually focus on metrics like request rate and error rate — so using the Open Model aligns well with these targets. Another important benefit is that the Open Model tends to produce more consistent results, which makes it easier to apply reliable assertion logic.&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%2F2zucmc2mpv0zukuj3iop.jpg" 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%2F2zucmc2mpv0zukuj3iop.jpg" alt="Image description" width="800" height="782"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your microservice depends on other services, especially those outside your ownership, you should consider mocking them. Mocking dependent services is often necessary to isolate the system under test and ensure more reliable and consistent load test results. Make sure your mocked API allows you to configure latency delays and has sufficient throughput capacity (at a minimum, it should be fast enough not to become a bottleneck).&lt;/p&gt;

</description>
      <category>nbomber</category>
      <category>loadtesting</category>
      <category>performance</category>
      <category>microservices</category>
    </item>
    <item>
      <title>NBomber v6.0.1</title>
      <dc:creator>Anton Moldovan</dc:creator>
      <pubDate>Mon, 17 Mar 2025 10:54:40 +0000</pubDate>
      <link>https://dev.to/nbomber/nbomber-v601-3522</link>
      <guid>https://dev.to/nbomber/nbomber-v601-3522</guid>
      <description>&lt;p&gt;In the &lt;a href="https://github.com/PragmaticFlow/NBomber/releases/tag/v6.0.1" rel="noopener noreferrer"&gt;new release&lt;/a&gt;, we are introducing Custom Metrics, one of the most requested features. Additionally, we've made several improvements related to thresholds, memory consumption, CSV, HTML reports, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Metrics
&lt;/h2&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%2Ffjrd3sryalp3r9p7xo1d.jpg" 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%2Ffjrd3sryalp3r9p7xo1d.jpg" alt="Image description" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Metrics are numerical measurements reported over time. By default, NBomber automatically collects built-in metrics: CPU, RAM (usage), Data (sent/receive), and more. Besides built-ins, now you can define your custom metrics.&lt;/p&gt;

&lt;p&gt;NBomber provides different types of custom metrics that you can use, depending on what you want to measure. These include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Counter&lt;/strong&gt;: a cumulative count of events, such as the number of successful or failed requests.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-counter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unitOfMeasure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"MB"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// tracks a value that may increase or decrease over time&lt;/span&gt;
&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gauge&lt;/strong&gt;: measures the last value recorded, such as memory usage or the number of active users at a given time.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;gauge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateGauge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-gauge"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unitOfMeasure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"KB"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;gauge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;6.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;gauge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7.3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// set the current value of the metric&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use your custom metrics with thresholds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"scenario"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithThresholds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Threshold&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Counters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-counter"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Threshold&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Gauges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-gauge"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;6.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or define thresholds in the JSON config file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"ThresholdSettings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Metric"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"my-counter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"value &amp;lt; 1000"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Metric"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"my-gauge"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"value &amp;gt;= 6.5"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All these capabilities open up new ways to validate specific conditions. After running a load test, you will be able to view and check custom metric values in the HTML report.&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%2Fc2bvtlcs5fhvdjm3qkbl.jpg" 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%2Fc2bvtlcs5fhvdjm3qkbl.jpg" alt="Image description" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also see them in the Console UI.&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%2F29o8zy0hzerozdc8tzes.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%2F29o8zy0hzerozdc8tzes.png" alt="Image description" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more information about this feature, please refer to our &lt;a href="https://nbomber.com/docs/nbomber/custom-metrics" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML Report: New Metrics Tabs
&lt;/h2&gt;

&lt;p&gt;We've slightly rearranged the tabs in the HTML report to provide more convenient navigation based on the scenario context.&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%2Fasanebu3oio0t0ug7e59.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%2Fasanebu3oio0t0ug7e59.png" alt="Image description" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML Report: Printout Threshold code body
&lt;/h2&gt;

&lt;p&gt;In the previous v5.8 release, NBomber introduced a new feature called Runtime Thresholds. This feature allows you to define thresholds using C#/F# code or JSON expressions. Defining thresholds in JSON was a bit more complete as you could see the JSON expression text in your HTML report. The downside of defining a threshold using C#/F# code was that &lt;code&gt;checkExpression&lt;/code&gt; wasn't displayed in the final HTML report.&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%2F8ug9w85bahp79d9rw872.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%2F8ug9w85bahp79d9rw872.png" alt="Image description" width="800" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, we've fixed that! In the new release, we've added functionality that iterates over the code body and prints it.&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%2Fo69utwogu8e9bh6edcez.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%2Fo69utwogu8e9bh6edcez.png" alt="Image description" width="800" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GetScenarioTimerTime
&lt;/h2&gt;

&lt;p&gt;We've added a feature that allows you to get the current time of the scenario timer. This can be useful for scenarios that depend on time-based criteria within the scenario.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello_world_scenario"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;currentScenarioTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetScenarioTimerTime&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Information&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Current scenario time: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;currentScenarioTime&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can find the complete example by this &lt;a href="https://github.com/PragmaticFlow/NBomber/blob/dev/examples/Demo/HelloWorld/ScenarioTimerTimeExample.cs" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Latency
&lt;/h2&gt;

&lt;p&gt;We've added an option to pass custom latency, which can be useful for streaming-based scenarios where you need to measure the latency between several independent processes that publish and consume data independently. In the future, we will describe this use case in our documentation and provide guidance on how to handle it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customLatencyMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  New System Metrics
&lt;/h2&gt;

&lt;p&gt;We've expanded our standard list of system metrics by adding a few important ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dns-lookups-duration&lt;/code&gt; - The average time taken for a DNS lookup&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dns-lookups-requested&lt;/code&gt; - The number of DNS lookups requested since the process started&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gc:loh-size&lt;/code&gt; - The number of bytes for the large object heap&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gc:time-in-gc&lt;/code&gt; - The percent of time in GC since the last GC&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%2F2dzciy1uyvxrxg1u8sww.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%2F2dzciy1uyvxrxg1u8sww.png" alt="Image description" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CSV Report: Failures Stats
&lt;/h2&gt;

&lt;p&gt;Previously, NBomber's CSV reports didn't include statistics on failures. The default way to get failure stats was by getting them from the final &lt;code&gt;NodeStats&lt;/code&gt; record or by using &lt;code&gt;IReportingSink&lt;/code&gt; and subscribing to real-time metrics. However, some of our clients still rely on CSV for extracting data to process further. To maintain consistency with other reports, we've now added failure statistics to the CSV report as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logs folder change for NBomber Cluster
&lt;/h2&gt;

&lt;p&gt;When running NBomber Cluster, the Coordinator folder and Agent(s) folders are created at the same level. This can be inconvenient if you're storing logs in blob storage. We've addressed this by nesting the Agent logs under the same session folder path. The folder structure now looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sessionId/reports&lt;/code&gt; - for Coordinator&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sessionId/reports/agentId&lt;/code&gt; - for Agent&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  XML documentation link
&lt;/h2&gt;

&lt;p&gt;Since day one, NBomber has provided documentation comments for IDE IntelliSense. While this works well, there were cases where a more detailed documentation page would be helpful. To address this, we've added a link to the Documentation page that describes specific features. Now, you can click the Documentation link in the pop-up window and navigate to the full page documentation.&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%2Fne1bzynmozs2705jw91q.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%2Fne1bzynmozs2705jw91q.png" alt="Image description" width="800" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance improvements
&lt;/h2&gt;

&lt;p&gt;At NBomber, we are always striving to optimize performance, aiming to make our framework the fastest and most resource-efficient. This release is no exception.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mean and StdDev
&lt;/h3&gt;

&lt;p&gt;We made an optimization related to the calculation of &lt;code&gt;Mean&lt;/code&gt; and &lt;code&gt;StdDev&lt;/code&gt;. For real-time reporting, we need to calculate these values periodically (each 5 sec). Previously, we had to iterate through all items to calculate the &lt;code&gt;Mean&lt;/code&gt;. However, we discovered that we can completely skip this step by tracking the &lt;code&gt;Mean&lt;/code&gt; as we go. This optimization also contributed to the performance of &lt;code&gt;StdDev&lt;/code&gt;, which depends on the &lt;code&gt;Mean&lt;/code&gt; calculation.&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON serialization
&lt;/h3&gt;

&lt;p&gt;We found that for long-running scenarios, especially those lasting over 1-2 hours, generating the HTML report can be quite heavy. The main contributor to this is extra memory allocations that occur when serializing the metrics history in JSON for the HTML report. Historically, we used the &lt;a href="https://github.com/PragmaticFlow/FSharp.Json.New" rel="noopener noreferrer"&gt;F# JSON serializer&lt;/a&gt;, which works well with F# types and also plays an important role in schema validation for JSON config parsing. F# JSON validates the JSON based on the types you pass, which is great. However, the downside is that this library was written a long time ago and isn't very memory-efficient. In the new release, we've limited the use of F# JSON, using it only for parsing the JSON config. For all other cases, we've switched to the standard .NET System.Text.Json, which delivers much better performance. In addtition, we conducted a benchmark using one hour of statistics for five concurrent scenarios.&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%2Ftmm6212sbq56uen6d2dr.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%2Ftmm6212sbq56uen6d2dr.png" alt="Image description" width="800" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Statistics compression
&lt;/h3&gt;

&lt;p&gt;We've started compressing statistics, which has reduced memory usage. While we hadn't encountered any issues with this in the past, we still decided to optimize it. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Previously, storing one hour of stats for a single scenario required ~5MB of RAM. With the new optimizations, we've reduced it to just 360KB. In absolute numbers, the impact is minimal, but optimizations like this help reduce GC pressure, making them worthwhile.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  NBomber Studio
&lt;/h2&gt;

&lt;p&gt;Alongside NBomber, we released a new version of &lt;a href="https://nbomber.com/docs/nbomber-studio/overview" rel="noopener noreferrer"&gt;NBomber Studio&lt;/a&gt;. This update includes bug fixes related to frontend session handling and improvements to the UI. We've removed manual steps, such as having to click the refresh or search button to get updates.&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%2Fojp1ahl509g5obk2el4z.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%2Fojp1ahl509g5obk2el4z.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the previous version, UI auto-updates only worked for an open session, but we've now expanded this functionality further. The search button has been removed from filtering, and now, when you change something—such as the date range or test name—requests are sent automatically. Additionally, we’ve added auto-updating for the History tab, as it's a useful feature.&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%2Fyjohlc8r81phawdhagjl.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%2Fyjohlc8r81phawdhagjl.png" alt="Image description" width="800" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nbomber.com/blog/2025/03/17/nbomber-v6.0.1/" rel="noopener noreferrer"&gt;Original blog post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/PragmaticFlow/NBomber/releases/tag/v6.0.1" rel="noopener noreferrer"&gt;Release Notes for v6.0.1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Please follow our &lt;a href="https://nbomber.com/docs/getting-started/roadmap" rel="noopener noreferrer"&gt;Roadmap&lt;/a&gt; page for the upcoming release.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>loadtesting</category>
      <category>performance</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
