{"id":1925,"date":"2026-11-07T14:50:00","date_gmt":"2026-11-07T14:50:00","guid":{"rendered":"https:\/\/devopsschool.org\/blog\/?p=1925"},"modified":"2026-11-07T14:50:00","modified_gmt":"2026-11-07T14:50:00","slug":"team-moved-releases-off-peak","status":"publish","type":"post","link":"https:\/\/devopsschool.org\/blog\/team-moved-releases-off-peak\/","title":{"rendered":"How One Team Moved Risky Releases Off-Peak and Calmed Down"},"content":{"rendered":"<p>This is a fictional story, yet engineers who have looked after a busy production system will recognise each beat of it. It follows a small platform team at an imaginary payroll software company, which we will call Ledgerline, as it learned to move its riskiest releases off-peak. Nothing about their tooling changed dramatically. What changed was when they chose to act.<\/p>\n<h2>The problem: releasing into the rush<\/h2>\n<p>Ledgerline sold payroll and attendance software to mid-sized employers. Its traffic had a sharp, predictable shape. Activity climbed every weekday morning as HR staff logged in, spiked hard in the final days of each month as payroll was processed, and fell away at weekends and overnight.<\/p>\n<p>The platform team, five engineers led by a calm, slightly weary lead named Kavitha, had drifted into releasing whenever work was finished. In practice that meant Thursday and Friday afternoons, because the sprint ended on Friday. Twice in one quarter, a release landed during month-end processing. The first caused a slowdown in report generation. The second broke a payslip export for several hours, on the exact day customers needed it most.<\/p>\n<p>The post-incident discussion was uncomfortable. The code changes themselves were modest. The damage came from timing.<\/p>\n<h2>Step one: looking at the actual traffic<\/h2>\n<p>Kavitha asked one of the engineers, Imran, to pull two months of request rates, database load and background job volumes and lay them out by hour and day. The picture was clearer than anyone expected. The quietest sustained stretch was not late at night, as most had assumed, because nightly payroll calculations ran then and kept the database busy. The real trough was early Tuesday and Wednesday mornings, roughly between six and eight, and almost the entire week immediately after month-end.<\/p>\n<p>That second finding mattered most. The team had been treating every week as equal, when in fact the first week of each month was the calmest of all.<\/p>\n<h2>Step two: sorting changes by risk<\/h2>\n<p>The team did not decide to move everything. Small, well-tested changes behind feature flags could keep flowing during the day. Instead, they agreed on a short list of change types that must go out in a quiet window:<\/p>\n<ul>\n<li>database schema migrations;<\/li>\n<li>upgrades to the payroll calculation engine;<\/li>\n<li>changes to export and reporting pipelines;<\/li>\n<li>infrastructure work on the main cluster.<\/li>\n<\/ul>\n<p>For those, the rule was simple: schedule in the early midweek trough, and never in the last five working days of a month. Larger platform projects would land in the first week after month-end. The team also borrowed the idea of a targeted pause; the explainer on <a href=\"https:\/\/devopsschool.org\/blog\/deployment-freeze\/\">what a deployment freeze is and how teams apply one<\/a> helped them shape a month-end freeze that covered only high-risk categories rather than all work.<\/p>\n<h2>Step three: making the early window humane<\/h2>\n<p>Nobody wanted to start at six every week. The team rotated the early release duty, so each engineer took it roughly once a month, and the person on duty started late the day before and finished early afterwards. Kavitha insisted that a second engineer be reachable during every window. A quiet system, she pointed out, is only safe if someone who understands it is awake.<\/p>\n<h2>Step four: exposing changes gradually<\/h2>\n<p>For the payroll engine upgrades, the team went further. They began routing a small share of low-traffic tenants to the new version first, during the morning trough, and only expanding once error rates and timings looked normal. The approach is a familiar one; our guide to <a href=\"https:\/\/devopsschool.org\/blog\/canary-deployment\/\">how canary releases work in practice<\/a> covers the pattern in more depth. Combining a quiet hour with a small first audience meant that even a faulty change touched very few customers.<\/p>\n<h2>What happened next<\/h2>\n<p>Over the following two quarters, the team saw no customer-facing incidents from planned releases during month-end. A schema migration did fail once, in an early Wednesday window, when an index build took far longer than in staging. Because traffic was minimal and two engineers were on hand, they rolled it back calmly, investigated, and reapplied it the following week with a revised approach. Customers never noticed.<\/p>\n<p>The support team noticed something too: fewer frantic tickets on the busiest days of the month, and colleagues with time to handle the ones that did arrive.<\/p>\n<p>When leadership asked what had changed, Kavitha put it plainly: &#8220;We didn&#8217;t get better at writing code. We got better at choosing the moment.&#8221;<\/p>\n<h2>A lesson from outside engineering<\/h2>\n<p>Imran later admitted the idea had clicked during a family holiday. Planning a trip with <a href=\"https:\/\/goaorbit.com\/\">Goa Orbit, a Goa travel site covering its beaches, forts, food and nightlife<\/a>, his family had picked the quieter shoulder months and found the whole visit calmer and more attentive than their previous peak-season trips. Systems and resorts, he joked, behave the same way when they are not overwhelmed.<\/p>\n<h2>Practical takeaways for your team<\/h2>\n<ol>\n<li><strong>Look at real load data, including background jobs.<\/strong> The quiet period may not be where you assume.<\/li>\n<li><strong>Check monthly and seasonal patterns, not just daily ones.<\/strong> Some weeks are far calmer than others.<\/li>\n<li><strong>Only move the risky categories.<\/strong> Low-risk changes can keep flowing; don&#8217;t slow everything.<\/li>\n<li><strong>Staff the window properly.<\/strong> Quiet traffic with no expert awake is not safe.<\/li>\n<li><strong>Combine quiet timing with gradual exposure<\/strong> for the changes that matter most.<\/li>\n<li><strong>Make it part of your change process.<\/strong> Recording why a slot was chosen keeps the habit alive; see <a href=\"https:\/\/devopsschool.org\/blog\/change-management\/\">the basics of change management in IT<\/a> for how that fits more broadly.<\/li>\n<\/ol>\n<p>Ledgerline is fictional, but the lesson is real. The busiest moment is usually the worst one for delicate work, and teams that learn to wait for the lull spend far less time apologising to customers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A fictional payroll platform team learns to move risky releases into quiet midweek mornings and post-month-end weeks, and stops breaking things on busy days.<\/p>\n","protected":false},"author":5,"featured_media":1926,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[486],"tags":[],"class_list":["post-1925","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/posts\/1925","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/comments?post=1925"}],"version-history":[{"count":1,"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/posts\/1925\/revisions"}],"predecessor-version":[{"id":1967,"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/posts\/1925\/revisions\/1967"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/media\/1926"}],"wp:attachment":[{"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/media?parent=1925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/categories?post=1925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devopsschool.org\/blog\/wp-json\/wp\/v2\/tags?post=1925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}