{"id":2380,"date":"2015-11-08T08:00:33","date_gmt":"2015-11-08T16:00:33","guid":{"rendered":"https:\/\/redfindevelop.wpengine.com\/blog\/devblog\/?p=2380"},"modified":"2020-10-05T13:12:02","modified_gmt":"2020-10-05T20:12:02","slug":"load-testing-with-taurus","status":"publish","type":"post","link":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/","title":{"rendered":"Load Testing with Taurus"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">When you&#8217;re developing new functionality on an existing website, especially on a hot new young fresh startup like Redfin, you can get really excited about <\/span><a href=\"http:\/\/startupquote.com\/post\/1624569753\"><span style=\"font-weight: 400;\">moving fast and breaking things<\/span><\/a><span style=\"font-weight: 400;\"> and really break things. I want to spend a little bit of time reflecting on a time that I broke things, and how load testing with <\/span><a href=\"http:\/\/gettaurus.org\/\"><span style=\"font-weight: 400;\">Taurus<\/span><\/a><span style=\"font-weight: 400;\"> helped me fix it.<\/span><\/p>\n<h1><span style=\"font-weight: 400;\">What happened<\/span><\/h1>\n<p><span style=\"font-weight: 400;\">A couple of months\u00a0ago, I shipped a new feature to include links on our listing and property pages (<\/span><a href=\"https:\/\/redfin.com\/WA\/Seattle\/116-Warren-Ave-N-98109\/home\/2095810\"><span style=\"font-weight: 400;\">an example<\/span><\/a><span style=\"font-weight: 400;\">). The change was mostly intended for <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Search_engine_marketing\"><span style=\"font-weight: 400;\">SEM<\/span><\/a><span style=\"font-weight: 400;\">, to help search engines understand the relationship between various pages that we have on <\/span><a href=\"https:\/\/redfin.com\/blog\/\"><span style=\"font-weight: 400;\">Redfin.com<\/span><\/a><span style=\"font-weight: 400;\">. Usually, when we ship a new feature, we have it behind a <\/span><a href=\"http:\/\/martinfowler.com\/bliki\/FeatureToggle.html\"><span style=\"font-weight: 400;\">runtime feature toggle<\/span><\/a><span style=\"font-weight: 400;\"> we call Bouncer, but I shipped some of my debugging code into production:<\/span><\/p>\n<pre class=\"lang:js decode:true\">if (Bouncer.isOn(Feature.SMART_INTERLINKING) || true) {\n  \/\/ CRUSH THE DB!!!\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Usually, we would have gradually dialed up the feature, and discovered slowly but surely that the load this feature adds to our <\/span><a href=\"http:\/\/www.postgresql.org\/\"><span style=\"font-weight: 400;\">PostgreSQL cluster<\/span><\/a><span style=\"font-weight: 400;\"> is untenable, but because of my debugging code, we saw the new controller go from not existing to taking a startling 15% of our total database SQL execution time overnight. I pushed a hotfix, and then had to quickly pull together a long-term solution. Because of the high visibility of the bug, I had a lot of developers suggesting less expensive ways to query our database, and since the &#8220;later&#8221; had come in my plan to <\/span><a href=\"http:\/\/c2.com\/cgi\/wiki?OptimizeLater\"><span style=\"font-weight: 400;\">Optimize Later<\/span><\/a><span style=\"font-weight: 400;\">, it was important to come up with the solution that would put the least load on the database and return results blazingly fast.<\/span><\/p>\n<h1><span style=\"font-weight: 400;\">What\u00a0I tested<\/span><\/h1>\n<p><span style=\"font-weight: 400;\">By the end of my initial investigation, I had come up with 5 different solutions for how I could retrieve the data I needed from the database, some of which used a pre-computed <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Junction_table\"><span style=\"font-weight: 400;\">mapping table<\/span><\/a><span style=\"font-weight: 400;\">, some of which used <\/span><a href=\"http:\/\/postgis.net\/documentation\"><span style=\"font-weight: 400;\">GIS queries<\/span><\/a><span style=\"font-weight: 400;\">, some of which used <\/span><a href=\"https:\/\/docs.jboss.org\/hibernate\/orm\/3.3\/reference\/en-US\/html\/querysql.html\"><span style=\"font-weight: 400;\">native SQL<\/span><\/a><span style=\"font-weight: 400;\">, some of which used <\/span><a href=\"https:\/\/docs.jboss.org\/hibernate\/orm\/3.3\/reference\/en-US\/html\/querycriteria.html\"><span style=\"font-weight: 400;\">criteria queries<\/span><\/a><span style=\"font-weight: 400;\">. I added 5 separate methods to my <\/span><a href=\"http:\/\/docs.spring.io\/spring-framework\/docs\/current\/spring-framework-reference\/html\/mvc.html\"><span style=\"font-weight: 400;\">Spring MVC<\/span><\/a><span style=\"font-weight: 400;\"> controller:<\/span><\/p>\n<pre class=\"lang:java decode:true\">@Controller\npublic class ExpensiveComputationController {\n\n  private @Inject ExpensiveComputationHelper helper;\n\n  @RequestMapping(value = \"\/api\/variant1\", method = RequestMethod.GET)\n  public doExpensiveComputation1() {\n    return helper.expensiveVariant1();\n  }\n\n  @RequestMapping(value = \"\/api\/variant2\", method = RequestMethod.GET)\n  public doExpensiveComputation2() {\n    return helper.expensiveVariant2();\n  }\n\n\/\/ snip\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Then, I needed to load test each of the variants. My first instinct was to use <\/span><a href=\"http:\/\/curl.haxx.se\/docs\/manpage.html\"><span style=\"font-weight: 400;\">cURL<\/span><\/a><span style=\"font-weight: 400;\"> to time the total time used to return a response. I found <\/span><a href=\"https:\/\/josephscott.org\/archives\/2011\/10\/timing-details-with-curl\/\"><span style=\"font-weight: 400;\">this fantastic article<\/span><\/a><span style=\"font-weight: 400;\"> on how to time curl requests, and got a reasonable bellwether for how long each of variant takes:<\/span><\/p>\n<pre class=\"lang:sh decode:true\">curl -w \"ntime: %{time_total}sn\" https:\/\/redfintest.com\/api\/variant1<\/pre>\n<p><span style=\"font-weight: 400;\">However, sending a single request at a time is not a particularly representative statistic for how effective a given method or query functions because a real production database would never be running just one query &#8212; for instance, <\/span><a href=\"https:\/\/redfin.com\/blog\"><span style=\"font-weight: 400;\">Redfin<\/span><\/a><span style=\"font-weight: 400;\"> has thousands of active, concurrent users while I\u2019m writing this article. To mimic this behavior, we needed to use a <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Load_testing#Load_testing_tools\"><span style=\"font-weight: 400;\">load generator<\/span><\/a><span style=\"font-weight: 400;\"> to generate a lot of concurrent requests to simulate a real-world-like test. There are <\/span><a href=\"http:\/\/alternativeto.net\/tag\/load-testing\/\"><span style=\"font-weight: 400;\">a lot of load generation tools available<\/span><\/a><span style=\"font-weight: 400;\">, like <\/span><a href=\"https:\/\/www.joedog.org\/siege-home\/\"><span style=\"font-weight: 400;\">Siege<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"http:\/\/jmeter.apache.org\/\"><span style=\"font-weight: 400;\">Apache JMeter<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"http:\/\/grinder.sourceforge.net\/\"><span style=\"font-weight: 400;\">The Grinder<\/span><\/a><span style=\"font-weight: 400;\">, and <\/span><a href=\"http:\/\/gatling.io\/#\/\"><span style=\"font-weight: 400;\">Gatling<\/span><\/a><span style=\"font-weight: 400;\">. \u00a0At Redfin, we recommend <\/span><a href=\"https:\/\/www.joedog.org\/siege-home\/\"><span style=\"font-weight: 400;\">Siege<\/span><\/a><span style=\"font-weight: 400;\"> for load testing major architectural changes, since solutions like <\/span><a href=\"http:\/\/jmeter.apache.org\/\"><span style=\"font-weight: 400;\">Apache JMeter<\/span><\/a><span style=\"font-weight: 400;\"> just can\u2019t generate enough load to replicate real production-like traffic, but I hoped to find a solution that was a little easier to use. \u00a0I saw <\/span><a href=\"http:\/\/gettaurus.org\/docs\/Home\/?utm_source=BM&amp;utm_medium=BM_blog&amp;utm_campaign=Taurus\"><span style=\"font-weight: 400;\">Taurus<\/span><\/a><span style=\"font-weight: 400;\">, which claimed I could write my tests once and then run them using JMeter AND Grinder AND Gatling by adding a <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Domain-specific_language\"><span style=\"font-weight: 400;\">DSL<\/span><\/a><span style=\"font-weight: 400;\"> for the supported tools! Sweet!<\/span><\/p>\n<h1><span style=\"font-weight: 400;\">How I tested it<\/span><\/h1>\n<p><span style=\"font-weight: 400;\">Getting started with Taurus couldn&#8217;t have been easier. I followed <\/span><a href=\"https:\/\/blazemeter.com\/blog\/taurus-new-star-test-automation-tools-constellation\"><span style=\"font-weight: 400;\">this article<\/span><\/a><span style=\"font-weight: 400;\">, but I&#8217;ll also include the CliffNotes\u00ae version here. I started out by installing the dependency:<\/span><\/p>\n<pre class=\"lang:sh decode:true\">sudo pip install bzt<\/pre>\n<p><span style=\"font-weight: 400;\">Then I created my test:<\/span><\/p>\n<pre class=\"lang:yaml decode:true\">---\nexecution:\n\u00a0concurrency: 25\n\u00a0hold-for: 5m\n\u00a0ramp-up: 1m\n\u00a0scenario:\n\u00a0\u00a0\u00a0requests:\n\u00a0\u00a0\u00a0\u00a0\u00a0- url: https:\/\/redfintest.com\/api\/variant1?param1=val1&amp;param2=val2\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0method: GET\n\u00a0\u00a0\u00a0\u00a0\u00a0- url: https:\/\/redfintest.com\/api\/variant1?param1=val3&amp;param2=val4\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0method: GET\n\u00a0\u00a0\u00a0\u00a0\u00a0...snip...<\/pre>\n<p><span style=\"font-weight: 400;\">Let\u2019s break that down line-by-line:<\/span><\/p>\n<pre class=\"lang:yaml decode:true\">---\nexecution:\n    concurrency: 25<\/pre>\n<p><span style=\"font-weight: 400;\">I generated load for 25 concurrent users. This isn\u2019t a particularly realistic number, but since I was generating the load from my laptop, and testing a locally-running process also running on my laptop, I was concerned that setting concurrent users too high would melt my laptop into my desk.<\/span><\/p>\n<pre class=\"lang:yaml decode:true\">ramp-up: 1m<\/pre>\n<p><span style=\"font-weight: 400;\">The test gives 1 minute of ramp-up time to Taurus to get 25 concurrent users making requests so that once the test starts, there are 25 actual concurrent users making requests. It&#8217;s much like how in stock car racing the race doesn\u2019t start from a cold stop, but instead the pack circles the track for a few laps before the race starts.<\/span><\/p>\n<pre class=\"lang:yaml decode:true\">hold-for: 5m\nscenario:\n  requests:\n    - url: https:\/\/redfintest.com\/api\/variant1?param1=val1&amp;param2=val2\n      method: GET\n    - url: https:\/\/redfintest.com\/api\/variant1?param1=val3&amp;param2=val4\n      method: GET<\/pre>\n<p><span style=\"font-weight: 400;\">The test goes on for 5 minutes of testing, and, in this example, each user makes two requests in succession, to https:\/\/redfintest.com\/api\/variant1, before creating a new user and starting from the beginning.<\/span><\/p>\n<p>Then, I fired up the load test:<\/p>\n<pre class=\"lang:sh decode:true\">bzt scenario.yml<\/pre>\n<p><span style=\"font-weight: 400;\">And was so very pleased &#8212; all in all, from deciding to use Taurus to having the results of a real load test took me less than a half hour, and 6 minutes of that was spent actually running the test. Taurus installed all the JMeter dependencies for me, and after a short wait, I was greeted with a super awesome-looking terminal of charts and graphs and numbers:<\/span><\/p>\n<p><a href=\"https:\/\/redfin.com\/blog\/devblog\/wp-content\/uploads\/sites\/3\/2015\/09\/Screen-Shot-2015-09-10-at-4.25.14-PM.png\"><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone size-full wp-image-2381\" src=\"https:\/\/redfin.com\/blog\/devblog\/wp-content\/uploads\/sites\/3\/2015\/09\/Screen-Shot-2015-09-10-at-4.25.14-PM.png\" alt=\"Screen Shot 2015-09-10 at 4.25.14 PM\" width=\"2880\" height=\"1760\" \/><\/a><\/p>\n<h1><span style=\"font-weight: 400;\">How I groked the results<\/span><\/h1>\n<p><span style=\"font-weight: 400;\">Taurus gave me lots of fantastic data about the amount of time it took to return results under load. \u00a0The console output for one of the variants looks like this:<\/span><\/p>\n<pre class=\"lang:sh decode:true\">16:26:59 INFO: Samples count: 23740, 0.00% failures\n\n16:26:59 INFO: Average times: total 0.348, latency 0.348, connect 0.000\n\n16:26:59 INFO: Percentile 0.0%: 0.062\n16:26:59 INFO: Percentile 50.0%: 0.317\n16:26:59 INFO: Percentile 90.0%: 0.508\n16:26:59 INFO: Percentile 95.0%: 0.670\n16:26:59 INFO: Percentile 99.0%: 0.876\n16:26:59 INFO: Percentile 99.9%: 1.227\n16:26:59 INFO: Percentile 100.0%: 1.750<\/pre>\n<p><span style=\"font-weight: 400;\">The top-line number, the samples count, was a reasonable approximation for how efficient a given variant was, since being able to process more requests in a fixed amount of time with a fixed number of concurrent requests means that each request must have been faster on average.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">And all in all, the table of results that came out:<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><\/td>\n<td><span style=\"font-weight: 400;\">1<\/span><\/td>\n<td><span style=\"font-weight: 400;\">2<\/span><\/td>\n<td><span style=\"font-weight: 400;\">3<\/span><\/td>\n<td><span style=\"font-weight: 400;\">4<\/span><\/td>\n<td><span style=\"font-weight: 400;\">5<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">samples<\/span><\/td>\n<td><span style=\"font-weight: 400;\">35,299<\/span><\/td>\n<td><span style=\"font-weight: 400;\">35,382<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #6aa84f;\">37,970<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #cc0000;\">4,443<\/span><\/td>\n<td><span style=\"font-weight: 400;\">37,669<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">mean<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.234s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.234s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #6aa84f;\">0.218s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #cc0000;\">1.868s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.219s<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">p0<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.039s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.045s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #6aa84f;\">0.029s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #cc0000;\">0.078s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.040s<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">p50<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.220s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.224s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #6aa84f;\">0.207s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #cc0000;\">1.794s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.210s<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">p90<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.301s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.293s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #6aa84f;\">0.287s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #cc0000;\">2.814s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.282s<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">p95<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.351s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.327s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.333s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #cc0000;\">3.225s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #6aa84f;\">0.322s<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">p99.5<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.718s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.703s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.695s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #cc0000;\">4.131s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #6aa84f;\">0.689s<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">p99.9<\/span><\/td>\n<td><span style=\"font-weight: 400;\">1.182s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">1.683s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #6aa84f;\">0.849s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #cc0000;\">5.577s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">0.961s<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">p100<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #6aa84f;\">1.722s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">3.296s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">2.049s<\/span><\/td>\n<td><span style=\"font-weight: 400; color: #cc0000;\">6.544s<\/span><\/td>\n<td><span style=\"font-weight: 400;\">2.041s<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400;\">But those numbers are only half of what I needed to know to make the right decision &#8212; it tells me how fast it is for customers, but not necessarily how much load we are producing on the database. To get at the database statistics was more complicated, but thanks to some work by some other teams here at Redfin, most of the heavy lifting had already been done for me. Here at Redfin we use a C Port of <\/span><a href=\"https:\/\/www.etsy.com\/\"><span style=\"font-weight: 400;\">Etsy&#8217;s<\/span><\/a> <a href=\"https:\/\/github.com\/etsy\/statsd\"><span style=\"font-weight: 400;\">StatsD<\/span><\/a><span style=\"font-weight: 400;\">, stored by <\/span><a href=\"https:\/\/github.com\/graphite-project\/carbon\"><span style=\"font-weight: 400;\">Carbon<\/span><\/a><span style=\"font-weight: 400;\">, displayed by <\/span><a href=\"https:\/\/github.com\/graphite-project\"><span style=\"font-weight: 400;\">Graphite<\/span><\/a><span style=\"font-weight: 400;\"> and collected by a <\/span><a href=\"http:\/\/docs.spring.io\/spring\/docs\/current\/javadoc-api\/org\/springframework\/web\/servlet\/HandlerInterceptor.html\"><span style=\"font-weight: 400;\">Spring interceptor<\/span><\/a><span style=\"font-weight: 400;\"> that sends data to StatsD every time we call the database. Through this magical setup, I was able to get at the second half of what I wanted to know without doing any additional setup &#8212; I just opened up my browser to the appropriate controller and voila!<\/span><br \/>\n<a href=\"https:\/\/redfin.com\/blog\/devblog\/wp-content\/uploads\/sites\/3\/2015\/09\/Screen-Shot-2015-09-11-at-5.41.18-PM.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-2382\" src=\"https:\/\/redfin.com\/blog\/devblog\/wp-content\/uploads\/sites\/3\/2015\/09\/Screen-Shot-2015-09-11-at-5.41.18-PM.png\" alt=\"Screen Shot 2015-09-11 at 5.41.18 PM\" width=\"2238\" height=\"1360\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">Note that the order of variants on the graph is 1, 2, 2, 4, 5, 3 because I initially ran variant 2 when I should have run variant 3. \u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Based on the results we got, it was easy to tell that if we deployed variant 3 in place of variant 4 (the version I initially deployed), we could expect for 90% of users to render the component in a tenth the time that we were serving this component. Oh, and of course I shipped with automated end-to-end tests using <\/span><a href=\"http:\/\/www.seleniumhq.org\/\"><span style=\"font-weight: 400;\">Selenium<\/span><\/a><span style=\"font-weight: 400;\"> to prevent pushing bad code again, but that\u2019s a post for another day.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you&#8217;re developing new functionality on an existing website, especially on a hot new young fresh startup like Redfin, you can get really excited about moving fast and breaking things and really break things. I want to spend a little bit of time reflecting on a time that I broke things, and how load testing [&hellip;]<\/p>\n","protected":false},"author":13177,"featured_media":42644,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[57],"tags":[],"dashboard":[],"coauthors":[],"class_list":["post-2380","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-company-news"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v24.7 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Load Testing with Taurus - Redfin Real Estate News<\/title>\n<meta name=\"description\" content=\"In which I use Load Testing to find and fix database hotspots using Taurus\" \/>\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.redfin.com\/news\/load-testing-with-taurus\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Load Testing with Taurus\" \/>\n<meta property=\"og:description\" content=\"In which I use Load Testing to find and fix database hotspots using Taurus\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/\" \/>\n<meta property=\"og:site_name\" content=\"Redfin Real Estate News\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/redfin\" \/>\n<meta property=\"article:published_time\" content=\"2015-11-08T16:00:33+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-10-05T20:12:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.redfin.com\/news\/wp-content\/uploads\/2015\/11\/Taurus.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2880\" \/>\n\t<meta property=\"og:image:height\" content=\"1760\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Doug Wade\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@redfin\" \/>\n<meta name=\"twitter:site\" content=\"@redfin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Doug Wade\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/\"},\"author\":{\"name\":\"Doug Wade\",\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#\\\/schema\\\/person\\\/ce8e1b698aeb1c41384c05ef5c97ddbc\"},\"headline\":\"Load Testing with Taurus\",\"datePublished\":\"2015-11-08T16:00:33+00:00\",\"dateModified\":\"2020-10-05T20:12:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/\"},\"wordCount\":1181,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.redfin.com/news\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/Taurus.png\",\"articleSection\":[\"Company News\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/#respond\"]}],\"copyrightYear\":\"2015\",\"copyrightHolder\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/\",\"url\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/\",\"name\":\"Load Testing with Taurus - Redfin Real Estate News\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.redfin.com/news\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/Taurus.png\",\"datePublished\":\"2015-11-08T16:00:33+00:00\",\"dateModified\":\"2020-10-05T20:12:02+00:00\",\"description\":\"In which I use Load Testing to find and fix database hotspots using Taurus\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.redfin.com/news\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/Taurus.png\",\"contentUrl\":\"https:\\\/\\\/www.redfin.com/news\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/Taurus.png\",\"width\":2880,\"height\":1760},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/load-testing-with-taurus\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.redfin.com/news\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Load Testing with Taurus\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#website\",\"url\":\"https:\\\/\\\/www.redfin.com/news\\\/\",\"name\":\"Redfin Real Estate News\",\"description\":\"The latest real estate news and research from technology-powered residential real estate company, Redfin.\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.redfin.com/news\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#organization\",\"name\":\"Redfin\",\"url\":\"https:\\\/\\\/www.redfin.com/news\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.redfin.com\\\/news\\\/wp-content\\\/uploads\\\/2020\\\/10\\\/Redfin-News-Logo.png\",\"contentUrl\":\"https:\\\/\\\/www.redfin.com\\\/news\\\/wp-content\\\/uploads\\\/2020\\\/10\\\/Redfin-News-Logo.png\",\"width\":1100,\"height\":235,\"caption\":\"Redfin\"},\"image\":{\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/redfin\",\"https:\\\/\\\/x.com\\\/redfin\",\"https:\\\/\\\/www.instagram.com\\\/redfinrealestate\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/redfin\",\"https:\\\/\\\/www.pinterest.com\\\/redfin\\\/\",\"https:\\\/\\\/en.wikipedia.org\\\/wiki\\\/Redfin\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.redfin.com/news\\\/#\\\/schema\\\/person\\\/ce8e1b698aeb1c41384c05ef5c97ddbc\",\"name\":\"Doug Wade\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1cb4c01b6eebf4bb7770e674ad8d70385f0e968d07b6345cd98a9c4f06020943?s=96&d=wp_user_avatar&r=g98695681813068d628dacc4b535b1a8d\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1cb4c01b6eebf4bb7770e674ad8d70385f0e968d07b6345cd98a9c4f06020943?s=96&d=wp_user_avatar&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1cb4c01b6eebf4bb7770e674ad8d70385f0e968d07b6345cd98a9c4f06020943?s=96&d=wp_user_avatar&r=g\",\"caption\":\"Doug Wade\"},\"description\":\"I'm a software developer at Redfin on the Platforms team. I'm a cyclist, soccer hooligan, and beer enthusiast.\",\"sameAs\":[\"https:\\\/\\\/plus.google.com\\\/106007864994207794940\"],\"url\":\"https:\\\/\\\/www.redfin.com/news\\\/author\\\/doug-waderedfin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Load Testing with Taurus - Redfin Real Estate News","description":"In which I use Load Testing to find and fix database hotspots using Taurus","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.redfin.com\/news\/load-testing-with-taurus\/","og_locale":"en_US","og_type":"article","og_title":"Load Testing with Taurus","og_description":"In which I use Load Testing to find and fix database hotspots using Taurus","og_url":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/","og_site_name":"Redfin Real Estate News","article_publisher":"https:\/\/www.facebook.com\/redfin","article_published_time":"2015-11-08T16:00:33+00:00","article_modified_time":"2020-10-05T20:12:02+00:00","og_image":[{"width":2880,"height":1760,"url":"https:\/\/www.redfin.com\/news\/wp-content\/uploads\/2015\/11\/Taurus.png","type":"image\/png"}],"author":"Doug Wade","twitter_card":"summary_large_image","twitter_creator":"@redfin","twitter_site":"@redfin","twitter_misc":{"Written by":"Doug Wade","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/#article","isPartOf":{"@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/"},"author":{"name":"Doug Wade","@id":"https:\/\/www.redfin.com\/news\/#\/schema\/person\/ce8e1b698aeb1c41384c05ef5c97ddbc"},"headline":"Load Testing with Taurus","datePublished":"2015-11-08T16:00:33+00:00","dateModified":"2020-10-05T20:12:02+00:00","mainEntityOfPage":{"@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/"},"wordCount":1181,"commentCount":0,"publisher":{"@id":"https:\/\/www.redfin.com\/news\/#organization"},"image":{"@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/#primaryimage"},"thumbnailUrl":"https:\/\/www.redfin.com\/news\/wp-content\/uploads\/2015\/11\/Taurus.png","articleSection":["Company News"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/#respond"]}],"copyrightYear":"2015","copyrightHolder":{"@id":"https:\/\/www.redfin.com\/news\/#organization"}},{"@type":"WebPage","@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/","url":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/","name":"Load Testing with Taurus - Redfin Real Estate News","isPartOf":{"@id":"https:\/\/www.redfin.com\/news\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/#primaryimage"},"image":{"@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/#primaryimage"},"thumbnailUrl":"https:\/\/www.redfin.com\/news\/wp-content\/uploads\/2015\/11\/Taurus.png","datePublished":"2015-11-08T16:00:33+00:00","dateModified":"2020-10-05T20:12:02+00:00","description":"In which I use Load Testing to find and fix database hotspots using Taurus","breadcrumb":{"@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/#primaryimage","url":"https:\/\/www.redfin.com\/news\/wp-content\/uploads\/2015\/11\/Taurus.png","contentUrl":"https:\/\/www.redfin.com\/news\/wp-content\/uploads\/2015\/11\/Taurus.png","width":2880,"height":1760},{"@type":"BreadcrumbList","@id":"https:\/\/www.redfin.com\/news\/load-testing-with-taurus\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.redfin.com\/news\/"},{"@type":"ListItem","position":2,"name":"Load Testing with Taurus"}]},{"@type":"WebSite","@id":"https:\/\/www.redfin.com\/news\/#website","url":"https:\/\/www.redfin.com\/news\/","name":"Redfin Real Estate News","description":"The latest real estate news and research from technology-powered residential real estate company, Redfin.","publisher":{"@id":"https:\/\/www.redfin.com\/news\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.redfin.com\/news\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.redfin.com\/news\/#organization","name":"Redfin","url":"https:\/\/www.redfin.com\/news\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.redfin.com\/news\/#\/schema\/logo\/image\/","url":"https:\/\/www.redfin.com\/news\/wp-content\/uploads\/2020\/10\/Redfin-News-Logo.png","contentUrl":"https:\/\/www.redfin.com\/news\/wp-content\/uploads\/2020\/10\/Redfin-News-Logo.png","width":1100,"height":235,"caption":"Redfin"},"image":{"@id":"https:\/\/www.redfin.com\/news\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/redfin","https:\/\/x.com\/redfin","https:\/\/www.instagram.com\/redfinrealestate\/","https:\/\/www.linkedin.com\/company\/redfin","https:\/\/www.pinterest.com\/redfin\/","https:\/\/en.wikipedia.org\/wiki\/Redfin"]},{"@type":"Person","@id":"https:\/\/www.redfin.com\/news\/#\/schema\/person\/ce8e1b698aeb1c41384c05ef5c97ddbc","name":"Doug Wade","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/1cb4c01b6eebf4bb7770e674ad8d70385f0e968d07b6345cd98a9c4f06020943?s=96&d=wp_user_avatar&r=g98695681813068d628dacc4b535b1a8d","url":"https:\/\/secure.gravatar.com\/avatar\/1cb4c01b6eebf4bb7770e674ad8d70385f0e968d07b6345cd98a9c4f06020943?s=96&d=wp_user_avatar&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1cb4c01b6eebf4bb7770e674ad8d70385f0e968d07b6345cd98a9c4f06020943?s=96&d=wp_user_avatar&r=g","caption":"Doug Wade"},"description":"I'm a software developer at Redfin on the Platforms team. I'm a cyclist, soccer hooligan, and beer enthusiast.","sameAs":["https:\/\/plus.google.com\/106007864994207794940"],"url":"https:\/\/www.redfin.com\/news\/author\/doug-waderedfin-com\/"}]}},"_links":{"self":[{"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/posts\/2380","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/users\/13177"}],"replies":[{"embeddable":true,"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/comments?post=2380"}],"version-history":[{"count":0,"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/posts\/2380\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/media\/42644"}],"wp:attachment":[{"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/media?parent=2380"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/categories?post=2380"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/tags?post=2380"},{"taxonomy":"dashboard","embeddable":true,"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/dashboard?post=2380"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.redfin.com\/news\/wp-json\/wp\/v2\/coauthors?post=2380"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}