{"id":6469,"date":"2016-09-19T15:22:59","date_gmt":"2016-09-19T19:22:59","guid":{"rendered":"http:\/\/blog.litespeedtech.com\/?p=6469"},"modified":"2016-09-19T15:22:59","modified_gmt":"2016-09-19T19:22:59","slug":"democracy-and-the-benchmark","status":"publish","type":"post","link":"https:\/\/lswp.store\/index.php\/2016\/09\/19\/democracy-and-the-benchmark\/","title":{"rendered":"Democracy and the Benchmark"},"content":{"rendered":"<p>It seems like we\u2019re entering the YouTube era of benchmarking.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6577\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/aliens.jpg\" alt=\"aliens\" height=\"460\" srcset=\"https:\/\/lswp.store\/wp-content\/uploads\/2016\/09\/aliens.jpg 539w, https:\/\/lswp.store\/wp-content\/uploads\/2016\/09\/aliens-289x300.jpg 289w\" sizes=\"(max-width: 539px) 100vw, 539px\" \/><\/p>\n<p>You know how you can go on YouTube and find someone who knows almost nothing about the subject they are posting a video about? Well, benchmarking these days is kind of like that\u2026<\/p>\n<p><!--more--><\/p>\n<p>Just a quick word about the author. I worked as a senior engineer with Mercury Interactive. Mercury\u2019s LoadRunner tool was\/is the industry standard for performance testing\/benchmarking. I\u2019ve spent 17 years trying to make people smarter about how they test and tune their systems. I also worked extensively with the ActiveTest group within Mercury, and I\u2019m going to use some of the methods and procedures gleaned over thousands of customers and millions of dollars of R&amp;D to develop the ActiveTest products.<\/p>\n<p>I have to say, I am dismayed at some of the nonsense that I see people posting.<\/p>\n<p>There really isn\u2019t a polite way to say it. Some of these folks don\u2019t even know the basics, so I thought it might make sense to write this post that explains Benchmarking 101. The goal of the post is to hopefully instill the rigor that we\u2019ve seemingly lost and get back to doing intelligent investigation of data and system performance.<\/p>\n<h3>Bad Tooling<\/h3>\n<p>I will admit that I am biased towards LoadRunner since it is the tool that I know. Any number of tools can generate load in competent hands. For the purposes of this article, I will refer to four components of tooling using ideas from LoadRunner, but you should expand them to whatever tool you use. The four components are:<\/p>\n<ul>\n<li>a script that hits your test site<\/li>\n<li>a controller that monitors the test and provides some feedback<\/li>\n<li>a load injector(s) that scale(s) your script to multiple running users<\/li>\n<li>some kind of analysis of the output<\/li>\n<\/ul>\n<p>I\u2019m just going to start with a simple statement. If your test tool is something that you run from a command line, your test results are pretty much worthless. If you run a simple google search, you can find dozens of options that help you produce more reliable results. Tools like Siege, weighttp, etc. tend to be used by very unsophisticated testers because they are free, but generally, more so because they are simple.<\/p>\n<p><code>weighttp -n 100000 -c [0-1000 step:10 rounds:3] -t 8 -k \"http:\/\/x.x.x.x:80\/index.html\"<\/code><\/p>\n<p>I\u2019m sorry, but doing an accurate, meaningful benchmarking exercise isn\u2019t a single command line. If you are making any claims beyond some very basic pass\/fail stuff, this is useless.<br \/>\nA lot of online tools are available for use, but there are many issues with using them. First and foremost is the lack of control and visibility into conditions. Pingdom and webpagetest.org are good for spot checking performance, but not at all useful for a benchmark. Benchmarking needs to be done in a controlled environment to have any comparative value.<\/p>\n<h3>Good Benchmarking Practices<\/h3>\n<p>Let\u2019s face it, most of the benchmarks we see published are extremely grandiose in their claims. 13X performance? What does that mean?<\/p>\n<p>Nothing. Nothing at all.<\/p>\n<p>Before you begin, you need to have something you want to test, and a scientifically accurate way to measure it. 13X is a comparative statement. 13X what? How was X measured? Did you measure 13X using the same methodology? Was your test environment under control?<\/p>\n<p>Looking back at the four components, let\u2019s investigate good testing practices.<\/p>\n<p>It all starts with a script. What are you trying to emulate? If you script people browsing catalog pages, does that mean that the checkout process is 13X faster too? How data dependent is your script- are you passing multiple logins and passwords? You aren\u2019t if you run a command line\/online tool\u2026<\/p>\n<p>Your controller environment is where you simulate the scenario behavior. Do all of my users arrive at one time (like a holiday sale?) or do they ramp up to help understand where my breaking points are? Are they all doing the same thing, or different things?<\/p>\n<p><strong><em>How you pair your script and scenario DEFINES what you are testing. This needs to match your goal for the test.<\/em><\/strong><\/p>\n<p>I\u2019ll say that again. Those two components define the condition you are testing. If you see someone publish a benchmark without defining the test conditions or extrapolating it to things not defined in those components, the odds are pretty good that they don\u2019t know anything at all about benchmarking.<\/p>\n<p>And, usually, they prove that they don\u2019t know by the next step\u2026<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter size-full wp-image-6587\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/infinite.jpg\" alt=\"To Infinity And Beyond!\" width=\"517\" height=\"408\" srcset=\"https:\/\/lswp.store\/wp-content\/uploads\/2016\/09\/infinite.jpg 517w, https:\/\/lswp.store\/wp-content\/uploads\/2016\/09\/infinite-300x237.jpg 300w\" sizes=\"(max-width: 517px) 100vw, 517px\" \/><\/p>\n<p>The load injector has finite capacity. If you see benchmark data that suggests that a load injector seems infinitely scalable, you should probably ignore the results they publish. A simple litmus test is that it takes as much or more hardware to generate load as it does to respond to it. The injector needs to receive all of the data sent by the web server and make sure that the request completes successfully&#8230;. And thus, should be on a separate platform from the web server! Good practice is to benchmark your injectors to know exactly how much load they are capable of generating without producing errors.<\/p>\n<p>Lastly, analysis should be automated. In my experience, it is pretty easy to edit away data that suggests problems, so you need to remove that possibility if you are trying to provide a valid benchmark. All of the data should be used, and the data should not contain any error status codes. Vendors all want their products to shine, and that can lead to shenanigans.<\/p>\n<p>So, what are good practices?<\/p>\n<p>Start with a proof statement. Develop a test that exercises only that proof. Validate your test environment. Use automation to collect data and prepare results transparently. Explain anything that falls outside the model.<\/p>\n<p>What is the anatomy of a poorly designed benchmark?<\/p>\n<p>If you use a command line tool, or test without control over the scenario, or test without visibility into a scenario, or drive infinite load with your VM, or use Excel to report&#8230;you are practicing bad benchmarking. If you have data that you cannot explain, making something up.<\/p>\n<h3>Understanding Data and Relationships<\/h3>\n<p>Web performance data is a discipline ruled by mathematics.<\/p>\n<p>There is no politically correct way to say this other than there are a lot of people doing garbage work these days. Aside from the bad testing practices, if you do not understand the data you collect, it is really difficult to explain what happened. It is even worse, if you just start fabricating conclusions. Many of these people are viewed as experts, but they lack a basic understanding of the fundamentals of web performance. It\u2019s time to expose.<\/p>\n<p>Let\u2019s start with the basics. (Understanding relationships)<\/p>\n<p>If I told you that I was going to drive from point A to point B as fast as I could, you would easily be able to calculate how long the trip should take through simple math (distance\/speed). A simple mathematical relationship defines time, distance, and speed as a functional relationship. Think of this as an analogy for baseline performance of a single web user.<\/p>\n<p>However, we live in the real world, and we have to share the road. If the road has more lanes, it can handle more cars. If the cars are well coordinated, traffic flows well and our round trip time stays about the same. Think of this as an analogy for a healthy system.<\/p>\n<p>But, what happens when you have more cars than road capacity?<\/p>\n<p>Traffic causes congestion, or a slowing of the round trip time. Even though the road hasn\u2019t changed, its ability to handle traffic deteriorates. Any given road can handle some load of cars. Think of this as an analogy for hits\/requests per second. These are measures of performance.<\/p>\n<p>Another physical limitation of a road is the physical size and width of the road. If you consider a Smart car or a VW Beetle vs. a double trailer semi truck, you can see that they will occupy a different footprint on the road. While you might have enough physical space for one of those trucks, it could probably fit 5-6 of the mini cars. Think of this idea as an analogy for throughput. Throughput is a measure of capacity.<\/p>\n<p>We will use these concepts to describe benchmarking and how it models to the road analogy throughout the rest of this post.<\/p>\n<h3>Let\u2019s benchmark!<\/h3>\n<p>In the following scenario, I have written a simple script that visits a web page. Every time the script finishes, it resets and starts over. Every 10 seconds, a new user joins the scenario, repeating the script in the same manner.<\/p>\n<p>But\u2026 remember the first covenant of a benchmark?<\/p>\n<p><i>What are you trying to show\/prove?<\/i><\/p>\n<p>For this specific run, I will be illustrating one simple idea: what a healthy load looks like and the metrics that show the mathematical relationships between number of users, hits\/sec, connections, and throughput when your test systems are functioning well during a benchmarking exercise&#8230;and when you need to stop to investigate.<\/p>\n<p>Using the traffic analogy, I am attempting to figure out how many cars I can add to the road before I start seeing traffic delays\u2026 sort of (we will discuss this in further detail later).<\/p>\n<div style=\"text-align: center; margin-bottom: -13px;\">Graph #1 (Running virtual users)<\/div>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6477\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/Report0.png\" alt=\"Benchmarking 101 - Report0\" width=\"802\" height=\"296\" \/><\/p>\n<p>In this graph, you can see that the number of users is scaling slowly. By taking this approach, we can watch the other graphs in the tool and make sure that everything is performing up to expectations.<\/p>\n<div style=\"text-align: center; margin-bottom: -13px;\">Graph #2 (Hits per second)<\/div>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6479\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/Report1-lined.png\" alt=\"Benchmarking 101 - Report1\" width=\"802\" height=\"296\" \/><\/p>\n<div style=\"text-align: center; margin-bottom: -13px;\">Graph #4 (Connections)<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6483\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/Report3.png\" alt=\"Benchmarking 101 - Report3\" width=\"802\" height=\"296\" \/><\/p>\n<p>It seems pretty obvious to say that a single user generates a \u201chit\u201d (or a request for a resource from the web server via a connection), and that two users would generate twice as many, three users three times as many, etc.<\/p>\n<p>There is a mathematical relationship between the number of users running and hits\/requests per second. They are linear, meaning that as one scales the other follows it. This relationship holds true from one user to any number of users.<\/p>\n<p>Think of this as the cars on the road. As long as there is no bottleneck in traffic, you can add more cars without impacting commute time. As long as the server isn\u2019t overly busy, it creates the connection and sends the files.<\/p>\n<div style=\"text-align: center; margin-bottom: -13px;\">Graph #3 (Throughput)<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6481\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/Report2.png\" alt=\"Benchmarking 101 - Report2\" width=\"802\" height=\"296\" \/><\/p>\n<div style=\"text-align: center; margin-bottom: -13px;\">Graph #4 (Connections)<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6483\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/Report3.png\" alt=\"Benchmarking 101 - Report3\" width=\"802\" height=\"296\" \/><\/p>\n<p>In exactly the same way that users and hits correlate, so will throughput and connection requests <strong>in a well behaving benchmark<\/strong>. If you do not see this mathematical relationship between the numbers, stop. Something is broken. Yet another reason that command line\/online tools are useless- there is no visibility during the benchmark.<\/p>\n<p><strong><em>Graphs 1-4 ALWAYS move together linearly in systems that are performing well, independent of scale.<\/em><\/strong><\/p>\n<div style=\"text-align: center; margin-bottom: -13px;\">Graph #5 (Passed transactions)<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6485\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/Report4.png\" alt=\"Benchmarking 101 - Report4\" width=\"802\" height=\"296\" \/><\/p>\n<div style=\"text-align: center; margin-bottom: -13px;\">Graph #6 (HTTP status codes)<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6487\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/Report5.png\" alt=\"Benchmarking 101 - Report5\" width=\"802\" height=\"296\" \/><\/p>\n<p>Assuming that all of the mathematically bound graphs are moving well together, you need to validate that there were no errors being returned by the server during the test run. If you look at these graphs, you see nothing but passed transactions and 200 and 302 status codes (a normal redirect, not an error). Any 4XX or 5XX HTTP status codes mean that your web server was not able to handle a request (HTTP Status codes are only returned by a web server).<\/p>\n<div style=\"text-align: center; margin-bottom: -13px;\">Graph #7 (Transaction Response time- also, why I stopped this run!)<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6489\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/report6-lined.png\" alt=\"Benchmarking 101 - report6\" width=\"802\" height=\"296\" \/><\/p>\n<p>While the run didn\u2019t have a specific performance goal, it is pretty typical to watch transaction performance during a benchmark to get a sense of a few metrics:<\/p>\n<p>1.) What is my no load performance? Here, that occurs around 10s or so into the test and is about 2.7s.<\/p>\n<p>2.) What point does the number of users drive the performance above the threshold of acceptable performance? Let\u2019s pretend that it was 3s and that occurs around 2:30 into the test, which can be referenced back to 16 virtual users running.<\/p>\n<p>3.) What point does the system begin to fail? While this specific test was terminated prior to errors being present, it appears that response times were beginning to grow which indicates there is a problem.<\/p>\n<p>So, I aborted this run\u2026 simply because I had the data I needed for this blog post.<\/p>\n<h3>Garbage in, Garbage Out<\/h3>\n<p>I have a little confession to make. I know what the bottleneck in this test was. I was running the injector on my laptop, which also had the controller\u2026 and my e-mail and a bunch of other things open. My laptop began to run out of resources. At the end of the test run, you can see response times jump way up. That is a behavior that occurs consistently with the hard interruption\/termination of the tool I use, and has been observed dozens of times.<\/p>\n<p><em>I thought you said not to use the load injector to monitor?<\/em><\/p>\n<p>I did, and for this very reason\u2026 however, I know what the limits of my laptop are for this type of work, because <strong>I have benchmarked its capability as a load injector<\/strong>. However, in this case, I\u2019m also using it to illustrate what I call an <strong><em>\u201cillogical conclusion\u201d<\/em><\/strong>.<\/p>\n<p>What is a garbage conclusion? Frankly, it is nothing more than a lazy guess. In some cases, it is even worse than that: it is a bad guess that goes completely against what the data is saying.<\/p>\n<p>In my example, you might conclude that the web server was slowing down and about to break, because that is what the data looks like it is saying. In reality, the server was perfectly healthy and returning data to the injector as fast as the no load performance. It was the injector that was unable to process it in a timely manner.<\/p>\n<p><strong>If you overdrive your load injector, it will blow up your test results.<\/strong><\/p>\n<p>Simply put, if you understand the mathematical relationships between the data in healthy systems, you need to stop and investigate what is going on when those relationships no longer work. It\u2019s not rocket science, but it <em>is<\/em> science.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-large wp-image-6499\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/meltdown.jpg\" alt=\"meltdown\" height=\"450\" \/><\/p>\n<p>Simply opening a browser from an independent PC during a benchmark to inspect system behavior can show you if it is your web server or your load injector.<\/p>\n<h3>Real world examples of Bad Benchmarking and Illogical Conclusions<\/h3>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6501\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/Abraham.jpg\" alt=\"Abraham\" height=\"450\" \/><\/p>\n<p>First, let me say that I have no other purpose in writing this article except to correct errors out in the community, which is filled with bad benchmarks and misunderstanding. It is a little bit self-serving, though, since I spend a LOT of time defending our products against bad benchmarking\/garbage conclusions. Hopefully, this blog post will clear up some of the bad practices and force people to adopt industry standard practices.<\/p>\n<h4>Example #1<\/h4>\n<p><a href=\"https:\/\/www.rootusers.com\/linux-web-server-performance-benchmark-2016-results\/\">https:\/\/www.rootusers.com\/linux-web-server-performance-benchmark-2016-results\/<\/a><\/p>\n<p>Well, if you read the comments, you\u2019ll see that I try to explain it to him, as I would love to know how we stack up against the competition, but there is so much wrong with everything he\u2019s done that you simply cannot use any of it. I think my last comment has made him pause, as it is reflected by the graphs posted above.<\/p>\n<p>Here\u2019s an easy way to understand why this is Bad Benchmarking and Illogical Conclusions.<\/p>\n<p>If you look at his plot of running virtual users against requests per second, you don\u2019t see the linear relationship as illustrated in my graphs above. 100 users generate the same load as 500 as does 1000?<\/p>\n<p>If that was true, you wouldn\u2019t need to build a bigger server to support a larger user load, since it generates the same number of requests and throughput no matter how many users are running.<\/p>\n<p>Clearly, this test was broken from the start and the results are meaningless, but the tests run on for hours because he is running a command line tool and has no visibility into the fact that his benchmark isn\u2019t doing anything.<\/p>\n<p>It is quite possible that he overworked his load injector similar to my example, because if you refer back to my hits\/sec and throughput graphs, you\u2019ll see that they begin to plateau towards the end of the test run. This is a behavior consistent with an overworked load injector. This is nothing more than an educated guess (opinion)- the data is useless (fact).<\/p>\n<h4>Example #2<\/h4>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=I1_V2u-AUmA&amp;feature=youtu.be\">https:\/\/www.youtube.com\/watch?v=I1_V2u-AUmA&amp;feature=youtu.be<\/a><\/p>\n<p>I don\u2019t even know where to begin with this one.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6505\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/whitaker.jpg\" alt=\"Whitaker Eye\" height=\"350\" \/><\/p>\n<p>For starters, it is at a national conference where he is being touted as an expert in the subject by the vendor, but I\u2019m going to quickly dispel that myth. This presentation touches on almost every point I\u2019ve mentioned about Bad Benchmarking and Illogical Conclusions, but once again, I\u2019ll limit my analysis to just a couple of key points to prove that this benchmark is worthless.<\/p>\n<p>At about 6 minutes in, the presenter shows us the command line test interface he\u2019s going to use to make his expert analysis.<\/p>\n<p>Siege.<\/p>\n<p>What can you see while running Siege? Nothing. I\u2019ve beaten this topic to death, so refer back throughout if you need to refresh on why a single command line is insufficient for benchmarking. When your test has no UI and things start to break down, you are dead in the water.<\/p>\n<p>At 8 minutes in, the presenter starts discussing results. Remember that linear relationship between the number of users and requests\/sec? Do you see it? No. Does that stop him from discussing the results? Not for a second. Instead of trying to figure out what went wrong, he actually tries to explain it!<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-large wp-image-6507\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/you-had-one-job.jpg\" alt=\"You had one job\" height=\"550\" \/><\/p>\n<p>Every purple graph shows that there was something wrong very early on in the test. Well established linear relationships are not evident in any of them. At 12:45, we can see that performance actually gets better at 100 users than at 50 users! Anomalies like that REQUIRE explanations. It\u2019s like suggesting 50 more cars on the road will make a traffic jam go away!<\/p>\n<p>Let\u2019s focus on the graph at 12:22, because it makes absolutely no sense. If you ignore the broken purple data, and just look at the pink line&#8230;at 50 users, it looks like ~20K transactions, but at 100 users it is ~90K transactions? 4.5X the rate for 2X the users? Huh? Where is that transaction load coming from if our baseline data is good? We go to 300 users at 130K transactions? 3X the users and 1.5X the rate? This is a classic plateau being reached, but not when, where, or why the presenter concludes.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6509\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/Replot.png\" alt=\"Replot\" width=\"538\" height=\"320\" \/><\/p>\n<p>When your data is all over the map and doesn\u2019t follow the mathematical model, you better start over. His non-linear scale on the X axis makes his data appear much more linear than it actually is. When replotted, you can clearly see the plateau. It is also much more obvious that his problems start around 100 users, if not before.<\/p>\n<p>When you hit plateaus in benchmarking, it is critical to have some sophisticated error handling in your test scripts. It\u2019s pretty common for a server to be much larger and more capable of handling requests, so you need to make sure that your test environment is not only capable of handling the sending of the request, but the processing of the response as well. Many times, the server will mishandle requests (e.g. send back incomplete pages) or customer error pages rather than 404s (\u201cWe\u2019re experiencing issues\u201d error page with a clean HTTP 200 Status OK). I cannot begin to guess what the server was sending back, but I know it wasn\u2019t functioning Magento pages.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6511\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/deming.jpg\" alt=\"Deming\" height=\"350\" \/><\/p>\n<p>I\u2019m fond of this Deming quote, but perhaps it should be amended to say \u201cwithout data that makes sense, &#8230;\u201d<\/p>\n<h3>Benchmarking 101 Conclusions<\/h3>\n<p>As one of my friends once explained to me, <strong>\u201cif you can\u2019t say it simply, you don\u2019t understand it well enough.\u201d<\/strong><\/p>\n<p>So, here goes my summary:<\/p>\n<p>All data in this type of benchmarking should be straight lines and linear relationships. If you aren\u2019t getting straight lines with a constant slope as user load scales, stop and figure out why. You aren\u2019t doing anything useful if you don\u2019t correct problems.<\/p>\n<p>And never argue against the math and the model&#8230;<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6513\" style=\"margin: 20px;\" src=\"http:\/\/blog.litespeedtech.com\/wp-content\/uploads\/2016\/09\/school.png\" alt=\"6th Grade Math\" height=\"450\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>You know how you can go on YouTube and find someone who knows almost nothing about the subject they are posting a video about? Well, benchmarking these days is kind of like that.<\/p>\n","protected":false},"author":1,"featured_media":6605,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[16,27,20],"tags":[],"class_list":["post-6469","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-benchmarks","category-web-server","category-performance"],"jetpack_featured_media_url":"https:\/\/lswp.store\/wp-content\/uploads\/2016\/09\/infinite-1.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts\/6469","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/comments?post=6469"}],"version-history":[{"count":0,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts\/6469\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/media\/6605"}],"wp:attachment":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/media?parent=6469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/categories?post=6469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/tags?post=6469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}