Understanding variability in Heroku dyno performance

Thu Apr 15, 2021, 3080 Words

Heroku is a great platform if your app conforms to their expectations, but their dyno abstraction is somewhat leaky. It is surprisingly easy to deploy an application that behaves differently than you’d expect despite their documentation’s warnings about shared CPUs. In this post, I share some research on the performance/behavior of their various dyno classes and how I think about selecting dynos for different workloads.

If you’re familiar with Heroku’s platform, I suggest skipping ahead to exploring CPU-intensive workloads. The information in this post comes from a combination of my experience using Heroku and their documentation. I do not have any specific or privileged knowledge of how Heroku works, nor have I ever worked at Herkou.

Platform overview

Heroku is one of, if not the, original platform-as-a-service vendors. The platform was originally designed to host Ruby on Rails applications that conformed to the 12 Factor App. As long as I’ve been using the platform it has had strong opinions about how applications should be architected and offered an incredible developer experience if you say within the bounds. Heroku is essentially a container orchestration platform, and while they started by building containers automatically based on Git pushes - albeit for a limited number of languages - these days they also offer direct support for Docker containers. As a result, you can deploy any stack you want.

While they may be unfamiliar initially, their in-house abstractions map nicely onto more familiar - or at least more thoroughly documented - concepts from Docker. A new Git push creates what’s called a Slug, which is effectively the same thing as a Docker image. Both slugs and images are compressed tarballs containing the files necessary to run a particular command on a Linux kernel. Unlike Docker images, which consist of many compressed layers stacked on top of one another, a slug does not have layers.

When you run a Docker image as a container, the image is unpacked by a Docker host and executed. By default, Docker is a single-machine tool, so running containers on a cluster of machines requires an orchestrator like Docker Swarm or Kubernetes. Part of Heroku’s value proposition to developers is that they handle all of the orchestration & cluster management via their dyno manager. Like other orchestrators, the dyno manager is responsible for container placement and management - making sure dynos restart after a crash, have their log drains attached, etc…

Within Heroku, there are two distinct runtimes: Common Runtime and Private Spaces. The Common Runtime (CR) is a multi-tenant cluster running in AWS us-east-1 or an AWS EU zone. Private Spaces (PS) provides stronger isolation guarantees by essentially being a VPC within one of 8 different AWS regions. The two runtimes are quite different and optimize for different use cases. CR is intended to be highly responsive to creating new applications and dynos, while PS is meant for longer-running processes that can afford slower startup times. All of my experience is with CR, and that is what I’ll be referring to as Heroku throughout the remainder of this post.

As a multi-tenant environment, Heroku’s CR maintains a sizable cluster of machines in AWS which it uses to allocate new dynos as necessary. Heroku allows horizontally scaling applications and makes a best effort to allocate different dynos for the same application into different availability zones, providing some “free” redundancy. Additionally, because they have a large cluster of machines up and running at all times, allocating the marginal dyno is typically extremely fast because it doesn’t involve allocating any additional nodes to the cluster. In other words, the CR provides fast startup times for new dynos because the majority of the dynos running are sharing time with dynos from other customers. I say majority rather than all dynos because after a certain price tier within the CR dynos are allocated on dedicated hardware. Whether the machine itself is dedicated to the dyno or whether CPUs are pinned to a particular container is an implementation detail of the platform that I’ll explore later.

Ramifications of timesharing in the cloud

Cloud computing is all about running giant clusters of commodity hardware and renting time on them to users. The main reason to prefer commodity hardware over the more exotic machines used for high-performance clusters is their cost; cloud vendors purchase a variety of relatively inexpensive machines & abstract away the differences between them. As a user of cloud machines, you’re typically buying access to a virtual machine running atop some of this commodity hardware - although many vendors have begun offering bare-metal instances. That’s great, but it does mean that there is some variability in the machine’s performance because of variations in the underlying hardware. VMs running on older hardware may perform differently than those running new hardware, even if they’re the same instance class. Plus, the processes will be running on a VM rather than bare metal, so there will be an imperceptible (for most applications) performance hit from that.

Using cloud machines rather than hosting your own is deciding that the increased variability in machine performance is worth the increased ease with which instances are provisioned and managed. Choosing to use a PaaS rather than an IaaS is like making that decision twice. Not only are you choosing to outsource managing the physical machines to a cloud provider, but you’re also choosing to outsource managing the cloud compute resources. That could be a great business decision, but it’s important to note that many PaaS providers build their orchestration infrastructure on top of cloud instances provided by vendors like AWS or GCP.

For multi-tenant nodes (also known as “timeshared”), this story gets more complicated and scheduling priority becomes very important. In a timeshared system, the CPU is shared between many processes, with each process getting some, but not necessarily equal CPU cycles. For PaaS providers, it’s in their best interest to cram as many containers as possible onto a given node in the cluster to maximize their profit. So something like Heroku’s CR dyno manager presumably looks at node utilization and tries to maintain the highest safe usage rate across each node in the cluster. As a result, containers running on those nodes need to contend with each other for resources, and their workloads can impact each other. This dramatically increases variability in CPU-bound workloads.

Heroku has multiple timeshared offerings (free, hobby, standard-1x, standard-2x) providing different performance characteristics depending on the tier. As a result, lower-tiered processes on the same cluster node receive less processor time than their more expensive peers. I’m unsure of the exact mechanism the Heroku uses to differentiate scheduling, but Docker allows passing memory & CPU restrictions to Docker run, so I imagine Heroku uses some combination of setpriority() and something like ulimit, rather than implementing something bespoke.

Exploring CPU-intensive workload variability

This post was inspired by highly variable response times in services running on shared Heroku dynos, particularly when parsing JSON. Parsing large blocks of JSON - multiple Mb - require translating raw bytes into in-memory data structures, which in turn requires many CPU cycles to move data back and forth from main-memory and perform the parsing logic. On a crowded shared Heroku node, regardless of whether you’re running a free or a standard-2x, you’re going to see a lot of variance in this type of workload. Unfortunately, I couldn’t find anything describing what was going on here.

On a certain level, not understanding what happens beneath Heroku’s abstractions is a feature rather than a bug. But, in the interest of uncovering a few more details, I ended up benchmarking Heroku with a CPU-intensive workload. I describe the benchmark in more detail at the end of this post, but essentially it performed 10k JSON deserializations for a large JSON file on each size dyno and collected some stats about them.

Each point in this scatter plot represents one batch of 100 JSON deserializations. The x axis represents median duration and y represents the variance within a single batch as measured by the gap between median and p90 parse times. The size of each point increases as the p90 duration for a sample increases. Taller cluster height indicates a wider variation between the median and p90 deserialization time; in other words how fat the tail for this group of samples was. As clusters widen, there is more variance in the median duration.

406080100120140160180200220240260median batch run (ms)26024022020018016014012010080604020gap between median and 90th percentile (ms)FreeHobbyStandard 1xStandard 2xPerformance-MPerformance-LLocal (MBP)Free median: 204.89035 min: 92.457149 max: 465.311805 p90: 334.153366 gap: 129.263016Free median: 200.256489 min: 93.415576 max: 619.274411 p90: 408.614709 gap: 208.35822Free median: 200.809722 min: 89.697006 max: 393.734792 p90: 303.36828 gap: 102.558558Free median: 188.894914 min: 91.873962 max: 424.265491 p90: 303.844512 gap: 114.949598Free median: 200.520502 min: 87.003645 max: 471.862789 p90: 326.613723 gap: 126.093221Free median: 200.019613 min: 88.801175 max: 505.954642 p90: 338.258684 gap: 138.239071Free median: 226.773245 min: 89.646333 max: 506.392871 p90: 345.099266 gap: 118.326021Free median: 222.353328 min: 93.091483 max: 444.529726 p90: 355.187094 gap: 132.833766Free median: 190.28487 min: 88.944001 max: 674.577251 p90: 381.384875 gap: 191.100005Free median: 218.321544 min: 91.403938 max: 488.252166 p90: 426.161313 gap: 207.839769Free median: 236.091773 min: 85.305364 max: 686.798359 p90: 408.490066 gap: 172.398293Free median: 198.42201 min: 88.302945 max: 490.421413 p90: 362.548368 gap: 164.126358Free median: 180.072051 min: 89.06527 max: 334.6999 p90: 261.476874 gap: 81.404823Free median: 175.939636 min: 90.952115 max: 335.670405 p90: 230.594941 gap: 54.655305Free median: 242.46716 min: 100.242414 max: 691.281932 p90: 482.118041 gap: 239.650881Free median: 211.632768 min: 92.419605 max: 447.389167 p90: 397.084476 gap: 185.451708Free median: 215.726038 min: 87.458309 max: 480.469221 p90: 399.783616 gap: 184.057578Free median: 202.556257 min: 85.171824 max: 363.154872 p90: 297.268378 gap: 94.712121Free median: 226.644622 min: 91.150276 max: 591.582701 p90: 378.811638 gap: 152.167016Free median: 186.513215 min: 92.839417 max: 727.823494 p90: 325.380349 gap: 138.867134Free median: 201.667728 min: 91.939333 max: 357.394639 p90: 303.148379 gap: 101.480651Free median: 191.049897 min: 92.336861 max: 392.002175 p90: 327.524344 gap: 136.474447Free median: 216.360983 min: 89.292037 max: 385.580183 p90: 302.797976 gap: 86.436993Free median: 184.350143 min: 94.123327 max: 283.072538 p90: 252.196018 gap: 67.845875Free median: 195.855648 min: 88.860222 max: 326.470694 p90: 270.923103 gap: 75.067455Free median: 185.490124 min: 86.117056 max: 491.829151 p90: 271.558181 gap: 86.068057Free median: 186.932857 min: 90.002779 max: 263.160075 p90: 241.347603 gap: 54.414746Free median: 194.150301 min: 94.071955 max: 350.74678 p90: 277.114554 gap: 82.964253Free median: 182.395592 min: 92.042159 max: 466.330795 p90: 310.663219 gap: 128.267627Free median: 191.000455 min: 88.856243 max: 328.738287 p90: 278.511909 gap: 87.511454Free median: 185.05779 min: 94.331183 max: 351.276923 p90: 271.63574 gap: 86.57795Free median: 163.384358 min: 87.461962 max: 643.526039 p90: 385.698705 gap: 222.314347Free median: 191.845816 min: 101.478918 max: 463.790108 p90: 309.751786 gap: 117.90597Free median: 263.648323 min: 113.266952 max: 595.488722 p90: 430.151732 gap: 166.503409Free median: 236.832086 min: 86.316143 max: 470.924413 p90: 376.49675 gap: 139.664664Free median: 223.320264 min: 87.76955 max: 861.480766 p90: 459.294848 gap: 235.974584Free median: 211.5757 min: 91.446359 max: 498.417061 p90: 331.111485 gap: 119.535785Free median: 212.508495 min: 91.440796 max: 553.23194 p90: 347.621393 gap: 135.112898Free median: 263.210329 min: 90.039427 max: 666.196266 p90: 510.911882 gap: 247.701553Free median: 165.03412 min: 81.592593 max: 494.553731 p90: 272.726882 gap: 107.692762Free median: 228.19856 min: 92.532214 max: 613.758544 p90: 385.905213 gap: 157.706653Free median: 211.017937 min: 88.668101 max: 496.689642 p90: 349.024644 gap: 138.006707Free median: 221.517418 min: 92.350162 max: 412.045679 p90: 337.666121 gap: 116.148703Free median: 204.308254 min: 96.357414 max: 451.174529 p90: 329.980878 gap: 125.672624Free median: 236.410601 min: 89.565784 max: 484.334189 p90: 354.201477 gap: 117.790876Free median: 206.179864 min: 85.854049 max: 494.172232 p90: 292.201066 gap: 86.021202Free median: 216.010012 min: 89.485679 max: 624.468771 p90: 464.386926 gap: 248.376914Free median: 223.31926 min: 100.157469 max: 549.738533 p90: 368.60703 gap: 145.28777Free median: 224.43353 min: 91.873043 max: 955.02591 p90: 491.419173 gap: 266.985643Free median: 164.597217 min: 90.035522 max: 323.544434 p90: 217.095049 gap: 52.497832Free median: 204.888078 min: 88.870752 max: 506.180397 p90: 324.082941 gap: 119.194863Free median: 182.285146 min: 91.344412 max: 334.966483 p90: 260.335057 gap: 78.049911Free median: 192.166433 min: 85.530625 max: 396.871096 p90: 304.300308 gap: 112.133875Free median: 189.962175 min: 88.420488 max: 711.012405 p90: 298.216814 gap: 108.254639Free median: 193.787129 min: 87.962534 max: 378.792726 p90: 270.79801 gap: 77.010881Free median: 198.835244 min: 98.920012 max: 333.121057 p90: 290.553407 gap: 91.718163Free median: 213.646066 min: 85.91367 max: 536.033994 p90: 334.481081 gap: 120.835015Free median: 209.220399 min: 87.538938 max: 391.103455 p90: 311.721723 gap: 102.501324Free median: 196.213922 min: 83.866494 max: 719.641526 p90: 324.905921 gap: 128.691999Free median: 186.463048 min: 116.457555 max: 386.126906 p90: 306.258005 gap: 119.794957Free median: 208.008118 min: 108.064082 max: 540.07295 p90: 381.60161 gap: 173.593492Free median: 207.976138 min: 85.868887 max: 559.850135 p90: 350.439331 gap: 142.463193Free median: 188.06098 min: 87.481239 max: 401.698717 p90: 289.928375 gap: 101.867395Free median: 183.059481 min: 85.144972 max: 497.730886 p90: 324.743981 gap: 141.6845Free median: 190.253135 min: 87.655207 max: 630.633067 p90: 289.248939 gap: 98.995804Free median: 253.995615 min: 91.899346 max: 760.845948 p90: 435.270367 gap: 181.274752Free median: 213.248056 min: 93.198976 max: 522.741673 p90: 373.69425 gap: 160.446194Free median: 203.786325 min: 91.43698 max: 466.052126 p90: 314.801042 gap: 111.014717Free median: 223.163694 min: 90.000939 max: 638.310479 p90: 385.797054 gap: 162.63336Free median: 254.730074 min: 89.315541 max: 463.513116 p90: 387.623875 gap: 132.893801Free median: 194.030135 min: 86.318218 max: 678.135912 p90: 345.453925 gap: 151.42379Free median: 245.74304 min: 90.149055 max: 962.597083 p90: 511.675251 gap: 265.932211Free median: 220.145884 min: 107.842229 max: 432.757203 p90: 289.407959 gap: 69.262075Free median: 195.715111 min: 86.842208 max: 507.681796 p90: 344.995809 gap: 149.280698Free median: 187.769178 min: 88.83747 max: 424.23906 p90: 329.098669 gap: 141.329491Free median: 181.429472 min: 89.429359 max: 400.295891 p90: 250.405419 gap: 68.975947Free median: 184.769781 min: 88.940212 max: 377.702489 p90: 282.357416 gap: 97.587635Free median: 175.472109 min: 108.076878 max: 331.860219 p90: 250.747321 gap: 75.275212Free median: 226.260471 min: 99.540135 max: 860.947576 p90: 382.508256 gap: 156.247785Free median: 229.487884 min: 86.219581 max: 650.912738 p90: 353.991031 gap: 124.503147Free median: 163.449097 min: 89.971596 max: 429.988196 p90: 285.524271 gap: 122.075174Free median: 214.553722 min: 83.92177 max: 495.128093 p90: 333.596686 gap: 119.042964Free median: 190.885501 min: 92.132 max: 346.778333 p90: 289.334932 gap: 98.449431Free median: 226.658496 min: 107.909555 max: 662.839927 p90: 452.268684 gap: 225.610188Free median: 160.672001 min: 82.938438 max: 300.961611 p90: 260.457373 gap: 99.785372Free median: 226.169986 min: 94.087384 max: 426.163287 p90: 371.547518 gap: 145.377532Free median: 192.45915 min: 87.384956 max: 398.7591 p90: 336.355605 gap: 143.896455Free median: 230.283151 min: 99.439565 max: 540.51386 p90: 389.029606 gap: 158.746455Free median: 238.718588 min: 86.553855 max: 491.691835 p90: 387.460708 gap: 148.74212Free median: 246.872636 min: 119.966319 max: 473.602743 p90: 382.344647 gap: 135.472011Free median: 247.560663 min: 99.471765 max: 527.362439 p90: 412.756283 gap: 165.19562Free median: 214.660081 min: 84.904994 max: 680.267033 p90: 464.455845 gap: 249.795764Free median: 208.907439 min: 85.212396 max: 461.04619 p90: 387.3244 gap: 178.416961Free median: 224.656418 min: 97.219373 max: 400.393415 p90: 333.084504 gap: 108.428086Free median: 197.366609 min: 89.601395 max: 520.774247 p90: 310.207664 gap: 112.841055Free median: 238.344029 min: 100.246743 max: 454.253868 p90: 340.387402 gap: 102.043373Hobby median: 164.502745 min: 86.48292 max: 311.143201 p90: 253.589146 gap: 89.086401Hobby median: 166.08663 min: 87.691863 max: 422.118042 p90: 285.102571 gap: 119.015941Hobby median: 162.753156 min: 82.080178 max: 584.221694 p90: 312.537089 gap: 149.783933Hobby median: 172.332903 min: 90.214126 max: 402.773315 p90: 252.507112 gap: 80.174209Hobby median: 159.781999 min: 91.049335 max: 250.337243 p90: 214.745014 gap: 54.963015Hobby median: 161.712196 min: 95.838122 max: 381.994339 p90: 265.354857 gap: 103.642661Hobby median: 165.436951 min: 90.574715 max: 412.901816 p90: 273.546325 gap: 108.109374Hobby median: 166.214359 min: 86.322909 max: 351.325093 p90: 239.415124 gap: 73.200765Hobby median: 177.613245 min: 87.161996 max: 361.150095 p90: 289.301482 gap: 111.688237Hobby median: 166.487971 min: 89.19194 max: 348.488203 p90: 235.553619 gap: 69.065648Hobby median: 161.991757 min: 83.451104 max: 321.154094 p90: 248.816582 gap: 86.824825Hobby median: 184.73792 min: 90.018596 max: 658.02023 p90: 294.887827 gap: 110.149907Hobby median: 160.411864 min: 88.646066 max: 395.867372 p90: 259.510369 gap: 99.098505Hobby median: 168.435378 min: 86.189733 max: 386.775991 p90: 263.408119 gap: 94.972741Hobby median: 159.829328 min: 82.449019 max: 358.990887 p90: 248.706807 gap: 88.877479Hobby median: 188.776104 min: 87.092928 max: 596.97546 p90: 386.737311 gap: 197.961207Hobby median: 165.067484 min: 82.928389 max: 551.263782 p90: 267.730697 gap: 102.663213Hobby median: 169.319717 min: 93.234949 max: 454.526908 p90: 350.974268 gap: 181.654551Hobby median: 166.7547 min: 87.841258 max: 474.009563 p90: 265.644429 gap: 98.889729Hobby median: 165.814435 min: 85.818631 max: 333.127855 p90: 262.614941 gap: 96.800506Hobby median: 173.257752 min: 72.821378 max: 449.418997 p90: 285.50061 gap: 112.242858Hobby median: 215.160283 min: 82.584877 max: 704.209155 p90: 425.010011 gap: 209.849728Hobby median: 117.45717 min: 52.832833 max: 252.843137 p90: 192.689558 gap: 75.232388Hobby median: 102.770703 min: 49.642431 max: 280.705074 p90: 171.794121 gap: 69.023418Hobby median: 91.145863 min: 47.277651 max: 208.796849 p90: 144.878153 gap: 53.73229Hobby median: 127.38408 min: 51.959262 max: 281.895594 p90: 219.677516 gap: 92.293436Hobby median: 107.068772 min: 60.327419 max: 208.677147 p90: 184.840713 gap: 77.771941Hobby median: 120.828477 min: 62.239659 max: 322.023181 p90: 207.361014 gap: 86.532537Hobby median: 80.209276 min: 41.435193 max: 147.381996 p90: 121.60246 gap: 41.393184Hobby median: 103.031366 min: 58.967429 max: 183.642952 p90: 144.669714 gap: 41.638348Hobby median: 80.802755 min: 43.128903 max: 177.316029 p90: 121.120173 gap: 40.317418Hobby median: 69.766683 min: 44.672257 max: 139.047304 p90: 93.467482 gap: 23.700799Hobby median: 75.949129 min: 46.945326 max: 131.696302 p90: 119.616859 gap: 43.66773Hobby median: 79.494493 min: 45.095053 max: 142.696624 p90: 110.393192 gap: 30.898699Hobby median: 96.563905 min: 49.279538 max: 170.321587 p90: 132.590499 gap: 36.026594Hobby median: 69.995317 min: 42.772973 max: 155.683484 p90: 102.682593 gap: 32.687276Hobby median: 74.775446 min: 41.4371 max: 136.851034 p90: 103.328667 gap: 28.553221Hobby median: 70.245727 min: 46.865204 max: 114.537892 p90: 99.344928 gap: 29.099201Hobby median: 87.097396 min: 51.406658 max: 183.077344 p90: 134.222448 gap: 47.125052Hobby median: 95.965674 min: 48.140494 max: 179.588236 p90: 132.590091 gap: 36.624417Hobby median: 98.866772 min: 55.389048 max: 248.176058 p90: 148.679642 gap: 49.81287Hobby median: 91.408573 min: 56.316351 max: 203.006833 p90: 144.623791 gap: 53.215218Hobby median: 80.814904 min: 44.436266 max: 121.906019 p90: 110.708814 gap: 29.89391Hobby median: 70.927 min: 47.24501 max: 114.645256 p90: 95.133059 gap: 24.206059Hobby median: 74.605291 min: 43.348197 max: 169.941356 p90: 105.100019 gap: 30.494728Hobby median: 59.68361 min: 40.721832 max: 96.135252 p90: 75.16665 gap: 15.48304Hobby median: 63.579793 min: 43.072186 max: 92.596816 p90: 77.764954 gap: 14.185161Hobby median: 69.051003 min: 43.50663 max: 112.05129 p90: 97.764521 gap: 28.713518Hobby median: 71.461109 min: 43.66313 max: 124.507597 p90: 89.550123 gap: 18.089014Hobby median: 66.014797 min: 41.948805 max: 110.850566 p90: 87.622908 gap: 21.608111Hobby median: 68.488005 min: 41.157021 max: 113.118978 p90: 97.108327 gap: 28.620322Hobby median: 61.041952 min: 41.597209 max: 85.419893 p90: 74.898654 gap: 13.856702Hobby median: 78.693293 min: 45.90185 max: 140.364822 p90: 114.275004 gap: 35.581711Hobby median: 66.784528 min: 41.626399 max: 118.229461 p90: 97.522166 gap: 30.737638Hobby median: 64.985198 min: 40.859427 max: 140.648209 p90: 106.85645 gap: 41.871252Hobby median: 69.660573 min: 41.807771 max: 124.729233 p90: 106.041002 gap: 36.380429Hobby median: 67.364258 min: 42.375124 max: 126.306195 p90: 96.878025 gap: 29.513767Hobby median: 57.858088 min: 42.100024 max: 91.48954 p90: 73.550299 gap: 15.692211Hobby median: 71.424511 min: 41.890899 max: 130.460805 p90: 112.547055 gap: 41.122544Hobby median: 74.375542 min: 46.74711 max: 129.911704 p90: 114.762787 gap: 40.387245Hobby median: 75.75294 min: 41.092116 max: 133.272675 p90: 104.354288 gap: 28.601348Hobby median: 65.113747 min: 41.576824 max: 103.485753 p90: 90.721929 gap: 25.608182Hobby median: 60.040928 min: 40.653382 max: 100.044351 p90: 78.996054 gap: 18.955126Hobby median: 70.000362 min: 42.525791 max: 136.453775 p90: 110.689009 gap: 40.688647Hobby median: 70.534879 min: 44.402767 max: 136.495704 p90: 110.707629 gap: 40.17275Hobby median: 79.491879 min: 45.521539 max: 168.281902 p90: 131.887949 gap: 52.39607Hobby median: 68.049793 min: 41.786255 max: 128.484824 p90: 82.803916 gap: 14.754123Hobby median: 90.670584 min: 48.259494 max: 184.315771 p90: 120.325544 gap: 29.65496Hobby median: 76.13478 min: 42.065405 max: 129.150304 p90: 120.357969 gap: 44.223189Hobby median: 88.166508 min: 47.058285 max: 163.379407 p90: 126.864496 gap: 38.697988Hobby median: 91.210602 min: 47.908365 max: 175.977696 p90: 139.513485 gap: 48.302883Hobby median: 97.813696 min: 51.659336 max: 235.101631 p90: 162.763312 gap: 64.949616Hobby median: 79.199243 min: 50.136156 max: 134.916423 p90: 103.743202 gap: 24.543959Hobby median: 88.011613 min: 55.522978 max: 177.881985 p90: 131.526107 gap: 43.514494Hobby median: 68.091426 min: 42.42413 max: 116.842984 p90: 87.822454 gap: 19.731028Hobby median: 83.814514 min: 46.879952 max: 162.905548 p90: 129.456231 gap: 45.641717Hobby median: 75.377394 min: 44.686942 max: 163.086236 p90: 99.910434 gap: 24.53304Hobby median: 77.588466 min: 43.488113 max: 153.795576 p90: 112.50062 gap: 34.912154Hobby median: 79.383974 min: 46.778209 max: 155.337537 p90: 116.750586 gap: 37.366612Hobby median: 76.336387 min: 43.583884 max: 118.103207 p90: 98.173556 gap: 21.837169Hobby median: 75.285668 min: 44.054602 max: 169.647219 p90: 118.944845 gap: 43.659177Hobby median: 80.576965 min: 44.635894 max: 169.531995 p90: 120.959414 gap: 40.382449Hobby median: 63.718711 min: 41.956809 max: 110.478606 p90: 89.515522 gap: 25.796811Hobby median: 64.081476 min: 41.062863 max: 103.905 p90: 85.230934 gap: 21.149458Hobby median: 74.52056 min: 45.540854 max: 113.699574 p90: 93.292581 gap: 18.772021Hobby median: 80.824497 min: 45.692872 max: 142.232797 p90: 114.486828 gap: 33.662331Hobby median: 77.69795 min: 45.678516 max: 184.170472 p90: 113.309586 gap: 35.611636Hobby median: 70.375774 min: 41.27189 max: 141.60562 p90: 103.958746 gap: 33.582972Hobby median: 70.808211 min: 43.307982 max: 124.975411 p90: 89.9761 gap: 19.167889Hobby median: 82.251545 min: 45.757642 max: 173.916692 p90: 125.933639 gap: 43.682094Hobby median: 92.889424 min: 48.520915 max: 204.785127 p90: 139.228908 gap: 46.339484Hobby median: 77.118228 min: 46.537404 max: 180.701809 p90: 115.332321 gap: 38.214093Hobby median: 98.557134 min: 49.301072 max: 298.429233 p90: 138.545365 gap: 39.988231Hobby median: 80.664845 min: 48.541652 max: 173.354998 p90: 110.971365 gap: 30.30652Hobby median: 68.359381 min: 41.199909 max: 156.190562 p90: 93.503489 gap: 25.144108Hobby median: 67.969596 min: 42.194484 max: 97.304505 p90: 86.818939 gap: 18.849343Hobby median: 65.921371 min: 42.741179 max: 118.18438 p90: 103.37461 gap: 37.453239Hobby median: 71.944937 min: 43.379019 max: 137.815736 p90: 97.390776 gap: 25.445839Hobby median: 60.301886 min: 41.185383 max: 89.672772 p90: 74.219247 gap: 13.917361Hobby median: 60.079382 min: 41.460114 max: 127.110773 p90: 79.514136 gap: 19.434754Standard 1x median: 64.88243 min: 43.344921 max: 128.506158 p90: 89.447035 gap: 24.564605Standard 1x median: 58.644547 min: 37.628991 max: 106.425931 p90: 86.42241 gap: 27.777863Standard 1x median: 67.768329 min: 43.659881 max: 124.434523 p90: 93.549056 gap: 25.780727Standard 1x median: 71.173559 min: 42.00588 max: 117.801894 p90: 95.520279 gap: 24.34672Standard 1x median: 74.944077 min: 43.157001 max: 145.068505 p90: 115.900301 gap: 40.956224Standard 1x median: 65.355178 min: 39.066383 max: 136.689931 p90: 102.285286 gap: 36.930108Standard 1x median: 64.819534 min: 38.910827 max: 105.743434 p90: 89.097462 gap: 24.277928Standard 1x median: 83.993864 min: 45.76103 max: 139.599354 p90: 125.737276 gap: 41.743412Standard 1x median: 73.076067 min: 43.311093 max: 183.117405 p90: 112.350356 gap: 39.274289Standard 1x median: 57.708466 min: 37.86103 max: 99.454688 p90: 76.135509 gap: 18.427043Standard 1x median: 69.599708 min: 43.040651 max: 131.646476 p90: 98.413454 gap: 28.813746Standard 1x median: 71.899661 min: 41.23842 max: 113.662766 p90: 97.532856 gap: 25.633195Standard 1x median: 64.506883 min: 42.928341 max: 122.619796 p90: 84.632008 gap: 20.125125Standard 1x median: 61.078483 min: 39.624457 max: 108.205105 p90: 83.878906 gap: 22.800423Standard 1x median: 56.775619 min: 37.820696 max: 86.02168 p90: 75.534685 gap: 18.759066Standard 1x median: 70.251009 min: 43.297096 max: 112.279291 p90: 95.019007 gap: 24.767998Standard 1x median: 74.178212 min: 45.475998 max: 163.198457 p90: 119.717369 gap: 45.539157Standard 1x median: 58.515709 min: 39.812365 max: 100.492357 p90: 78.514301 gap: 19.998592Standard 1x median: 61.888538 min: 39.790704 max: 95.957591 p90: 80.896112 gap: 19.007574Standard 1x median: 78.620043 min: 43.233967 max: 160.122406 p90: 112.880833 gap: 34.26079Standard 1x median: 71.356058 min: 42.707185 max: 182.965105 p90: 104.482533 gap: 33.126475Standard 1x median: 67.63441 min: 43.141033 max: 104.88678 p90: 93.910109 gap: 26.275699Standard 1x median: 57.172732 min: 38.907998 max: 91.294335 p90: 72.471412 gap: 15.29868Standard 1x median: 62.644134 min: 39.347102 max: 134.182602 p90: 89.579307 gap: 26.935173Standard 1x median: 70.292595 min: 40.811098 max: 111.480807 p90: 91.80836 gap: 21.515765Standard 1x median: 65.38023 min: 41.174668 max: 133.014191 p90: 97.218491 gap: 31.838261Standard 1x median: 58.844889 min: 39.763908 max: 109.034927 p90: 87.189199 gap: 28.34431Standard 1x median: 59.433432 min: 39.021474 max: 103.81263 p90: 81.151397 gap: 21.717965Standard 1x median: 70.6944 min: 41.75253 max: 183.231365 p90: 105.997879 gap: 35.303479Standard 1x median: 72.841222 min: 44.302374 max: 160.15951 p90: 105.58193 gap: 32.740708Standard 1x median: 74.907394 min: 38.205222 max: 142.0358 p90: 113.734775 gap: 38.827381Standard 1x median: 63.305544 min: 38.488736 max: 118.574046 p90: 88.620717 gap: 25.315173Standard 1x median: 69.122794 min: 43.686021 max: 124.080343 p90: 101.66594 gap: 32.543146Standard 1x median: 66.252527 min: 42.20198 max: 117.692192 p90: 86.04509 gap: 19.792563Standard 1x median: 74.520316 min: 39.625269 max: 196.458052 p90: 128.197502 gap: 53.677186Standard 1x median: 83.8354 min: 42.817018 max: 130.507686 p90: 113.597308 gap: 29.761908Standard 1x median: 75.357302 min: 44.457282 max: 143.830794 p90: 103.472852 gap: 28.11555Standard 1x median: 89.621222 min: 47.020896 max: 167.008199 p90: 129.494499 gap: 39.873277Standard 1x median: 87.720747 min: 42.158502 max: 193.319059 p90: 132.150825 gap: 44.430078Standard 1x median: 124.089686 min: 68.75396 max: 240.787299 p90: 181.967687 gap: 57.878001Standard 1x median: 106.333304 min: 58.906741 max: 225.929721 p90: 174.57456 gap: 68.241256Standard 1x median: 92.730751 min: 48.285872 max: 176.493897 p90: 134.119245 gap: 41.388494Standard 1x median: 135.22524 min: 55.60706 max: 348.077915 p90: 257.915761 gap: 122.690521Standard 1x median: 165.933322 min: 74.301323 max: 478.775767 p90: 308.934842 gap: 143.00152Standard 1x median: 165.280399 min: 76.313588 max: 426.961264 p90: 276.49958 gap: 111.219181Standard 1x median: 145.431732 min: 79.355497 max: 325.864159 p90: 217.626654 gap: 72.194922Standard 1x median: 116.230989 min: 62.097716 max: 252.672509 p90: 172.925704 gap: 56.694715Standard 1x median: 98.772068 min: 56.750213 max: 167.300759 p90: 130.819799 gap: 32.047731Standard 1x median: 102.496739 min: 51.940402 max: 205.609198 p90: 141.479693 gap: 38.982954Standard 1x median: 134.220807 min: 71.153477 max: 382.108839 p90: 223.10603 gap: 88.885223Standard 1x median: 178.595277 min: 67.753717 max: 495.33003 p90: 315.234043 gap: 136.638766Standard 1x median: 137.428829 min: 71.84521 max: 289.293555 p90: 221.556368 gap: 84.127539Standard 1x median: 151.552813 min: 66.858427 max: 341.199434 p90: 263.462795 gap: 111.909982Standard 1x median: 195.748528 min: 75.424476 max: 470.769053 p90: 363.797315 gap: 168.048787Standard 1x median: 118.822818 min: 61.52841 max: 268.684038 p90: 184.922263 gap: 66.099445Standard 1x median: 144.044193 min: 67.905431 max: 327.449566 p90: 230.618138 gap: 86.573945Standard 1x median: 109.762508 min: 52.581335 max: 335.949617 p90: 206.220251 gap: 96.457743Standard 1x median: 99.087143 min: 53.736235 max: 299.87775 p90: 171.855494 gap: 72.768351Standard 1x median: 152.332367 min: 60.625559 max: 419.824357 p90: 254.282909 gap: 101.950542Standard 1x median: 113.53947 min: 64.017224 max: 180.424802 p90: 145.11684 gap: 31.57737Standard 1x median: 93.789421 min: 50.676019 max: 194.750202 p90: 160.226661 gap: 66.43724Standard 1x median: 117.497486 min: 48.938035 max: 276.869449 p90: 187.616271 gap: 70.118785Standard 1x median: 107.856161 min: 62.386954 max: 263.478297 p90: 190.987394 gap: 83.131233Standard 1x median: 97.114087 min: 49.201222 max: 223.643625 p90: 150.795798 gap: 53.681711Standard 1x median: 80.382612 min: 43.206402 max: 151.902035 p90: 120.949163 gap: 40.566551Standard 1x median: 117.739585 min: 57.920246 max: 226.995342 p90: 193.936747 gap: 76.197162Standard 1x median: 147.93154 min: 66.503361 max: 334.359336 p90: 281.725517 gap: 133.793977Standard 1x median: 118.399706 min: 61.492938 max: 234.514185 p90: 171.899135 gap: 53.499429Standard 1x median: 106.269409 min: 48.650539 max: 187.403129 p90: 148.931898 gap: 42.662489Standard 1x median: 118.720605 min: 58.134068 max: 274.352211 p90: 197.213976 gap: 78.493371Standard 1x median: 88.421053 min: 50.115601 max: 178.781686 p90: 125.831563 gap: 37.41051Standard 1x median: 82.972779 min: 48.440833 max: 162.256345 p90: 108.752442 gap: 25.779663Standard 1x median: 105.748981 min: 49.083503 max: 252.515309 p90: 162.369257 gap: 56.620276Standard 1x median: 83.806271 min: 50.68724 max: 153.982586 p90: 121.724232 gap: 37.917961Standard 1x median: 83.459739 min: 44.879231 max: 188.60546 p90: 121.103979 gap: 37.64424Standard 1x median: 71.996736 min: 45.250107 max: 151.244694 p90: 98.164028 gap: 26.167292Standard 1x median: 70.443672 min: 40.885603 max: 98.486855 p90: 90.500856 gap: 20.057184Standard 1x median: 82.445506 min: 46.946777 max: 135.690266 p90: 115.729541 gap: 33.284035Standard 1x median: 90.08438 min: 48.23892 max: 224.963699 p90: 150.329534 gap: 60.245154Standard 1x median: 98.224758 min: 40.612288 max: 245.578261 p90: 180.574164 gap: 82.349406Standard 1x median: 122.806261 min: 50.97548 max: 366.14526 p90: 193.315276 gap: 70.509015Standard 1x median: 82.159544 min: 47.329989 max: 184.398783 p90: 128.614184 gap: 46.45464Standard 1x median: 78.323765 min: 45.160531 max: 135.046371 p90: 107.313102 gap: 28.989337Standard 1x median: 86.639058 min: 44.814625 max: 191.467753 p90: 130.544641 gap: 43.905583Standard 1x median: 74.079889 min: 41.312347 max: 136.683335 p90: 110.65678 gap: 36.576891Standard 1x median: 68.925181 min: 40.816649 max: 115.532135 p90: 95.794433 gap: 26.869252Standard 1x median: 81.703181 min: 48.446835 max: 139.515892 p90: 116.861663 gap: 35.158482Standard 1x median: 80.12083 min: 45.508879 max: 159.920386 p90: 130.372965 gap: 50.252135Standard 1x median: 72.224095 min: 43.654535 max: 133.147998 p90: 110.29415 gap: 38.070055Standard 1x median: 92.168595 min: 45.084557 max: 288.736679 p90: 181.471485 gap: 89.30289Standard 1x median: 123.04169 min: 57.081174 max: 310.71196 p90: 180.531834 gap: 57.490144Standard 1x median: 102.767022 min: 43.41598 max: 206.38416 p90: 160.507981 gap: 57.740959Standard 1x median: 85.959972 min: 45.476603 max: 255.929215 p90: 150.877324 gap: 64.917352Standard 1x median: 81.979928 min: 42.386934 max: 321.694809 p90: 175.492384 gap: 93.512456Standard 1x median: 59.756083 min: 39.474347 max: 122.625599 p90: 82.626787 gap: 22.870704Standard 1x median: 71.59165 min: 42.795373 max: 130.555984 p90: 97.946647 gap: 26.354997Standard 1x median: 72.890581 min: 42.221348 max: 120.306458 p90: 102.304556 gap: 29.413975Standard 1x median: 86.299541 min: 41.820401 max: 235.01534 p90: 143.591518 gap: 57.291977Standard 1x median: 88.443117 min: 42.743648 max: 142.952767 p90: 119.935118 gap: 31.492001Standard 1x median: 91.129167 min: 52.174521 max: 196.482391 p90: 145.149606 gap: 54.020439Standard 2x median: 91.958213 min: 45.274592 max: 182.897926 p90: 145.56602 gap: 53.607807Standard 2x median: 109.013553 min: 59.076062 max: 246.471285 p90: 186.074665 gap: 77.061112Standard 2x median: 125.220583 min: 58.26513 max: 346.37249 p90: 256.037845 gap: 130.817262Standard 2x median: 114.29798 min: 41.858257 max: 268.536795 p90: 190.281604 gap: 75.983624Standard 2x median: 96.247676 min: 44.916184 max: 205.737872 p90: 149.01638 gap: 52.768704Standard 2x median: 72.580689 min: 36.635362 max: 160.474938 p90: 112.064176 gap: 39.483487Standard 2x median: 77.66615 min: 42.273214 max: 163.867889 p90: 127.681626 gap: 50.015476Standard 2x median: 79.573666 min: 38.222361 max: 174.003566 p90: 133.018187 gap: 53.444521Standard 2x median: 73.258677 min: 38.359393 max: 131.860304 p90: 115.019077 gap: 41.7604Standard 2x median: 78.668742 min: 36.325851 max: 157.569178 p90: 116.994179 gap: 38.325437Standard 2x median: 79.484311 min: 38.977266 max: 163.575549 p90: 125.663474 gap: 46.179163Standard 2x median: 85.492789 min: 39.650131 max: 172.450225 p90: 136.182888 gap: 50.690099Standard 2x median: 75.643561 min: 37.248008 max: 163.943483 p90: 116.845017 gap: 41.201456Standard 2x median: 74.147163 min: 36.589592 max: 176.269971 p90: 125.770274 gap: 51.623111Standard 2x median: 77.547757 min: 34.66729 max: 176.319625 p90: 138.481995 gap: 60.934238Standard 2x median: 79.590569 min: 42.185139 max: 186.990614 p90: 149.908586 gap: 70.318017Standard 2x median: 90.87326 min: 41.053365 max: 180.389622 p90: 148.708146 gap: 57.834886Standard 2x median: 83.407524 min: 35.997191 max: 175.410169 p90: 131.820478 gap: 48.412954Standard 2x median: 77.68501 min: 36.429057 max: 172.192717 p90: 126.555028 gap: 48.870018Standard 2x median: 75.338579 min: 37.940399 max: 175.820935 p90: 116.911996 gap: 41.573417Standard 2x median: 69.255227 min: 37.087538 max: 136.403373 p90: 103.48266 gap: 34.227433Standard 2x median: 81.74261 min: 40.783317 max: 183.263421 p90: 141.500645 gap: 59.758035Standard 2x median: 107.548299 min: 45.363034 max: 333.607175 p90: 183.3244 gap: 75.776101Standard 2x median: 80.568497 min: 41.337002 max: 159.720202 p90: 137.881832 gap: 57.313335Standard 2x median: 80.552326 min: 39.049317 max: 152.774488 p90: 119.463204 gap: 38.910878Standard 2x median: 77.904069 min: 40.089753 max: 170.915854 p90: 129.013551 gap: 51.109482Standard 2x median: 88.674985 min: 44.441825 max: 201.69433 p90: 151.5217 gap: 62.846715Standard 2x median: 91.096694 min: 38.062302 max: 183.543165 p90: 151.041426 gap: 59.944732Standard 2x median: 113.234132 min: 42.564415 max: 329.664231 p90: 210.010255 gap: 96.776123Standard 2x median: 89.508578 min: 40.995586 max: 261.489505 p90: 160.464217 gap: 70.955639Standard 2x median: 89.075261 min: 39.266306 max: 175.688653 p90: 144.572681 gap: 55.49742Standard 2x median: 72.1543 min: 40.450848 max: 152.763441 p90: 114.544736 gap: 42.390436Standard 2x median: 87.827045 min: 46.956195 max: 179.002917 p90: 136.431379 gap: 48.604334Standard 2x median: 85.331859 min: 43.646278 max: 234.907403 p90: 141.815383 gap: 56.483524Standard 2x median: 106.576817 min: 48.623002 max: 218.16141 p90: 171.952385 gap: 65.375568Standard 2x median: 103.484292 min: 41.056097 max: 169.672048 p90: 141.281909 gap: 37.797617Standard 2x median: 96.992647 min: 45.564133 max: 214.266781 p90: 155.170863 gap: 58.178216Standard 2x median: 85.353496 min: 43.384788 max: 169.462154 p90: 128.410817 gap: 43.057321Standard 2x median: 86.857786 min: 39.145354 max: 150.039719 p90: 124.643877 gap: 37.786091Standard 2x median: 92.513642 min: 44.640306 max: 178.159191 p90: 151.119436 gap: 58.605794Standard 2x median: 97.17206 min: 42.500128 max: 183.686769 p90: 160.493547 gap: 63.321487Standard 2x median: 103.375612 min: 47.322248 max: 233.071254 p90: 178.807984 gap: 75.432372Standard 2x median: 92.957697 min: 43.835209 max: 187.156093 p90: 151.703439 gap: 58.745742Standard 2x median: 87.797046 min: 43.67297 max: 180.059601 p90: 149.148445 gap: 61.351399Standard 2x median: 67.060934 min: 38.497352 max: 121.050561 p90: 101.912935 gap: 34.852001Standard 2x median: 88.003498 min: 38.959104 max: 170.926144 p90: 139.079958 gap: 51.07646Standard 2x median: 95.326184 min: 47.88274 max: 212.851829 p90: 150.475201 gap: 55.149017Standard 2x median: 79.30581 min: 41.293873 max: 177.614234 p90: 134.96101 gap: 55.6552Standard 2x median: 77.529632 min: 38.901501 max: 155.772661 p90: 138.323208 gap: 60.793576Standard 2x median: 81.347672 min: 41.497216 max: 194.065529 p90: 135.305303 gap: 53.957631Standard 2x median: 82.57916 min: 37.545314 max: 176.44376 p90: 139.202719 gap: 56.623559Standard 2x median: 88.795133 min: 50.085831 max: 178.839574 p90: 140.572672 gap: 51.777539Standard 2x median: 90.691542 min: 42.997363 max: 204.773041 p90: 159.20423 gap: 68.512688Standard 2x median: 86.910036 min: 41.2301 max: 168.355004 p90: 137.610666 gap: 50.70063Standard 2x median: 77.342175 min: 36.784262 max: 169.378131 p90: 130.511576 gap: 53.169401Standard 2x median: 86.017936 min: 41.809719 max: 179.621364 p90: 144.820611 gap: 58.802675Standard 2x median: 91.647705 min: 43.516732 max: 211.216209 p90: 159.07969 gap: 67.431985Standard 2x median: 87.563977 min: 39.824606 max: 209.727856 p90: 141.945879 gap: 54.381902Standard 2x median: 81.303155 min: 41.466199 max: 159.949377 p90: 132.801272 gap: 51.498117Standard 2x median: 88.972905 min: 42.670202 max: 161.156924 p90: 135.370677 gap: 46.397772Standard 2x median: 80.581612 min: 41.72413 max: 154.716904 p90: 118.668251 gap: 38.086639Standard 2x median: 72.429332 min: 40.631594 max: 142.759183 p90: 112.778174 gap: 40.348842Standard 2x median: 75.850061 min: 38.356799 max: 146.251878 p90: 122.812992 gap: 46.962931Standard 2x median: 125.909941 min: 56.50596 max: 311.85066 p90: 195.344597 gap: 69.434656Standard 2x median: 110.098817 min: 41.181028 max: 354.072617 p90: 165.021136 gap: 54.922319Standard 2x median: 99.193616 min: 46.411479 max: 199.202926 p90: 156.983495 gap: 57.789879Standard 2x median: 94.648284 min: 41.77263 max: 202.16365 p90: 155.37306 gap: 60.724776Standard 2x median: 100.332009 min: 41.310736 max: 197.831687 p90: 159.956795 gap: 59.624786Standard 2x median: 82.649647 min: 39.902697 max: 155.636999 p90: 115.912275 gap: 33.262628Standard 2x median: 79.71404 min: 38.333566 max: 161.200314 p90: 123.861496 gap: 44.147456Standard 2x median: 102.201302 min: 57.670325 max: 213.666848 p90: 155.064256 gap: 52.862954Standard 2x median: 77.051452 min: 37.11991 max: 172.384208 p90: 124.839895 gap: 47.788443Standard 2x median: 76.295998 min: 37.959632 max: 183.176936 p90: 130.911216 gap: 54.615218Standard 2x median: 70.590394 min: 38.113813 max: 127.397734 p90: 115.563826 gap: 44.973432Standard 2x median: 81.88483 min: 40.017223 max: 161.781921 p90: 135.820181 gap: 53.935351Standard 2x median: 93.186726 min: 41.081089 max: 170.091666 p90: 138.927688 gap: 45.740962Standard 2x median: 84.189308 min: 35.373725 max: 188.01751 p90: 147.277034 gap: 63.087726Standard 2x median: 76.915223 min: 38.138235 max: 175.870168 p90: 141.993036 gap: 65.077813Standard 2x median: 90.370298 min: 42.631926 max: 193.945621 p90: 144.579527 gap: 54.209229Standard 2x median: 89.37622 min: 38.291455 max: 265.648987 p90: 169.118984 gap: 79.742764Standard 2x median: 71.068953 min: 35.906852 max: 172.432216 p90: 114.904527 gap: 43.835574Standard 2x median: 73.760641 min: 35.160835 max: 149.206258 p90: 114.677001 gap: 40.91636Standard 2x median: 66.780711 min: 36.416749 max: 166.552994 p90: 112.470081 gap: 45.68937Standard 2x median: 65.307601 min: 37.400731 max: 118.58612 p90: 100.912795 gap: 35.605194Standard 2x median: 71.419415 min: 37.897094 max: 150.923865 p90: 114.525067 gap: 43.105652Standard 2x median: 68.571556 min: 37.204759 max: 114.551815 p90: 94.97367 gap: 26.402114Standard 2x median: 68.883111 min: 36.21454 max: 140.044234 p90: 100.874061 gap: 31.99095Standard 2x median: 85.054282 min: 37.054426 max: 184.087521 p90: 142.296275 gap: 57.241993Standard 2x median: 90.62564 min: 37.11904 max: 199.946449 p90: 140.129006 gap: 49.503366Standard 2x median: 88.860168 min: 38.291071 max: 169.404858 p90: 135.065297 gap: 46.205129Standard 2x median: 82.961557 min: 42.892946 max: 172.27313 p90: 138.017815 gap: 55.056258Standard 2x median: 64.879354 min: 36.100552 max: 119.446281 p90: 95.0869 gap: 30.207546Standard 2x median: 65.072484 min: 37.055279 max: 130.129354 p90: 113.093448 gap: 48.020964Standard 2x median: 102.322511 min: 42.475679 max: 293.20118 p90: 162.766957 gap: 60.444446Standard 2x median: 79.759313 min: 36.030247 max: 172.324536 p90: 126.796122 gap: 47.036809Standard 2x median: 76.866707 min: 36.476337 max: 163.272554 p90: 122.142174 gap: 45.275467Standard 2x median: 74.415357 min: 35.705251 max: 161.184702 p90: 114.452693 gap: 40.037336Standard 2x median: 66.97776 min: 37.417819 max: 145.437818 p90: 103.050853 gap: 36.073093Standard 2x median: 72.221974 min: 36.626053 max: 150.418668 p90: 114.081142 gap: 41.859168Standard 2x median: 74.822657 min: 36.920968 max: 161.755902 p90: 121.887412 gap: 47.064755Performance-M median: 35.764612 min: 24.474498 max: 62.432858 p90: 59.012946 gap: 23.248334Performance-M median: 35.180578 min: 24.489187 max: 60.865288 p90: 53.701581 gap: 18.521003Performance-M median: 35.372782 min: 24.533774 max: 66.288161 p90: 55.337537 gap: 19.964755Performance-M median: 35.240414 min: 24.49823 max: 60.028618 p90: 54.99013 gap: 19.749716Performance-M median: 35.226201 min: 24.468611 max: 59.695207 p90: 54.074242 gap: 18.848041Performance-M median: 35.171917 min: 24.477337 max: 61.349806 p90: 55.095912 gap: 19.923995Performance-M median: 35.725473 min: 24.532536 max: 100.718209 p90: 58.581823 gap: 22.85635Performance-M median: 35.083432 min: 24.440202 max: 61.486711 p90: 53.645622 gap: 18.56219Performance-M median: 35.907566 min: 24.498859 max: 64.274756 p90: 54.396247 gap: 18.488681Performance-M median: 35.875908 min: 24.467973 max: 60.558165 p90: 54.473196 gap: 18.597288Performance-M median: 35.5713 min: 24.438639 max: 63.999342 p90: 56.594793 gap: 21.023493Performance-M median: 35.448425 min: 24.385029 max: 63.204807 p90: 57.120722 gap: 21.672297Performance-M median: 35.464434 min: 24.403111 max: 61.953322 p90: 56.279132 gap: 20.814698Performance-M median: 35.519557 min: 24.430723 max: 59.369133 p90: 53.912398 gap: 18.392841Performance-M median: 35.157406 min: 24.392912 max: 60.015333 p90: 56.349531 gap: 21.192125Performance-M median: 35.312048 min: 24.426809 max: 60.358461 p90: 53.91793 gap: 18.605882Performance-M median: 35.2979 min: 24.458041 max: 67.73902 p90: 54.337036 gap: 19.039136Performance-M median: 35.570496 min: 24.462332 max: 71.513631 p90: 54.661315 gap: 19.090819Performance-M median: 35.623938 min: 24.463695 max: 63.211691 p90: 55.615548 gap: 19.99161Performance-M median: 35.365209 min: 24.498601 max: 59.683294 p90: 54.683933 gap: 19.318724Performance-M median: 35.351709 min: 24.459696 max: 59.741537 p90: 54.186698 gap: 18.834989Performance-M median: 35.281165 min: 24.440078 max: 61.412045 p90: 55.65719 gap: 20.376025Performance-M median: 35.515681 min: 24.410293 max: 67.646532 p90: 59.725029 gap: 24.209348Performance-M median: 35.768419 min: 24.490549 max: 62.868987 p90: 54.616603 gap: 18.848184Performance-M median: 35.274695 min: 24.474211 max: 68.130739 p90: 54.127857 gap: 18.853162Performance-M median: 35.860928 min: 24.431378 max: 64.191762 p90: 53.617255 gap: 17.756327Performance-M median: 35.154077 min: 24.40561 max: 66.481664 p90: 54.069767 gap: 18.91569Performance-M median: 34.947848 min: 24.401251 max: 72.874498 p90: 53.898757 gap: 18.950909Performance-M median: 35.361178 min: 24.396311 max: 59.579012 p90: 53.868468 gap: 18.50729Performance-M median: 35.249292 min: 24.43179 max: 63.613889 p90: 54.084316 gap: 18.835024Performance-M median: 35.397195 min: 24.443747 max: 59.775742 p90: 54.145207 gap: 18.748012Performance-M median: 35.102337 min: 24.483649 max: 66.352808 p90: 54.059325 gap: 18.956988Performance-M median: 35.129642 min: 24.494064 max: 59.78152 p90: 54.749434 gap: 19.619792Performance-M median: 36.424733 min: 24.511158 max: 67.126084 p90: 59.583671 gap: 23.158938Performance-M median: 35.69112 min: 24.460355 max: 62.868082 p90: 57.854685 gap: 22.163565Performance-M median: 35.058352 min: 24.415102 max: 60.605867 p90: 56.88387 gap: 21.825518Performance-M median: 34.964077 min: 24.426473 max: 59.58277 p90: 54.346693 gap: 19.382616Performance-M median: 35.87888 min: 24.422239 max: 62.086909 p90: 56.968664 gap: 21.089784Performance-M median: 35.543348 min: 24.494848 max: 61.355805 p90: 54.421369 gap: 18.878021Performance-M median: 35.49259 min: 24.456402 max: 59.435908 p90: 55.448345 gap: 19.955755Performance-M median: 36.124878 min: 24.480763 max: 60.127555 p90: 55.041859 gap: 18.916981Performance-M median: 35.301369 min: 24.478331 max: 60.016411 p90: 55.354655 gap: 20.053286Performance-M median: 35.14183 min: 24.468079 max: 60.695647 p90: 57.121821 gap: 21.979991Performance-M median: 35.389477 min: 24.522963 max: 73.573264 p90: 54.267003 gap: 18.877526Performance-M median: 35.405074 min: 24.491534 max: 64.893264 p90: 53.693578 gap: 18.288504Performance-M median: 35.917483 min: 24.429389 max: 65.278238 p90: 55.153272 gap: 19.235789Performance-M median: 35.623738 min: 24.442882 max: 65.128056 p90: 54.686534 gap: 19.062796Performance-M median: 35.039504 min: 24.42088 max: 60.414197 p90: 54.380087 gap: 19.340583Performance-M median: 35.221591 min: 24.460976 max: 66.482932 p90: 55.927499 gap: 20.705908Performance-M median: 35.549687 min: 24.444974 max: 64.283142 p90: 55.157387 gap: 19.6077Performance-M median: 35.460006 min: 24.429113 max: 61.685438 p90: 54.236221 gap: 18.776215Performance-M median: 35.583062 min: 24.465843 max: 65.14907 p90: 54.581488 gap: 18.998426Performance-M median: 35.284888 min: 24.466401 max: 59.921738 p90: 54.931216 gap: 19.646328Performance-M median: 35.858333 min: 24.440523 max: 64.876125 p90: 58.793165 gap: 22.934832Performance-M median: 35.586492 min: 24.515158 max: 59.462688 p90: 55.66315 gap: 20.076658Performance-M median: 35.329758 min: 24.444433 max: 60.590054 p90: 54.784697 gap: 19.454939Performance-M median: 72.411909 min: 24.494069 max: 129.203277 p90: 92.834368 gap: 20.422459Performance-M median: 37.130685 min: 24.730995 max: 92.445121 p90: 61.915216 gap: 24.784531Performance-M median: 36.105321 min: 24.824009 max: 66.319924 p90: 56.224227 gap: 20.118906Performance-M median: 36.619291 min: 24.796851 max: 67.227652 p90: 58.020721 gap: 21.40143Performance-M median: 36.307892 min: 24.829675 max: 109.245847 p90: 60.033496 gap: 23.725604Performance-M median: 36.348173 min: 24.804375 max: 62.365409 p90: 56.890687 gap: 20.542514Performance-M median: 36.145345 min: 24.730259 max: 69.027804 p90: 60.928617 gap: 24.783272Performance-M median: 36.596274 min: 24.900127 max: 64.3701 p90: 56.573707 gap: 19.977433Performance-M median: 36.348476 min: 24.824726 max: 64.883148 p90: 57.526377 gap: 21.177901Performance-M median: 36.121441 min: 24.786309 max: 70.825759 p90: 56.114515 gap: 19.993074Performance-M median: 36.551067 min: 24.861751 max: 77.184768 p90: 59.073067 gap: 22.522Performance-M median: 37.881274 min: 24.984199 max: 126.558321 p90: 77.859231 gap: 39.977957Performance-M median: 36.636901 min: 24.805837 max: 65.891959 p90: 56.673043 gap: 20.036142Performance-M median: 37.080599 min: 24.795578 max: 61.185891 p90: 58.183892 gap: 21.103293Performance-M median: 36.253471 min: 24.809844 max: 67.51324 p90: 56.321382 gap: 20.067911Performance-M median: 36.395527 min: 24.86342 max: 64.700682 p90: 56.110539 gap: 19.715012Performance-M median: 36.336997 min: 24.817507 max: 62.527668 p90: 56.295717 gap: 19.95872Performance-M median: 36.161348 min: 24.827268 max: 62.274991 p90: 56.401884 gap: 20.240536Performance-M median: 37.007297 min: 24.826289 max: 63.361161 p90: 56.795369 gap: 19.788072Performance-M median: 36.387331 min: 24.753424 max: 63.471426 p90: 56.668641 gap: 20.28131Performance-M median: 36.45542 min: 24.812216 max: 66.007059 p90: 56.42022 gap: 19.9648Performance-M median: 36.064244 min: 24.80417 max: 67.768735 p90: 58.953093 gap: 22.888849Performance-M median: 35.836331 min: 24.787497 max: 61.109704 p90: 55.996908 gap: 20.160577Performance-M median: 36.07773 min: 24.86397 max: 67.308404 p90: 58.018866 gap: 21.941136Performance-M median: 36.400104 min: 24.888824 max: 63.034066 p90: 56.580776 gap: 20.180672Performance-M median: 36.922408 min: 24.869593 max: 62.067016 p90: 57.133486 gap: 20.211078Performance-M median: 36.798859 min: 24.829601 max: 67.270337 p90: 56.192712 gap: 19.393853Performance-M median: 35.888976 min: 24.847744 max: 67.570946 p90: 56.372546 gap: 20.48357Performance-M median: 37.052315 min: 24.805489 max: 61.162693 p90: 56.694695 gap: 19.64238Performance-M median: 36.154118 min: 24.88781 max: 62.118339 p90: 57.363578 gap: 21.20946Performance-M median: 36.203202 min: 24.880022 max: 64.355239 p90: 56.821096 gap: 20.617894Performance-M median: 36.492037 min: 24.830943 max: 68.003613 p90: 57.63553 gap: 21.143493Performance-M median: 37.111187 min: 24.916887 max: 67.781386 p90: 56.918455 gap: 19.807268Performance-M median: 36.34363 min: 24.867316 max: 61.69465 p90: 56.50717 gap: 20.16354Performance-M median: 36.694103 min: 24.868022 max: 61.454676 p90: 58.180499 gap: 21.486396Performance-M median: 36.447332 min: 24.888295 max: 68.288503 p90: 57.805579 gap: 21.358247Performance-M median: 36.462265 min: 24.891142 max: 61.537898 p90: 56.449985 gap: 19.98772Performance-M median: 36.297992 min: 24.849901 max: 72.751705 p90: 56.975615 gap: 20.677623Performance-M median: 36.389478 min: 24.852375 max: 62.041596 p90: 56.903117 gap: 20.513639Performance-M median: 37.081168 min: 24.846144 max: 67.957396 p90: 57.103242 gap: 20.022074Performance-M median: 37.010395 min: 24.841556 max: 61.752192 p90: 56.812848 gap: 19.802453Performance-M median: 36.443505 min: 24.788917 max: 61.794144 p90: 56.688191 gap: 20.244686Performance-M median: 36.524444 min: 24.870035 max: 61.951112 p90: 57.154195 gap: 20.629751Performance-M median: 36.210752 min: 24.940882 max: 68.236706 p90: 56.317596 gap: 20.106844Performance-L median: 33.434311 min: 24.469806 max: 55.747209 p90: 39.06472 gap: 5.630409Performance-L median: 33.288034 min: 24.42071 max: 55.586904 p90: 38.875415 gap: 5.587381Performance-L median: 33.417801 min: 24.43478 max: 55.440639 p90: 39.126615 gap: 5.708814Performance-L median: 33.356395 min: 24.462601 max: 55.688671 p90: 39.171745 gap: 5.81535Performance-L median: 33.367786 min: 24.417823 max: 56.436327 p90: 39.468882 gap: 6.101096Performance-L median: 33.555684 min: 24.394852 max: 56.351289 p90: 38.881677 gap: 5.325993Performance-L median: 33.454542 min: 24.377071 max: 57.143499 p90: 39.075464 gap: 5.620922Performance-L median: 33.325478 min: 24.420082 max: 55.48105 p90: 39.025122 gap: 5.699644Performance-L median: 33.65304 min: 24.414541 max: 55.350956 p90: 39.510326 gap: 5.857286Performance-L median: 33.29946 min: 24.407225 max: 55.840199 p90: 39.220575 gap: 5.921115Performance-L median: 33.421092 min: 24.39809 max: 57.673604 p90: 39.279109 gap: 5.858017Performance-L median: 33.521179 min: 24.390167 max: 59.317124 p90: 40.168116 gap: 6.646937Performance-L median: 33.304003 min: 24.360341 max: 55.776917 p90: 38.519503 gap: 5.2155Performance-L median: 33.356925 min: 24.337782 max: 56.910141 p90: 39.314075 gap: 5.95715Performance-L median: 33.409577 min: 24.394228 max: 56.442406 p90: 39.062783 gap: 5.653206Performance-L median: 33.317657 min: 24.35436 max: 55.841112 p90: 38.962593 gap: 5.644936Performance-L median: 33.191455 min: 24.376217 max: 55.591056 p90: 39.196234 gap: 6.004779Performance-L median: 33.423064 min: 24.371601 max: 55.478129 p90: 38.915057 gap: 5.491993Performance-L median: 33.405671 min: 24.3675 max: 55.467974 p90: 38.774769 gap: 5.369098Performance-L median: 33.092847 min: 24.318485 max: 55.789767 p90: 38.364563 gap: 5.271716Performance-L median: 33.276494 min: 24.35621 max: 56.008369 p90: 38.614262 gap: 5.337768Performance-L median: 33.347699 min: 24.402523 max: 57.135159 p90: 38.838084 gap: 5.490385Performance-L median: 33.2241 min: 24.408737 max: 55.11221 p90: 38.445967 gap: 5.221867Performance-L median: 33.331941 min: 24.344829 max: 55.268693 p90: 38.512278 gap: 5.180337Performance-L median: 33.235815 min: 24.327429 max: 55.756831 p90: 38.7344 gap: 5.498585Performance-L median: 33.340854 min: 24.330321 max: 55.469042 p90: 38.578884 gap: 5.23803Performance-L median: 33.177179 min: 24.405361 max: 55.752285 p90: 38.704515 gap: 5.527336Performance-L median: 33.381227 min: 24.394998 max: 55.037129 p90: 38.435709 gap: 5.054482Performance-L median: 33.255498 min: 24.334987 max: 56.273146 p90: 38.535957 gap: 5.280459Performance-L median: 33.380782 min: 24.32475 max: 55.840321 p90: 39.008102 gap: 5.62732Performance-L median: 33.754465 min: 24.40283 max: 56.341217 p90: 39.315967 gap: 5.561502Performance-L median: 33.221368 min: 24.373271 max: 56.213435 p90: 38.65261 gap: 5.431242Performance-L median: 33.430042 min: 24.391218 max: 57.795928 p90: 38.853239 gap: 5.423197Performance-L median: 33.272642 min: 24.365692 max: 56.002054 p90: 38.855209 gap: 5.582567Performance-L median: 33.260423 min: 24.343412 max: 55.913029 p90: 38.768176 gap: 5.507753Performance-L median: 33.54794 min: 24.345297 max: 55.543391 p90: 38.788202 gap: 5.240262Performance-L median: 33.50605 min: 24.428991 max: 56.02347 p90: 39.040869 gap: 5.534819Performance-L median: 33.342905 min: 24.370173 max: 55.955753 p90: 38.973363 gap: 5.630458Performance-L median: 33.500786 min: 24.391161 max: 56.360912 p90: 39.063007 gap: 5.562221Performance-L median: 33.253388 min: 24.378005 max: 55.695483 p90: 38.812024 gap: 5.558636Performance-L median: 33.339177 min: 24.406265 max: 55.88689 p90: 38.978608 gap: 5.639431Performance-L median: 33.587819 min: 24.416 max: 56.922637 p90: 39.292456 gap: 5.704637Performance-L median: 33.072471 min: 24.377176 max: 55.159236 p90: 38.247544 gap: 5.175073Performance-L median: 33.432754 min: 24.432116 max: 57.074084 p90: 38.984707 gap: 5.551953Performance-L median: 33.456545 min: 24.445356 max: 56.437415 p90: 39.160744 gap: 5.704199Performance-L median: 33.335913 min: 24.505949 max: 55.75804 p90: 38.857129 gap: 5.521216Performance-L median: 33.323682 min: 24.403811 max: 57.020957 p90: 39.12854 gap: 5.804858Performance-L median: 33.395094 min: 24.438921 max: 57.203412 p90: 39.234349 gap: 5.839255Performance-L median: 33.334792 min: 24.376364 max: 55.819458 p90: 39.318872 gap: 5.98408Performance-L median: 33.425264 min: 24.39346 max: 55.74321 p90: 38.659285 gap: 5.234021Performance-L median: 33.438605 min: 24.426785 max: 55.552544 p90: 39.268831 gap: 5.830226Performance-L median: 33.37485 min: 24.434142 max: 56.697848 p90: 39.227517 gap: 5.852667Performance-L median: 33.368443 min: 24.423302 max: 55.656242 p90: 39.252091 gap: 5.883648Performance-L median: 33.437817 min: 24.467868 max: 55.723882 p90: 38.985744 gap: 5.547927Performance-L median: 33.483275 min: 24.417444 max: 56.344334 p90: 39.155381 gap: 5.672106Performance-L median: 33.352888 min: 24.449952 max: 55.788686 p90: 38.806605 gap: 5.453717Performance-L median: 33.289366 min: 24.466621 max: 55.520501 p90: 38.923723 gap: 5.634357Performance-L median: 33.383103 min: 24.50334 max: 55.496054 p90: 38.95462 gap: 5.571517Performance-L median: 33.149306 min: 24.449398 max: 55.506867 p90: 38.7868 gap: 5.637494Performance-L median: 33.641301 min: 24.520566 max: 56.979893 p90: 39.543275 gap: 5.901974Performance-L median: 33.240067 min: 24.465739 max: 55.047212 p90: 38.829436 gap: 5.589369Performance-L median: 33.153557 min: 24.436181 max: 57.283823 p90: 39.028513 gap: 5.874956Performance-L median: 33.253388 min: 24.469155 max: 56.23663 p90: 39.080731 gap: 5.827343Performance-L median: 33.365856 min: 24.530846 max: 58.221103 p90: 38.927987 gap: 5.562131Performance-L median: 33.474059 min: 24.452235 max: 57.261853 p90: 39.033429 gap: 5.55937Performance-L median: 33.377405 min: 24.457819 max: 56.013569 p90: 39.439574 gap: 6.062169Performance-L median: 33.18613 min: 24.448132 max: 55.97101 p90: 38.788326 gap: 5.602196Performance-L median: 33.206655 min: 24.427332 max: 55.772113 p90: 39.396786 gap: 6.190131Performance-L median: 33.37626 min: 24.415945 max: 55.612905 p90: 38.867699 gap: 5.491439Performance-L median: 33.35998 min: 24.466882 max: 56.473504 p90: 38.692222 gap: 5.332242Performance-L median: 33.195184 min: 24.514021 max: 55.940698 p90: 38.534127 gap: 5.338943Performance-L median: 33.236541 min: 24.545259 max: 56.402501 p90: 38.833706 gap: 5.597165Performance-L median: 33.226747 min: 24.481826 max: 55.540641 p90: 38.953638 gap: 5.726891Performance-L median: 33.208703 min: 24.419002 max: 55.505751 p90: 38.992754 gap: 5.784051Performance-L median: 33.391428 min: 24.436124 max: 56.322456 p90: 39.198782 gap: 5.807354Performance-L median: 33.227844 min: 24.459769 max: 55.962177 p90: 38.579716 gap: 5.351872Performance-L median: 33.502672 min: 24.486693 max: 56.502288 p90: 39.379623 gap: 5.876951Performance-L median: 33.579692 min: 24.506387 max: 56.488952 p90: 40.697508 gap: 7.117816Performance-L median: 33.171936 min: 24.438047 max: 55.891178 p90: 38.870278 gap: 5.698342Performance-L median: 33.810464 min: 24.488188 max: 56.733773 p90: 39.505893 gap: 5.695429Performance-L median: 33.516345 min: 24.419439 max: 56.733229 p90: 39.290211 gap: 5.773866Performance-L median: 33.220229 min: 24.4702 max: 55.765064 p90: 39.07701 gap: 5.856781Performance-L median: 33.242103 min: 24.440306 max: 56.348611 p90: 38.978289 gap: 5.736186Performance-L median: 33.314216 min: 24.465667 max: 55.94946 p90: 39.098147 gap: 5.783931Performance-L median: 33.498975 min: 24.467894 max: 56.381511 p90: 39.378759 gap: 5.879784Performance-L median: 33.153709 min: 24.502003 max: 55.231898 p90: 38.896706 gap: 5.742997Performance-L median: 33.463899 min: 24.442991 max: 56.264853 p90: 40.081244 gap: 6.617345Performance-L median: 33.282983 min: 24.459897 max: 55.748531 p90: 39.216507 gap: 5.933524Performance-L median: 32.971102 min: 24.461271 max: 55.599843 p90: 38.584471 gap: 5.613369Performance-L median: 33.181704 min: 24.475951 max: 55.350814 p90: 38.831281 gap: 5.649577Performance-L median: 33.179738 min: 24.454074 max: 55.293447 p90: 38.778112 gap: 5.598374Performance-L median: 33.055691 min: 24.40425 max: 56.223292 p90: 38.785061 gap: 5.72937Performance-L median: 33.220991 min: 24.450547 max: 56.302966 p90: 38.94153 gap: 5.720539Performance-L median: 33.278964 min: 24.470519 max: 56.450312 p90: 39.050893 gap: 5.771929Performance-L median: 33.383103 min: 24.552978 max: 55.695857 p90: 39.02668 gap: 5.643577Performance-L median: 33.770272 min: 24.617069 max: 56.948857 p90: 39.83842 gap: 6.068148Performance-L median: 33.470906 min: 24.528785 max: 55.197891 p90: 38.9679 gap: 5.496994Performance-L median: 33.238429 min: 24.443633 max: 55.925002 p90: 38.765444 gap: 5.527015Performance-L median: 33.250761 min: 24.52053 max: 55.293693 p90: 39.072657 gap: 5.821896Performance-L median: 33.36464 min: 24.500599 max: 56.526375 p90: 39.206315 gap: 5.841675Local (MBP) median: 39.023785 min: 35.633777 max: 52.146773 p90: 47.460474 gap: 8.436689Local (MBP) median: 38.708792 min: 34.338647 max: 52.210714 p90: 44.766613 gap: 6.057821Local (MBP) median: 39.050487 min: 35.406298 max: 53.454308 p90: 47.216326 gap: 8.165839Local (MBP) median: 39.537426 min: 36.039595 max: 52.45466 p90: 47.047522 gap: 7.510096Local (MBP) median: 41.8507 min: 36.999501 max: 57.670145 p90: 49.288668 gap: 7.437968Local (MBP) median: 41.48293 min: 35.154924 max: 52.271806 p90: 49.025332 gap: 7.542402Local (MBP) median: 41.780267 min: 36.543002 max: 51.166694 p90: 47.831358 gap: 6.051091Local (MBP) median: 39.25118 min: 35.317724 max: 49.505028 p90: 45.582849 gap: 6.331669Local (MBP) median: 39.225347 min: 34.972593 max: 51.654565 p90: 48.667984 gap: 9.442637Local (MBP) median: 39.833928 min: 35.880744 max: 61.119091 p90: 48.057867 gap: 8.223939Local (MBP) median: 40.215912 min: 35.667371 max: 52.20022 p90: 47.158926 gap: 6.943014Local (MBP) median: 39.511525 min: 35.347304 max: 53.190336 p90: 46.368544 gap: 6.857019Local (MBP) median: 38.974407 min: 36.036677 max: 51.201369 p90: 46.911677 gap: 7.93727Local (MBP) median: 39.321308 min: 36.187822 max: 52.297261 p90: 44.999657 gap: 5.678349Local (MBP) median: 39.424523 min: 35.174946 max: 49.709798 p90: 45.514314 gap: 6.089791Local (MBP) median: 39.172425 min: 35.589056 max: 48.739931 p90: 45.607671 gap: 6.435246Local (MBP) median: 39.827372 min: 35.359934 max: 48.792063 p90: 46.203071 gap: 6.375699Local (MBP) median: 39.393101 min: 35.222276 max: 56.278151 p90: 47.547462 gap: 8.154361Local (MBP) median: 40.748493 min: 35.686625 max: 54.181269 p90: 47.948768 gap: 7.200275Local (MBP) median: 41.420718 min: 37.007438 max: 56.681937 p90: 49.246597 gap: 7.825879Local (MBP) median: 42.257924 min: 38.639585 max: 56.026612 p90: 48.374543 gap: 6.116619Local (MBP) median: 41.282033 min: 34.991365 max: 52.971776 p90: 48.484856 gap: 7.202823Local (MBP) median: 40.431866 min: 35.323612 max: 50.643484 p90: 47.436347 gap: 7.004481Local (MBP) median: 39.483259 min: 36.275758 max: 56.89724 p90: 45.662844 gap: 6.179585Local (MBP) median: 39.979557 min: 35.57999 max: 52.484988 p90: 46.114744 gap: 6.135187Local (MBP) median: 41.401029 min: 36.370039 max: 55.999452 p90: 48.523165 gap: 7.122136Local (MBP) median: 40.65473 min: 35.371266 max: 52.751009 p90: 47.795694 gap: 7.140964Local (MBP) median: 40.851174 min: 36.251968 max: 54.790781 p90: 49.279252 gap: 8.428078Local (MBP) median: 38.818955 min: 35.219607 max: 49.643954 p90: 44.511124 gap: 5.692169Local (MBP) median: 39.22306 min: 35.361572 max: 51.419536 p90: 46.089192 gap: 6.866132Local (MBP) median: 39.320302 min: 35.8185 max: 51.403447 p90: 45.948729 gap: 6.628427Local (MBP) median: 40.309992 min: 35.592695 max: 54.472465 p90: 48.313523 gap: 8.003531Local (MBP) median: 38.727089 min: 35.062009 max: 53.747042 p90: 46.885172 gap: 8.158083Local (MBP) median: 39.349415 min: 34.828817 max: 50.036419 p90: 46.630694 gap: 7.281279Local (MBP) median: 39.670457 min: 34.664665 max: 52.896951 p90: 46.31565 gap: 6.645193Local (MBP) median: 39.30446 min: 35.395627 max: 50.609639 p90: 46.146418 gap: 6.841958Local (MBP) median: 39.371475 min: 34.763752 max: 53.261253 p90: 45.898499 gap: 6.527024Local (MBP) median: 40.573439 min: 35.464184 max: 53.632537 p90: 46.813475 gap: 6.240036Local (MBP) median: 39.559034 min: 34.993662 max: 52.487625 p90: 47.808518 gap: 8.249484Local (MBP) median: 40.083335 min: 35.009671 max: 53.846603 p90: 46.887693 gap: 6.804358Local (MBP) median: 40.946362 min: 36.305722 max: 52.851701 p90: 47.896927 gap: 6.950565Local (MBP) median: 40.12573 min: 35.299422 max: 52.067668 p90: 46.419647 gap: 6.293917Local (MBP) median: 40.466559 min: 35.212767 max: 51.66192 p90: 46.836175 gap: 6.369616Local (MBP) median: 40.518687 min: 34.992197 max: 51.188287 p90: 47.016343 gap: 6.497656Local (MBP) median: 40.201863 min: 35.878828 max: 51.77675 p90: 48.183227 gap: 7.981364Local (MBP) median: 39.880719 min: 35.028447 max: 55.739214 p90: 48.097445 gap: 8.216726Local (MBP) median: 41.253759 min: 36.171435 max: 56.110783 p90: 48.899998 gap: 7.646239Local (MBP) median: 39.826508 min: 34.996808 max: 49.59464 p90: 46.840983 gap: 7.014475Local (MBP) median: 40.44113 min: 35.585421 max: 51.925027 p90: 47.290277 gap: 6.849147Local (MBP) median: 41.107379 min: 35.934298 max: 55.706431 p90: 48.404856 gap: 7.297477Local (MBP) median: 39.691213 min: 35.422005 max: 52.299576 p90: 46.379373 gap: 6.68816Local (MBP) median: 39.87371 min: 35.372691 max: 51.454152 p90: 46.474771 gap: 6.601061Local (MBP) median: 40.307042 min: 35.430962 max: 52.982597 p90: 46.635384 gap: 6.328342Local (MBP) median: 41.153255 min: 34.902881 max: 53.057356 p90: 48.802344 gap: 7.649089Local (MBP) median: 40.381538 min: 35.686522 max: 55.465654 p90: 48.081956 gap: 7.700418Local (MBP) median: 39.915014 min: 35.457711 max: 51.676044 p90: 46.939304 gap: 7.02429Local (MBP) median: 39.638205 min: 35.672384 max: 54.750726 p90: 45.293659 gap: 5.655454Local (MBP) median: 39.667094 min: 35.854923 max: 54.315713 p90: 48.331783 gap: 8.664689Local (MBP) median: 40.22903 min: 35.748313 max: 53.708417 p90: 48.213845 gap: 7.984815Local (MBP) median: 39.840065 min: 35.97642 max: 53.224951 p90: 46.414377 gap: 6.574312Local (MBP) median: 40.064962 min: 35.524653 max: 58.251053 p90: 46.011411 gap: 5.946449Local (MBP) median: 39.590954 min: 35.424312 max: 50.647106 p90: 45.333128 gap: 5.742174Local (MBP) median: 38.289382 min: 34.973131 max: 50.653489 p90: 45.762925 gap: 7.473543Local (MBP) median: 38.538916 min: 34.72183 max: 49.666791 p90: 46.062784 gap: 7.523868Local (MBP) median: 38.76872 min: 34.244128 max: 53.248024 p90: 45.394766 gap: 6.626046Local (MBP) median: 38.564512 min: 34.862232 max: 50.711591 p90: 45.869678 gap: 7.305166Local (MBP) median: 39.705282 min: 35.438702 max: 46.683252 p90: 45.143156 gap: 5.437874Local (MBP) median: 40.775438 min: 35.997042 max: 52.691918 p90: 48.358891 gap: 7.583453Local (MBP) median: 40.497056 min: 36.339539 max: 55.469391 p90: 47.307525 gap: 6.810469Local (MBP) median: 40.193255 min: 35.395991 max: 51.40894 p90: 46.623548 gap: 6.430293Local (MBP) median: 39.895032 min: 35.580086 max: 52.528869 p90: 48.981005 gap: 9.085973Local (MBP) median: 40.517288 min: 36.021653 max: 51.861117 p90: 47.548293 gap: 7.031005Local (MBP) median: 39.997834 min: 35.080106 max: 51.588679 p90: 46.802218 gap: 6.804384Local (MBP) median: 40.553409 min: 36.131535 max: 54.294731 p90: 47.734327 gap: 7.180918Local (MBP) median: 39.619133 min: 35.286721 max: 50.87366 p90: 45.468024 gap: 5.848891Local (MBP) median: 39.840997 min: 35.761686 max: 52.265191 p90: 47.892782 gap: 8.051785Local (MBP) median: 39.930467 min: 34.856904 max: 49.050287 p90: 46.046301 gap: 6.115834Local (MBP) median: 39.051003 min: 35.484453 max: 50.38737 p90: 46.60682 gap: 7.555817Local (MBP) median: 40.261527 min: 35.163247 max: 50.868362 p90: 46.99211 gap: 6.730583Local (MBP) median: 40.251256 min: 36.005284 max: 51.46636 p90: 47.130706 gap: 6.87945Local (MBP) median: 38.935253 min: 34.934993 max: 48.858449 p90: 45.488403 gap: 6.55315Local (MBP) median: 39.575767 min: 35.276984 max: 51.592718 p90: 47.019688 gap: 7.443921Local (MBP) median: 41.087437 min: 35.673034 max: 50.645931 p90: 46.603622 gap: 5.516185Local (MBP) median: 39.512755 min: 35.410418 max: 61.21417 p90: 47.960366 gap: 8.447611Local (MBP) median: 40.292721 min: 34.519724 max: 51.877397 p90: 47.702655 gap: 7.409934Local (MBP) median: 39.936764 min: 35.261429 max: 52.920527 p90: 46.906171 gap: 6.969407Local (MBP) median: 40.855471 min: 35.414108 max: 51.773223 p90: 47.982988 gap: 7.127517Local (MBP) median: 41.512314 min: 36.152233 max: 52.198012 p90: 49.480049 gap: 7.967735Local (MBP) median: 40.683681 min: 35.447216 max: 50.55344 p90: 46.030318 gap: 5.346637Local (MBP) median: 38.736386 min: 35.331391 max: 53.34118 p90: 46.619998 gap: 7.883612Local (MBP) median: 39.896184 min: 35.02781 max: 53.666428 p90: 47.136396 gap: 7.240212Local (MBP) median: 39.971008 min: 34.726433 max: 51.487733 p90: 48.328983 gap: 8.357975Local (MBP) median: 40.838663 min: 34.869445 max: 51.664201 p90: 48.145528 gap: 7.306865Local (MBP) median: 40.6119 min: 34.747872 max: 50.369426 p90: 46.358633 gap: 5.746733Local (MBP) median: 39.521091 min: 34.69888 max: 51.180865 p90: 46.110734 gap: 6.589643Local (MBP) median: 39.739965 min: 34.675984 max: 50.151906 p90: 46.182131 gap: 6.442166Local (MBP) median: 38.983523 min: 34.557818 max: 50.805277 p90: 46.497565 gap: 7.514042Local (MBP) median: 39.304509 min: 34.823989 max: 53.429258 p90: 45.752565 gap: 6.448056Local (MBP) median: 39.2663 min: 35.270865 max: 52.056314 p90: 45.662589 gap: 6.396289Local (MBP) median: 38.356604 min: 34.759875 max: 50.884558 p90: 45.937289 gap: 7.580685

As you can see, there are clear differences between the shared & dedicated dyno sizes. That comes as no surprise, but it was interesting to see that the fastest free samples were faster than the slowest hobby or standard-1x dynos. I had assumed that free were relegated to their own extremely cheap underlying instance type, but it appears that may not be the case (more on this in a moment). Otherwise, I was also surprised to see that the paid+shared dyno classes - hobby, standard-1x, standard-2x - blend together to the degree they do.

The benchmark and visualization illustrate more or less what Heroku’s documentation says about the different dyno classes; free, hobby, and standard-1x all have the same degree of “CPU share”, which seems to correspond to the width of the clusters. standard-2x, with its double CPU share, has a tighter cluster, but still exhibits high variance. Then there are the dedicated instances with extremely tight clusters of small points, indicating consistently quick performance.

The following illustration shows how the average variance changes based on dyno type.

Performance-LLocal (MBP)Performance-MStandard 2xStandard 1xHobbyFreePerformance-L: 5.66msLocal (MBP): 7.04msPerformance-M: 20.44msStandard 2x: 53.1msStandard 1x: 50.15msHobby: 52.34msFree: 134.95ms

There is about an order of magnitude difference in the variance between a performance-l and the shared dynos. Granted, that difference amounts to ~45ms which is likely just noise for many workloads. And at (at least) 10x the price, a performance-l is difficult to justify for anything besides a professional application.

Behind the abstraction

After observing the benchmark performance across dyno classes, it’s worth asking what the underlying AWS instance types are for each of the dyno classes. In particular, were free dynos running on the same instances as paid dynos? Did a dedicated dyno in a performance class have its own AWS instance, or were they also clustered, but in such a way that there were always CPUs available for them?

Thankfully, because Linux containers are essentially sandboxed apps on an underlying kernel, it’s possible to poke around a bit. Launching a one-off dyno of each instance class via heroku run bash --app <app here> --size <dyno class> makes it trivial to extract some basic information about the underlying instance. I initially checked uname -a for each dyno class, and found all of them running the same version of AWS Linux. Nothing surprising there.

Next up was taking a look at /proc/cpuinfp and /proc/meminfo. The following table lays out the results as of April 2021:

Dyno class Num cores Core type Memory
free 8 core Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz 64GB
hobby 8 core Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz 64GB
standard-1x 8 core Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz 64GB
standard-2x 8 core Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz 64GB
performance-m 2 core Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz 4GB
performance-l 8 core Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz 16 GB

Turns out that all shared CPU dynos run on the same instance type. That makes a lot of sense from an infrastructure management perspective, but I was still surprised to see that free dynos run on the same instance type as paid dynos. This doesn’t mean that free dynos are necessarily neighbors with paid dynos though - Heroku could configure the dyno manager to label some cluster nodes as free and others as paid. That would prevent free dynos from impacting the performance of paid dynos, but this is just speculation, I have no idea if Heroku does this. Additionally, the /proc/cpuinfo confirms each performance dyno runs on its own dedicated instance.

Armed with the instance specs, it is straightforward to look up the underlying AWS instance type. The shared CPU dynos appear to run on storage optimized instances. That initially puzzled me, but it makes a fair bit of sense when remembering that Heroku is running Linux containers. Each container consumes a relatively limited amount of memory but could consume several GB of space on disk. So if you wanted to pack as many containers onto a machine as possible, you’d want something that could store a lot of decompressed images.

Performance dynos unsurprisingly appear to run on compute-optimized instances, exactly what Heroku bills them as.

What it all means

By this point two things are clear. First, the shared vs. dedicated dyno options at Heroku have vastly different performance profiles. These differences in performance are less about per-core speed than they are about the variance. Secondly, while dynos within the same “tier” demonstrate different performance characteristics from one another, they are not significant on a per-core level. The inter-tier differences come from memory and core count, which isn’t particularly surprising.

I that by providing you with a deeper understanding of how Heroku’s different dyno classes perform - albeit in a contrived benchmark - you’ll be better able to evaluate which one is the best fit for your application’s workload. For example, if you’re running a webserver with a fairly low memory footprint that mostly performs CRUD, an auto-scaled cluster of shard-CPU dynos is probably the most cost-effective solution. On the other hand, if the application provides middleware on the critical path for a frontend server you likely care a lot about having consistent performance, so one of the dedicated dynos would be a better fit. Unfortunately, Heroku’s documentation doesn’t illustrate just how divergent the behavior of these two classes is, so I’ve had to learn the hard way. Hopefully this post helps you avoid most of my mistakes around sizing dynos to application needs.

Benchmarking Heroku

The benchmark used for this experiment was inspired by the behavior observed on production applications across several languages. I’d been aware of the variability in response times for a long time, but it wasn’t until upgrading a Rails app from shared to dedicated dynos and watching the variability in p99 latency dramatically drop that I began wondering about the exact behavior. That led me to write a benchmark to trigger a sustained CPU-intensive workload on Heroku dynos.

The benchmark is simple, consisting of a Node app that loads and parses a 5MB JSON file in a loop. It performs 100 iterations per-request and returns some statistics about the batch of parsing performed. I also experimented with an empty loop, but found the JSON to be a more indicative workload to the issues I’ve experienced in production.

The benchmark data used for this analysis was collected by running 100 requests against each dyno size and aggregating the results.

Things I did not do:

  1. Run multiple tests per-dyno class
  2. Vary the time of day
  3. Control for garbage collection

All of those are interesting areas to explore in the future if warranted.

The code is on Github.