{"id":57958,"date":"2024-09-20T03:35:34","date_gmt":"2024-09-20T10:35:34","guid":{"rendered":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/?p=57958"},"modified":"2025-05-29T03:20:43","modified_gmt":"2025-05-29T10:20:43","slug":"creating-in-house-performance-testing-tool","status":"publish","type":"post","link":"\/us\/en\/blog\/creating-in-house-performance-testing-tool\/","title":{"rendered":"Creating in-house performance testing tool"},"content":{"rendered":"<p><span style=\"font-weight: 400\">Highlights\u00a0<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">His team created its own performance testing tool.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Stanislav shares insights on how the architecture of the tool was built and describes the entire process of the tool&#8217;s creation.<\/span><\/li>\n<\/ul>\n<hr \/>\n<h2><span style=\"font-weight: 400\">Introduction<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Hi, my name is Stas (but you can call me Stan, if you like it better) and I am a Senior Quality Assurance Engineer at RingCentral Bulgaria. We develop an UCaaS solution for business communications. Specifically, my team is part of the Analytics department. The department&#8217;s main product is an analytics portal (all of a sudden, huh?) that can provide RingCentral customers with detailed information about calls, video meetings, webinars, rooms and devices. My team is responsible for telephony analytics: we develop and maintain some reports about call metrics and call quality within the analytics portal.<\/span><\/p>\n<p><span style=\"font-weight: 400\">About two years ago our department in general and my team in particular started to develop a new call report. Normally, reports like ours are about some infrequent large queries to databases with their subsequent study and analysis. But in case of a new report, company protocols require us to perform some steps for production readiness validation. One of these steps is a performance test. So in the text below I will tell you our way of creating our own performance testing tool.<\/span><\/p>\n<p><span style=\"font-weight: 400\">In this piece, I will describe my experience in general terms without much detail. I aim to show you exactly how to proceed and let you find your own way with my humble hints.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Infrastructure evolution<\/span><\/h2>\n<p><span style=\"font-weight: 400\">At the moment when our team realized that we definitely need a tool for performance testing, we&#8217;ve already had some work done. So here&#8217;s some background information on the relationship between us and performance tests.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">An ace up my sleeve<\/span><\/h2>\n<p><span style=\"font-weight: 400\">As the Google Scholar project slogan says &#8220;Stand on the shoulders of giants&#8221;, I&#8217;m standing on the shoulders of my colleagues. As a performance testing tool, we&#8217;re using the Gatling plugin for sbt. The very first person to bring it to our project was my ex-teammate. Our team was migrating from one database to another, and we needed to somehow check the performance of a particular report, so we used the test results to make sure that the tested report worked well under pressure. But I should note that this wasn&#8217;t any kind of activity that would require the creation of an official report.<\/span><\/p>\n<p><span style=\"font-weight: 400\">So what exactly did we have at that moment? It was a simple Scala class with a simple test for a specific method. This test used (and to be honest, the original code is still somewhere in the wilds of the repository, so I can say &#8220;uses&#8221;, by the way) the Kubernetes Port Forward method, which is often used to establish a connection between internal cluster resources and the local machine. I won&#8217;t explain how this method works, but I will say that this method has limitations that do not allow it to be used as a regular connection for performance testing purposes. As you can understand, I have replaced the Port Forward method with something else.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Revving up<\/span><\/h2>\n<p><span style=\"font-weight: 400\">As I mentioned above, I replaced the Port Forward method with another type of connection. I happened to have another project before this one. The main goal of that project was to create a set of tests to help our DevOps team verify an environment after a release deployment. Originally, port forwarding was used here as well, but our DevOps created an enhancement that allows some services to connect directly to cluster routers. So I used this new feature to increase the stability of these tests.<\/span><\/p>\n<p><span style=\"font-weight: 400\">At the same time, this gave me an idea: what if I try to use this new connection type for a performance test? Theoretically, everything should be better: the throughput capacity should be higher than the port forward capacity. Stability should also be better. So I changed the connection scheme here. Let&#8217;s see the difference.<\/span><\/p>\n<p><span style=\"font-weight: 400\">The image below shows the first version of the architecture.<\/span><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-57963\" src=\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Scheme-1-H.png\" alt=\"\" width=\"2048\" height=\"701\" \/><\/p>\n<p><span style=\"font-weight: 400\">The second image below shows the next version of the architecture.<\/span><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-57966\" src=\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Scheme-3-H.png\" alt=\"\" width=\"2048\" height=\"701\" \/><\/p>\n<p><span style=\"font-weight: 400\">After this change I noticed that I got higher speed and channel capacity, but there are still network lags in this version, so I still have some room for improvement.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Above the klouds<\/span><\/h2>\n<p><span style=\"font-weight: 400\">As a next step I decided that it will be much better if our test module will be deployed to the cluster (klouds because clouds + kubernetes, don&#8217;t tell me you didn&#8217;t get it).<\/span><\/p>\n<p><span style=\"font-weight: 400\">At this step we need to clarify the next thing: should it be a deployment or a job? Both ways have their own advantages. Deployment has advantages such as scalability (easy to scale up or down based on performance testing needs), resiliency (automatically replaces pods that fail, get deleted, or are terminated), and ease of update and rollback process. But if we take a look at the job benefits, the decision is easy: task completion focus (designed to run batch jobs to completion) and cleanup mechanism (job can delete produced work-in-progress artefacts).<\/span><\/p>\n<p><span style=\"font-weight: 400\">Let&#8217;s see what our architecture looks like after wrapping the test into the k8s job.<\/span><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-57967\" src=\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Scheme-2-H-1-1.png\" alt=\"\" width=\"2048\" height=\"974\" \/><br \/>\n<span style=\"font-weight: 400\">It looks good, I&#8217;d say it&#8217;s production ready, but it&#8217;s not. We still have a router as a bottleneck. And there&#8217;s a good chance that running an intensive performance test on a router will affect other members of the development team.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Kill the middleman<\/span><\/h2>\n<p><span style=\"font-weight: 400\">The final step in tuning the test architecture is to remove the last redundant part of our route between Gatling and a service. Since we have already deployed Gatling to the Kubernetes cluster, we just need to change some target configurations in the test source code and voila \u2014 we have excluded the router from our chain.<\/span><\/p>\n<p><span style=\"font-weight: 400\"> <img decoding=\"async\" class=\"alignnone size-full wp-image-57964\" src=\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Scheme-2-H.png\" alt=\"\" width=\"2048\" height=\"692\" \/><\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400\">After all these changes, I think it&#8217;s time to look back and analyze our improvements.<\/span><\/p>\n<h2 class=\"heading h2 h3\"><span style=\"font-weight: 400\">Some boring numbers<\/span><\/h2>\n<p><span style=\"font-weight: 400\">If we want to understand what we&#8217;ve done after all, there\u2019s no better way than to compare measurement results on each step. In the table below I will show you the difference, but before I should explain what exactly is placed in this table.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Gatling automatically divides responses in three groups by response time. There\u2019re less than 800 ms (milliseconds), from 800 ms to 1200 ms and from 1200 ms and above. So the table will contain these three rows with percent of responses getting into this gap plus rows with failed responses count. And there\u2019ll be three columns: measurements for the first architecture with port forward, for second iteration with router DNS and for the last one. I deliberately omit measurements of the penultimate stage because they\u2019re not very revealing in my particular case. But it doesn\u2019t mean that you can skip this step without any consequences.\u00a0<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><\/td>\n<td><span style=\"font-weight: 400\">Port forward, % responses<\/span><\/td>\n<td><span style=\"font-weight: 400\">Router DNS, % responses<\/span><\/td>\n<td><span style=\"font-weight: 400\">Job in k8s, % responses<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">t &lt; 800 ms<\/span><\/td>\n<td><span style=\"font-weight: 400\">0%<\/span><\/td>\n<td><span style=\"font-weight: 400\">2%<\/span><\/td>\n<td><span style=\"font-weight: 400\">53%<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">800 ms &lt;= t &lt; 1200 ms<\/span><\/td>\n<td><span style=\"font-weight: 400\">1%<\/span><\/td>\n<td><span style=\"font-weight: 400\">25%<\/span><\/td>\n<td><span style=\"font-weight: 400\">13%<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">t &gt;= 1200 ms<\/span><\/td>\n<td><span style=\"font-weight: 400\">12%<\/span><\/td>\n<td><span style=\"font-weight: 400\">73%<\/span><\/td>\n<td><span style=\"font-weight: 400\">34%<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">failed<\/span><\/td>\n<td><span style=\"font-weight: 400\">87%<\/span><\/td>\n<td><span style=\"font-weight: 400\">0%<\/span><\/td>\n<td><span style=\"font-weight: 400\">0%<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400\">As we can see, all our movements were not in vain. Buckle up, in the next part I\u2019ll tell you more about the tests themselves and how we designed them.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Under the hood<\/span><\/h2>\n<p><span style=\"font-weight: 400\">We&#8217;ve talked about test infrastructure so far, but we haven&#8217;t said a word about what goes on inside our test container. You might be curious, so in the following part of my humble article, I will tell you more about performance testing itself.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Choose your fighter<\/span><\/h2>\n<p><span style=\"font-weight: 400\">One of the most important tasks for us was to understand which accounts to use for testing and how to select them. As I mentioned in the introduction, my team works with telephony data, so we measure all accounts in calls per day.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">As you can see, the account ID is an important parameter for our test. Depending on it, we will get different amounts of calls in the same period of time, because obviously accounts have different rates of calls per day\/week\/month\/year. At this point we realized that we need to divide all the accounts into some groups so that it&#8217;s possible to divide them into groups of similar size according to the amount of calls.<\/span><\/p>\n<p><span style=\"font-weight: 400\">I think you can guess the purpose of this division, but I&#8217;ll explain it anyway. If an account has more calls in it, it will take up more space in a database, and responses with calls for this account will be heavier compared to smaller accounts. Given these facts, we should understand that if we mix large and small accounts, the averages will be skewed. So if we want to measure performance for a large account, we should use only large accounts to ensure the validity of the measurement data.<\/span><\/p>\n<p><span style=\"font-weight: 400\">We have decided that three groups are sufficient for us: small, medium and large. In your case, the evaluation parameters and the number of groups may be different. But it doesn&#8217;t change the main idea \u2014 you should think carefully about whether the data should be divided in any way.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">All in good time<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Another important parameter for the test is time. Here we come to a few different problems. If we want to make some test runs in a single day, we should take into account that the call density isn&#8217;t uniform throughout the day. Also we should take into account that peak time is usually in a work day for our customers, most of which live in US\/Canada time zones.<\/span><\/p>\n<p><span style=\"font-weight: 400\">So if we don&#8217;t want to miss the right gap, we might do the next thing: adjust all to one timezone and declare in that zone the most interesting gaps. I think that the best timezone is UTC aka GMT+0. Adjusting all times to this specific one will help us avoid any time confusion.<\/span><\/p>\n<p><span style=\"font-weight: 400\">But that&#8217;s not all problems with defining the time range. Performance testing is a tricky thing, you should consider many things and nuances. One of them is cache memory or just cache. Yep, the thing that usually helps you will now play against you. Let me explain where the devil hides.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Imagine that you want to test your service performance with processing monthly data. And the depth of data storage is one year. Here you will have 12 months of the data. But you don&#8217;t have to set a date range beginning only as the month beginning, right? Because if you set your gaps with whole months, you will get 12 gaps or even 11 because the day we are performing the test run might be in the middle of the month, so we wouldn\u2019t count this part of the month. But here\u2019s the moment when cache comes into play. You see, there\u2019s only 12 (or 11) unique requests in terms of date range. That means, when your test will make a 13th request to the service, all possible responses will be processed at least one time. So response time will be corrupted with cache affection. Of course I don\u2019t think that you will set ranges like these, it\u2019s just an example.<\/span><\/p>\n<p><span style=\"font-weight: 400\">But why is that bad? If you\u2019re aiming to measure a single response time, there\u2019s nothing bad. But in case if you have a lot more requests to run, you won\u2019t get really much useful information. So how exactly do we trick the cache? The first option &#8211; disable it. Yes, that&#8217;s simple. But in case that you can\u2019t, here\u2019s the second option: use smaller units of time. I will show you how I\u2019ve done it.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Let\u2019s get back to our example. We have 12 months of data and are willing to measure response time for a monthly request. Maybe we should take day granularity? Then we\u2019ll have 335 different gaps. I assume that the year has 365 days and the average month has 30 days, so we can take any day from today to the day that was 11 months ago as the end of the requested time range. And any day from a year ago to 1 month ago. Thus we obtain a moving month with a rather large spread. But if you\u2019re going to make a lot more requests, you can downscale from days to hours. You will be able to get more than 7000 uniq time ranges.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Ugh, I was tired while I was writing this. Let\u2019s talk about something easier for understanding (and explaining).<\/span><\/p>\n<h2><span style=\"font-weight: 400\">And what\u2019s next?<\/span><\/h2>\n<p><span style=\"font-weight: 400\">The last step: define your simulation strategy. Sounds easy, huh? but that&#8217;s just at first glance. There\u2019re a few types of simulation, but we\u2019ll consider only three basic types of them here. They\u2019re debug, border performance and stability. But before we talk about them let\u2019s discuss some important terms.<\/span><\/p>\n<p><span style=\"font-weight: 400\">I will use next terms in the following text:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Intensity \u2014 number of requests per second to a service.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Ramp duration \u2014 period of time when number of requests increases from current number of requests to another.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Stage duration \u2014 period of time when number of requests is kept stable.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Stage numbers \u2014 number of stage durations used in a particular test.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400\">Now we\u2019re ready to discuss different kinds of simulation. I will give some examples of values above for each type, but don\u2019t mind changing them according to your needs.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Debug<\/span><\/h3>\n<p><span style=\"font-weight: 400\">The most simple and at the same time the most important type. It is used for debugging and testing the logic of the scripts themselves. I suggest using minimal static load in this case without any ramp. So the numbers will be Intensity = 1, Ramp duration = Null, Stage duration = 10 sec, Stage numbers = 1.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Border performance<\/span><\/h3>\n<p><span style=\"font-weight: 400\">This simulation type is used to run tests with a step load. We use it to determine the points of maximum performance: increasing load with each step we can find an upper point of acceptable load for the service under test. Below is a graph that demonstrates how it works.<\/span><\/p>\n<p><span style=\"font-weight: 400\">In the graph you can see the ramp duration of the load. The next load stage is reached during ramp duration. The stage itself lasts for stage duration, intensity per stage is calculated by the formula intensity \/ stage numbers. Here I won\u2019t give you any exact numbers but I\u2019ll give you some suggestions. First, adjust ramp duration. Increasing the load should be more gradual, so it will be easier to see where potential problems could be. But it should not be stretched too much either. Second, stage duration should not be shorter than ramp duration. You may adjust its length but I do not recommend to make it too short: deviations at the current load can be overlooked and this will blur the results for the next iteration.<\/span><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-57968\" src=\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Scheme-4-1024x653-1.png\" alt=\"\" width=\"1024\" height=\"653\" \/><\/p>\n<h3><span style=\"font-weight: 400\">Stability<\/span><\/h3>\n<p><span style=\"font-weight: 400\">This simulation type is used to run tests with a steadily supplied load with preliminary gradual overclocking. Such a test can be useful for confirming the stable operation of an application and performing regression tests. Below is an example of a steadily fed load test.<\/span><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-57969\" src=\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Scheme-5-1024x653-1.png\" alt=\"\" width=\"1024\" height=\"653\" \/><\/p>\n<p><span style=\"font-weight: 400\">In the graph, you can see the stable load being supplied. Stable load is reached during ramp duration, stable load lasts during stage duration with fixed intensity. For better test utilization I suggest using some intelligence from production.<\/span><\/p>\n<p><span style=\"font-weight: 400\">There were three main simulation types that were used in performance tests. Of course your limits end where your imagination ends, so never hesitate to experiment.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Aftertaste<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Let\u2019s summarize. I\u2019ve talked about two big parts of the performance test: its infrastructure and its internal logic. Thanks for reading my whole stream of consciousness! I hope this material was useful and if you were thinking about starting performance testing on your project, you have a better understanding of what to do after this little reading.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Highlights\u00a0 Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0 His team created its own performance testing tool.\u00a0 Stanislav shares insights on how the architecture of the tool was built and describes the entire process of the tool&#8217;s creation. Introduction Hi, my name is Stas (but you can call me Stan, if you like it &#8230;<\/p>\n","protected":false},"author":1227,"featured_media":57970,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18885],"tags":[43346],"class_list":["post-57958","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ringcentral-newsdesk","tag-working-at-rc-bulgaria"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v19.3 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Creating in-house performance testing tool | RingCentral Blog<\/title>\n<meta name=\"description\" content=\"Highlights\u00a0 Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0 His team created its own performance testing tool.\u00a0 Stanislav shares Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0His team created its own performance testing tool.\u00a0In this article Stanislav shares insights on how the architecture of the tool was built and describes the entire process of the tool&#039;s creation.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.ringcentral.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating in-house performance testing tool\" \/>\n<meta property=\"og:description\" content=\"Highlights\u00a0 Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0 His team created its own performance testing tool.\u00a0 Stanislav shares Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0His team created its own performance testing tool.\u00a0In this article Stanislav shares insights on how the architecture of the tool was built and describes the entire process of the tool&#039;s creation.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.ringcentral.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/\" \/>\n<meta property=\"og:site_name\" content=\"RingCentral Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ringcentral\" \/>\n<meta property=\"article:published_time\" content=\"2024-09-20T10:35:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-05-29T10:20:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.ringcentral.com\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png\" \/>\n\t<meta property=\"og:image:width\" content=\"930\" \/>\n\t<meta property=\"og:image:height\" content=\"700\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Stanislav Suslov\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ringcentral\" \/>\n<meta name=\"twitter:site\" content=\"@ringcentral\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Stanislav Suslov\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#article\",\"isPartOf\":{\"@id\":\"\/us\/en\/blog\/creating-in-house-performance-testing-tool\/\"},\"author\":{\"name\":\"Stanislav Suslov\",\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#\/schema\/person\/55359cc52e90cdc19d4b56095fe034ee\"},\"headline\":\"Creating in-house performance testing tool\",\"datePublished\":\"2024-09-20T10:35:34+00:00\",\"dateModified\":\"2025-05-29T10:20:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"\/us\/en\/blog\/creating-in-house-performance-testing-tool\/\"},\"wordCount\":2629,\"publisher\":{\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#primaryimage\"},\"thumbnailUrl\":\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png\",\"keywords\":[\"Working at RC Bulgaria\"],\"articleSection\":[\"Company news &amp; culture\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"\/us\/en\/blog\/creating-in-house-performance-testing-tool\/\",\"url\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/\",\"name\":\"Creating in-house performance testing tool | RingCentral Blog\",\"isPartOf\":{\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#primaryimage\"},\"thumbnailUrl\":\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png\",\"datePublished\":\"2024-09-20T10:35:34+00:00\",\"dateModified\":\"2025-05-29T10:20:43+00:00\",\"description\":\"Highlights\u00a0 Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0 His team created its own performance testing tool.\u00a0 Stanislav shares Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0His team created its own performance testing tool.\u00a0In this article Stanislav shares insights on how the architecture of the tool was built and describes the entire process of the tool's creation.\",\"breadcrumb\":{\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#primaryimage\",\"url\":\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png\",\"contentUrl\":\"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png\",\"width\":930,\"height\":700},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"\/us\/en\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Creating in-house performance testing tool\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#website\",\"url\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/\",\"name\":\"RingCentral Blog\",\"description\":\"Intelligent Communications\",\"publisher\":{\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#organization\",\"name\":\"RingCentral\",\"url\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#\/schema\/logo\/image\/\",\"url\":\"\/us\/en\/blog\/wp-content\/uploads\/2025\/04\/ringcentral-logo.png\",\"contentUrl\":\"\/us\/en\/blog\/wp-content\/uploads\/2025\/04\/ringcentral-logo.png\",\"width\":2048,\"height\":309,\"caption\":\"RingCentral\"},\"image\":{\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/ringcentral\",\"https:\/\/x.com\/ringcentral\",\"https:\/\/www.linkedin.com\/company\/ringcentral\/\",\"https:\/\/www.instagram.com\/ringcentral\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#\/schema\/person\/55359cc52e90cdc19d4b56095fe034ee\",\"name\":\"Stanislav Suslov\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/c8c882f8bfb0da7fb8c17f21e79c94f460d8548a8b1bb6d24c08be3e2e86bc62?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c8c882f8bfb0da7fb8c17f21e79c94f460d8548a8b1bb6d24c08be3e2e86bc62?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c8c882f8bfb0da7fb8c17f21e79c94f460d8548a8b1bb6d24c08be3e2e86bc62?s=96&d=mm&r=g\",\"caption\":\"Stanislav Suslov\"},\"description\":\"Senior QA Engineer at RingCentral Bulgaria. Mainly focused on testing back features and fixes. Interested in load testing, improving the stability and efficiency of services.\",\"url\":\"\/us\/en\/blog\/author\/stanislav-suslov\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Creating in-house performance testing tool | RingCentral Blog","description":"Highlights\u00a0 Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0 His team created its own performance testing tool.\u00a0 Stanislav shares Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0His team created its own performance testing tool.\u00a0In this article Stanislav shares insights on how the architecture of the tool was built and describes the entire process of the tool's creation.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.ringcentral.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/","og_locale":"en_US","og_type":"article","og_title":"Creating in-house performance testing tool","og_description":"Highlights\u00a0 Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0 His team created its own performance testing tool.\u00a0 Stanislav shares Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0His team created its own performance testing tool.\u00a0In this article Stanislav shares insights on how the architecture of the tool was built and describes the entire process of the tool's creation.","og_url":"https:\/\/www.ringcentral.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/","og_site_name":"RingCentral Blog","article_publisher":"https:\/\/www.facebook.com\/ringcentral","article_published_time":"2024-09-20T10:35:34+00:00","article_modified_time":"2025-05-29T10:20:43+00:00","og_image":[{"width":930,"height":700,"url":"https:\/\/www.ringcentral.com\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png","type":"image\/png"}],"author":"Stanislav Suslov","twitter_card":"summary_large_image","twitter_creator":"@ringcentral","twitter_site":"@ringcentral","twitter_misc":{"Written by":"Stanislav Suslov","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#article","isPartOf":{"@id":"\/us\/en\/blog\/creating-in-house-performance-testing-tool\/"},"author":{"name":"Stanislav Suslov","@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#\/schema\/person\/55359cc52e90cdc19d4b56095fe034ee"},"headline":"Creating in-house performance testing tool","datePublished":"2024-09-20T10:35:34+00:00","dateModified":"2025-05-29T10:20:43+00:00","mainEntityOfPage":{"@id":"\/us\/en\/blog\/creating-in-house-performance-testing-tool\/"},"wordCount":2629,"publisher":{"@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#organization"},"image":{"@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#primaryimage"},"thumbnailUrl":"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png","keywords":["Working at RC Bulgaria"],"articleSection":["Company news &amp; culture"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"\/us\/en\/blog\/creating-in-house-performance-testing-tool\/","url":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/","name":"Creating in-house performance testing tool | RingCentral Blog","isPartOf":{"@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#primaryimage"},"image":{"@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#primaryimage"},"thumbnailUrl":"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png","datePublished":"2024-09-20T10:35:34+00:00","dateModified":"2025-05-29T10:20:43+00:00","description":"Highlights\u00a0 Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0 His team created its own performance testing tool.\u00a0 Stanislav shares Stanislav is a Senior Quality Assurance Engineer at RingCentral.\u00a0His team created its own performance testing tool.\u00a0In this article Stanislav shares insights on how the architecture of the tool was built and describes the entire process of the tool's creation.","breadcrumb":{"@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#primaryimage","url":"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png","contentUrl":"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png","width":930,"height":700},{"@type":"BreadcrumbList","@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/creating-in-house-performance-testing-tool\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"\/us\/en\/blog\/"},{"@type":"ListItem","position":2,"name":"Creating in-house performance testing tool"}]},{"@type":"WebSite","@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#website","url":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/","name":"RingCentral Blog","description":"Intelligent Communications","publisher":{"@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#organization","name":"RingCentral","url":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#\/schema\/logo\/image\/","url":"\/us\/en\/blog\/wp-content\/uploads\/2025\/04\/ringcentral-logo.png","contentUrl":"\/us\/en\/blog\/wp-content\/uploads\/2025\/04\/ringcentral-logo.png","width":2048,"height":309,"caption":"RingCentral"},"image":{"@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/ringcentral","https:\/\/x.com\/ringcentral","https:\/\/www.linkedin.com\/company\/ringcentral\/","https:\/\/www.instagram.com\/ringcentral"]},{"@type":"Person","@id":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/#\/schema\/person\/55359cc52e90cdc19d4b56095fe034ee","name":"Stanislav Suslov","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c8c882f8bfb0da7fb8c17f21e79c94f460d8548a8b1bb6d24c08be3e2e86bc62?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c8c882f8bfb0da7fb8c17f21e79c94f460d8548a8b1bb6d24c08be3e2e86bc62?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c8c882f8bfb0da7fb8c17f21e79c94f460d8548a8b1bb6d24c08be3e2e86bc62?s=96&d=mm&r=g","caption":"Stanislav Suslov"},"description":"Senior QA Engineer at RingCentral Bulgaria. Mainly focused on testing back features and fixes. Interested in load testing, improving the stability and efficiency of services.","url":"\/us\/en\/blog\/author\/stanislav-suslov\/"}]}},"rc_img_url":"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/Creating_in-house_performance_testing_tool_930x700.png","rcblog_by_author":"<a href=\"\/us\/en\/blog\/author\/stanislav-suslov\/amp\" data-dl-events-click=\"true\" data-dl-element=\"link\"><span class=\"image\"><img src=\"https:\/\/secure.gravatar.com\/avatar\/c8c882f8bfb0da7fb8c17f21e79c94f460d8548a8b1bb6d24c08be3e2e86bc62?s=96&d=mm&r=g\" alt=\"\" width=\"30\" height=\"30\" layout=\"fixed\"><\/img><\/span><span class=\"by-author-name\">Stanislav Suslov<\/span><\/a>","rc_author_full_name":"Stanislav Suslov","rc_author_avatar":"\/us\/en\/blog\/wp-content\/uploads\/2024\/09\/stanislav.suslov2.jpg","rc_author_link":"\/us\/en\/blog\/author\/stanislav-suslov\/amp","rc_post_categories":"<a href=\"\/us\/en\/blog\/category\/trending\/ringcentral-newsdesk\/amp\">Company news &amp; culture<\/a>","amp_link":"\/us\/en\/blog\/creating-in-house-performance-testing-tool\/amp","excerpt_title":"Creating in-house performance testing tool","_links":{"self":[{"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/posts\/57958","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/users\/1227"}],"replies":[{"embeddable":true,"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/comments?post=57958"}],"version-history":[{"count":0,"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/posts\/57958\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/media\/57970"}],"wp:attachment":[{"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/media?parent=57958"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/categories?post=57958"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/newrcblog.wpengine.com\/us\/en\/blog\/wp-json\/wp\/v2\/tags?post=57958"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}