{"id":55340,"date":"2020-12-16T08:00:56","date_gmt":"2020-12-16T16:00:56","guid":{"rendered":"https:\/\/github.blog\/?p=55340"},"modified":"2021-12-20T14:44:20","modified_gmt":"2021-12-20T22:44:20","slug":"reducing-flaky-builds-by-18x","status":"publish","type":"post","link":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/","title":{"rendered":"Reducing flaky builds by 18x"},"content":{"rendered":"<p><em>Part of the\u00a0<a href=\"https:\/\/github.blog\/2020-10-29-building-github-introduction\/\" rel=\"nofollow\">Building GitHub blog series<\/a>.<\/em><\/p>\n<p>It\u2019s four o\u2019clock in the afternoon as you push the last tweak to your branch. Your teammate already reviewed and approved your pull request and now all that\u2019s left is to wait for CI. But, fifteen minutes later, your commit goes red. Surprised and a bit annoyed because the last five commits were green, you take a closer look only to find a failing test unrelated to your changes. When you run the test locally, it passes.<\/p>\n<p>Half an hour later, after running the test again and again locally without a single failure and retrying a still-red CI, you\u2019re no closer to deploying your code. As the clock ticks past five, you retry CI once more. But this time, something is different: it\u2019s green!<\/p>\n<p>You deploy, merge your pull request, and, an hour later than expected, close your laptop for the day.<\/p>\n<p>This is the cost of a flaky test. They\u2019re puzzling, frustrating, and waste your time. And try as we might to stop them, they\u2019re about as common as a developer who brews pour-over coffee every morning (read: very).<\/p>\n<p>Bonus points if you can guess what caused the test to fail.<\/p>\n<h2 id=\"how-far-weve-come\"><a class=\"heading-link\" href=\"#how-far-weve-come\">How far we&#8217;ve come<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>Earlier this year in our monolith, 1 in 11 commits had at least one red build caused by a flaky test, or about 9 percent of commits. If you were trying to deploy something with a handful of commits, there was a good chance you\u2019d need to retry the build or spend time diagnosing a failure, even if your code was fine. This slowed us down.<\/p>\n<p>Six weeks ago, after introducing a system to manage flaky tests, the percentage of commits with flaky builds dropped to less than half a percent, or 1 in 200 commits.<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55344\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/commits-with-flaky-builds.png?resize=1024%2C384\" alt=\"Chart showing number of commits with flakey builds month over month\" width=\"1024\" height=\"384\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/commits-with-flaky-builds.png?w=2318 2318w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/commits-with-flaky-builds.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/commits-with-flaky-builds.png?w=768 768w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/commits-with-flaky-builds.png?w=1024 1024w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/commits-with-flaky-builds.png?w=1536 1536w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/commits-with-flaky-builds.png?w=2048 2048w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p>This is an 18x improvement and the lowest rate of flaky builds since we began tracking flaky tests in 2016.<\/p>\n<p>So, how does it work?<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55345\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/flakey-test-bother.png?resize=1024%2C110\" alt=\"Text in red: the only person who is bother by a flakey test is the person who wrote it\" width=\"1024\" height=\"110\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/flakey-test-bother.png?w=2514 2514w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/flakey-test-bother.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/flakey-test-bother.png?w=768 768w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/flakey-test-bother.png?w=1024 1024w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/flakey-test-bother.png?w=1536 1536w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/flakey-test-bother.png?w=2048 2048w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p>Say you just merged a test that would fail once every 1,000 builds. It didn&#8217;t fail during development or review but a few hours later, the test fails on your teammate&#8217;s branch.<\/p>\n<p>When this failure occurs, the new system inspects it and finds it to be flaky. After ensuring the test passes when run against the same code, it\u00a0<strong>keeps the build green.<\/strong>\u00a0And it happens quickly: unless your teammate is watching closely, they won&#8217;t notice.<\/p>\n<p>But your flaky test is still out there, failing on other branches. Every time it does, the system keeps track of where it happened and how it failed, each time learning more about the failure. If it continues to affect developers, the system identifies it as high impact: it&#8217;s time for a human to investigate. Using test failure history and\u00a0<code>git blame<\/code>, the system finds the commit most likely to have introduced the problem\u2014your commit\u2014and assigns an issue to you.<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55347\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/ci-tooling.png?resize=1024%2C890\" alt=\"\" width=\"1024\" height=\"890\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/ci-tooling.png?w=1173 1173w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/ci-tooling.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/ci-tooling.png?w=768 768w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/ci-tooling.png?w=1024 1024w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p style=\"text-align: center;\"><em>Screenshot of GitHub&#8217;s internal CI tooling.<\/em><\/p>\n<p>From there, you can see information about the failure, including what may have caused it, where it failed, and who else might be responsible. After some poking around, you find the problem and merge a fix.<\/p>\n<p>The system noticed a problem, contained it, and delegated it the right person. In short,\u00a0<strong>the only person bothered by a flaky test is the person who wrote it.<\/strong><\/p>\n<div class=\"highlight highlight-source-ruby\">\n<pre><span class=\"pl-c\"># This ain't a blocker<\/span>\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">test_fails_one_in_a_thousand<\/span>\n  <span class=\"pl-en\">assert<\/span> <span class=\"pl-en\">rand<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-c1\">1000<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">zero?<\/span>\n<span class=\"pl-k\">end<\/span><\/pre>\n<\/div>\n<h2 id=\"how-it-works\"><a class=\"heading-link\" href=\"#how-it-works\">How it works<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>When we set out to build this new system, our intent wasn\u2019t to fix every flaky test or to stop developers from introducing new flaky tests. Such goals, if not impossible, seemed impractical. Similar to telling a developer to never write another bug, it would be much more costly and only slightly less flaky. Rather, we set out to manage the inevitability of flaky tests.<\/p>\n<h3 id=\"focusing-on-what-matters\"><a class=\"heading-link\" href=\"#focusing-on-what-matters\">Focusing on what matters<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h3>\n<p>When inspecting the history of failures in our monolith, we found that about a quarter of our tests had failed flaky across three or more branches in the past two years. But as we filtered by occurence, we learned that the flakiness was not evenly distributed: most flaky test failed fewer than ten times and only 0.4 percent of flaky tests failed 100 times or more.<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55346\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/tests-with-flakey.png?resize=1024%2C339\" alt=\"Bar chart showing tests with flakey failures\" width=\"1024\" height=\"339\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/tests-with-flakey.png?w=2085 2085w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/tests-with-flakey.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/tests-with-flakey.png?w=768 768w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/tests-with-flakey.png?w=1024 1024w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/tests-with-flakey.png?w=1536 1536w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/tests-with-flakey.png?w=2048 2048w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p>This made one thing clear: not every flaky failure should be investigated.<\/p>\n<p>Instead, by focusing on this top 0.4 percent, we could make the most of our time. So which tests were in this group?<\/p>\n<h3 id=\"automating-flake-detection\"><a class=\"heading-link\" href=\"#automating-flake-detection\">Automating flake detection<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h3>\n<blockquote><p>We define a &#8220;flaky&#8221; test result as a test that exhibits both a passing and a failing result with the same code. \u2013<a href=\"https:\/\/testing.googleblog.com\/2016\/05\/flaky-tests-at-google-and-how-we.html\" rel=\"nofollow\">John Micco, Google<\/a><\/p><\/blockquote>\n<p>Since 2016, our CI has been able to detect whether a test failure is flaky using two complementary approaches:<\/p>\n<ol>\n<li><strong>Same code, different results.<\/strong>\u00a0Once a build finishes, CI checks for other builds run against the same code using the root\u00a0<a href=\"https:\/\/git-scm.com\/book\/en\/v2\/Git-Internals-Git-Objects#_tree_objects\" rel=\"nofollow\">git tree hash<\/a>. If another build had different results\u2014for example, a test failed on the first build but passed on the second\u2014the test failure was marked as flaky. While this approach was accurate, it only worked if a build was retried.<\/li>\n<li><strong>Retry tests that fail.<\/strong>\u00a0When a test failed, it was retried again later within the same build. This could be used on every build at minimal cost. If the test passed when rerun, it was marked as flaky. However, certain types of flaky tests couldn&#8217;t be detected with this approach, such as a time-based flaky test. (If your test failed because it was a leap year, rerunning it two minutes later won&#8217;t help.)<\/li>\n<\/ol>\n<p>Unfortunately, these approaches were only able to identify 25 percent of the flaky failures, counting on developers to find the rest. Before delegating flaky test detection to CI, we needed an approach that was as good or better than a person.<\/p>\n<h3 id=\"making-it-better\"><a class=\"heading-link\" href=\"#making-it-better\">Making it better<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h3>\n<p>We decided to iterate on the test retry approach by rerunning the test three times, each in a scenario targeting a common cause of flakiness.<\/p>\n<ol>\n<li><strong>Retry in the same process.<\/strong>\u00a0This retry attempts to replicate the same conditions in which the test failed: same Ruby VM, same database, same host. If the test passes under the same conditions, it is likely caused by randomness in the code or a race condition.<\/li>\n<li><strong>Retry in the same process, shifted into the future.<\/strong>\u00a0This retry attempts to replicate the same conditions with one exception: time. If the test passes when run in the future, as simulated by test helpers, it is likely caused by an incorrect assumption about time (e.g., &#8220;there are 28 days in February&#8221;).<\/li>\n<li><strong>Retry on a different host.<\/strong>\u00a0This attempts to run the same code in a completely separate environment: different Ruby VM, different database, different host. If the test passes under these conditions but fails in the other two retries, it is likely caused by test order-dependence or some other shared state.<\/li>\n<\/ol>\n<p>Using this approach,\u00a0<strong>we are able to automatically identify 90 percent of flaky failures.<\/strong><\/p>\n<p>Further, because we kept a history of how a test would fail, we were also able to estimate the cause of flakiness: chance, time-based, or order-dependent. When it came time to fix a test, this gave the developer a headstart.<\/p>\n<h3 id=\"measuring-impact\"><a class=\"heading-link\" href=\"#measuring-impact\">Measuring impact<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h3>\n<p>Once we could accurately detect flaky failures, we needed a way to quantify impact to automate prioritization.<\/p>\n<p>To do this, we used information tracked with every test failure: build, branch, author, commit, and more. Using this information, a flaky test is given an impact score based on how many times it has failed as well as how many branches, developers, and deploys were affected by it. The higher the score, the more important the flaky test.<\/p>\n<p>Once the score exceeds a certain threshold, an issue is automatically opened and assigned to the people who most recently modified either the test files or associated code prior to the test becoming flaky. To help jog the memory of those assigned, a link to the commit that may have introduced the problem is added to the issue.<\/p>\n<p>Teams can also view flaky tests by impact, CODEOWNER, or suite, giving insight into the test suite and giving developers a TODO list for problem areas.<\/p>\n<h2 id=\"closing\"><a class=\"heading-link\" href=\"#closing\">Closing<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>By reducing the number of flaky builds by 18x, the new system makes CI more trustworthy and red builds more meaningful. If your pull request has a failure, it&#8217;s a sign you need to change something, not a sign you should hit <em>Rebuild<\/em>. When it comes time to deploy, you can be sure that your build won&#8217;t go red late in the day because a test doesn&#8217;t take into account daylight saving time.<\/p>\n<p>This keeps us moving, even when we make mistakes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Part of the\u00a0Building GitHub blog series. It\u2019s four o\u2019clock in the afternoon as you push the last tweak to your branch. Your teammate already reviewed and approved your pull request&hellip;<\/p>\n","protected":false},"author":1846,"featured_media":57452,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_gh_post_show_toc":"","_gh_post_is_no_robots":"","_gh_post_is_featured":"","_gh_post_is_excluded":"","_gh_post_is_unlisted":"","_gh_post_related_link_1":"","_gh_post_related_link_2":"","_gh_post_related_link_3":"","_gh_post_sq_img":"","_gh_post_sq_img_id":"","_gh_post_cta_title":"","_gh_post_cta_text":"","_gh_post_cta_link":"","_gh_post_cta_button":"","_gh_post_recirc_hide":"","_gh_post_recirc_col_1":"","_gh_post_recirc_col_2":"","_gh_post_recirc_col_3":"","_gh_post_recirc_col_4":"","_featured_video":"","_gh_post_additional_query_params":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"{title}\n\n{excerpt}\n\n{url}","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false,"_links_to":"","_links_to_target":""},"categories":[72,3308],"tags":[],"coauthors":[2270],"class_list":["post-55340","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-engineering","category-engineering-principles"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.6 (Yoast SEO v28.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Reducing flaky builds by 18x - The GitHub Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Reducing flaky builds by 18x\" \/>\n<meta property=\"og:description\" content=\"Part of the\u00a0Building GitHub blog series. It\u2019s four o\u2019clock in the afternoon as you push the last tweak to your branch. Your teammate already reviewed and approved your pull request&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/\" \/>\n<meta property=\"og:site_name\" content=\"The GitHub Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-12-16T16:00:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-12-20T22:44:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/Untitled.png?fit=1200%2C630\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Jordan Raine\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/Untitled.png?fit=1200%2C630\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jordan Raine\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/\"},\"author\":{\"name\":\"Jordan Raine\",\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/4d7334c12fe6dc9897b48e388da030fa\"},\"headline\":\"Reducing flaky builds by 18x\",\"datePublished\":\"2020-12-16T16:00:56+00:00\",\"dateModified\":\"2021-12-20T22:44:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/\"},\"wordCount\":1436,\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/Blog_ENGINEERING_for-social.png?fit=1200%2C630\",\"articleSection\":[\"Engineering\",\"Engineering principles\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/\",\"url\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/\",\"name\":\"Reducing flaky builds by 18x - The GitHub Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/Blog_ENGINEERING_for-social.png?fit=1200%2C630\",\"datePublished\":\"2020-12-16T16:00:56+00:00\",\"dateModified\":\"2021-12-20T22:44:20+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/4d7334c12fe6dc9897b48e388da030fa\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/#primaryimage\",\"url\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/Blog_ENGINEERING_for-social.png?fit=1200%2C630\",\"contentUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/Blog_ENGINEERING_for-social.png?fit=1200%2C630\",\"width\":1200,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/reducing-flaky-builds-by-18x\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/github.blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Engineering\",\"item\":\"https:\\\/\\\/github.blog\\\/engineering\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Engineering principles\",\"item\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Reducing flaky builds by 18x\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/github.blog\\\/#website\",\"url\":\"https:\\\/\\\/github.blog\\\/\",\"name\":\"The GitHub Blog\",\"description\":\"Updates, ideas, and inspiration from GitHub to help developers build and design software.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/github.blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/4d7334c12fe6dc9897b48e388da030fa\",\"name\":\"Jordan Raine\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0a25b56bfac7cba00835d9f6268d263d699f755ab930b8c1961c266011ae928b?s=96&d=mm&r=g04ccd2bec66a32275c8d69c98a382c3a\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0a25b56bfac7cba00835d9f6268d263d699f755ab930b8c1961c266011ae928b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0a25b56bfac7cba00835d9f6268d263d699f755ab930b8c1961c266011ae928b?s=96&d=mm&r=g\",\"caption\":\"Jordan Raine\"},\"url\":\"https:\\\/\\\/github.blog\\\/author\\\/jnraine\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Reducing flaky builds by 18x - The GitHub Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/","og_locale":"en_US","og_type":"article","og_title":"Reducing flaky builds by 18x","og_description":"Part of the\u00a0Building GitHub blog series. It\u2019s four o\u2019clock in the afternoon as you push the last tweak to your branch. Your teammate already reviewed and approved your pull request&hellip;","og_url":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/","og_site_name":"The GitHub Blog","article_published_time":"2020-12-16T16:00:56+00:00","article_modified_time":"2021-12-20T22:44:20+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/Untitled.png?fit=1200%2C630","type":"image\/png"}],"author":"Jordan Raine","twitter_card":"summary_large_image","twitter_image":"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/Untitled.png?fit=1200%2C630","twitter_misc":{"Written by":"Jordan Raine","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/#article","isPartOf":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/"},"author":{"name":"Jordan Raine","@id":"https:\/\/github.blog\/#\/schema\/person\/4d7334c12fe6dc9897b48e388da030fa"},"headline":"Reducing flaky builds by 18x","datePublished":"2020-12-16T16:00:56+00:00","dateModified":"2021-12-20T22:44:20+00:00","mainEntityOfPage":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/"},"wordCount":1436,"image":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/#primaryimage"},"thumbnailUrl":"https:\/\/github.blog\/wp-content\/uploads\/2021\/04\/Blog_ENGINEERING_for-social.png?fit=1200%2C630","articleSection":["Engineering","Engineering principles"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/","url":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/","name":"Reducing flaky builds by 18x - The GitHub Blog","isPartOf":{"@id":"https:\/\/github.blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/#primaryimage"},"image":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/#primaryimage"},"thumbnailUrl":"https:\/\/github.blog\/wp-content\/uploads\/2021\/04\/Blog_ENGINEERING_for-social.png?fit=1200%2C630","datePublished":"2020-12-16T16:00:56+00:00","dateModified":"2021-12-20T22:44:20+00:00","author":{"@id":"https:\/\/github.blog\/#\/schema\/person\/4d7334c12fe6dc9897b48e388da030fa"},"breadcrumb":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/#primaryimage","url":"https:\/\/github.blog\/wp-content\/uploads\/2021\/04\/Blog_ENGINEERING_for-social.png?fit=1200%2C630","contentUrl":"https:\/\/github.blog\/wp-content\/uploads\/2021\/04\/Blog_ENGINEERING_for-social.png?fit=1200%2C630","width":1200,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/github.blog\/engineering\/engineering-principles\/reducing-flaky-builds-by-18x\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/github.blog\/"},{"@type":"ListItem","position":2,"name":"Engineering","item":"https:\/\/github.blog\/engineering\/"},{"@type":"ListItem","position":3,"name":"Engineering principles","item":"https:\/\/github.blog\/engineering\/engineering-principles\/"},{"@type":"ListItem","position":4,"name":"Reducing flaky builds by 18x"}]},{"@type":"WebSite","@id":"https:\/\/github.blog\/#website","url":"https:\/\/github.blog\/","name":"The GitHub Blog","description":"Updates, ideas, and inspiration from GitHub to help developers build and design software.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/github.blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/github.blog\/#\/schema\/person\/4d7334c12fe6dc9897b48e388da030fa","name":"Jordan Raine","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/0a25b56bfac7cba00835d9f6268d263d699f755ab930b8c1961c266011ae928b?s=96&d=mm&r=g04ccd2bec66a32275c8d69c98a382c3a","url":"https:\/\/secure.gravatar.com\/avatar\/0a25b56bfac7cba00835d9f6268d263d699f755ab930b8c1961c266011ae928b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0a25b56bfac7cba00835d9f6268d263d699f755ab930b8c1961c266011ae928b?s=96&d=mm&r=g","caption":"Jordan Raine"},"url":"https:\/\/github.blog\/author\/jnraine\/"}]}},"jetpack_publicize_connections":[],"jetpack_shortlink":"https:\/\/wp.me\/pamS32-eoA","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/github.blog\/wp-content\/uploads\/2021\/04\/Blog_ENGINEERING_for-social.png?fit=1200%2C630","_links":{"self":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/55340","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/users\/1846"}],"replies":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/comments?post=55340"}],"version-history":[{"count":5,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/55340\/revisions"}],"predecessor-version":[{"id":55394,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/55340\/revisions\/55394"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/media\/57452"}],"wp:attachment":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/media?parent=55340"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/categories?post=55340"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/tags?post=55340"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/coauthors?post=55340"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}