<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Author at Infinum</title>
		<atom:link href="https://infinum.com/blog/author/jaka-sustersic/feed/" rel="self" type="application/rss+xml" />
		<link></link>
		<description>Building digital products</description>
		<lastBuildDate>Fri, 17 Apr 2026 13:59:15 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>19266034https://infinum.com/uploads/2025/05/Cobol-2.webp</url>
				</image>
				<title>Is Ruby on Rails Becoming the New COBOL?</title>
				<link>https://infinum.com/blog/is-ruby-on-rails-becoming-the-new-cobol/</link>
				<pubDate>Tue, 27 May 2025 12:29:17 +0000</pubDate>
				<dc:creator>Jaka Šušteršič</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19266034</guid>
				<description>
					<![CDATA[<p>Ruby on Rails was once the hottest ticket in tech. Now it's a cult classic with a loyal crowd. But is it on its way to becoming the next COBOL?</p>
<p>The post <a href="https://infinum.com/blog/is-ruby-on-rails-becoming-the-new-cobol/">Is Ruby on Rails Becoming the New COBOL?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-234"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	Ruby on Rails used to be the hot band everyone wanted to see live. Now it feels more like a cult classic, still good, still playing, but to a smaller, more devoted crowd. And lately, some folks are wondering: is Rails on the path to becoming the next COBOL?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	Yes, <em>that</em> COBOL. The 65-year-old language quietly running billions of lines of code inside banks, governments, and systems nobody wants to touch but everybody needs. On paper, the comparison seems extreme. But look closer, and you’ll start to see the shape of a long tail forming behind Rails. One that looks suspiciously like legacy.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	Let’s dig in.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-102">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-103'
	>
	The rise of two titans</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	COBOL and Ruby on Rails couldn’t be more different in syntax, style, or era. They definitely share one thing though: <strong>both were once the default choice for a generation of developers</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-108">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-109'
	>
	COBOL, born in 1959, became the backbone of enterprise and government systems by the ’70s. If you’ve ever withdrawn cash, paid taxes, or waited for a check to clear, COBOL probably had something to do with it. Its dominance was complete, and it stuck — not because developers loved it, but because rewriting working software is expensive, risky, and often unnecessary.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	Fast forward to the 2000s. Enter Rails: elegant, opinionated, and built for speed. DHH dropped <em>convention over configuration</em> like a mic, and the web dev world listened.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-114">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-115'
	>
	From 2005 to 2014, Rails was the framework of choice for startups, SaaS tools, and hacker weekends. Twitter, GitHub, Shopify, and Basecamp all bet big on it. For a while, every bootcamp taught it, every founder loved it, and every developer blog had a hot take on ActiveRecord callbacks.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-117">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-118'
	>
	It was a golden era. Until it wasn’t.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-120">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-121'
	>
	How Rails stacks up these days</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-123">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-124'
	>
	Spoiler alert: not like it used to.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-128"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-126">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-127'
	>
	Once the backbone of every hot startup stack, <strong>Rails has quietly slipped from the spotlight over the past decade</strong>. While direct stats about framework usage can be hard to pin down, Ruby’s trajectory helps illustrate the shift. <a href="https://octoverse.github.com/">GitHub’s Octoverse</a> reports show Ruby falling from #5 (2014) to #10 (2022) in language rankings. The <a href="https://www.tiobe.com/tiobe-index/">TIOBE Index</a> recently pushed it to 24th, with its CEO bluntly suggesting Ruby is “likely to go out of fashion.” Ouch.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-131"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-129">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-130'
	>
	Community chatter reflects the mood. “Rails is just not what it once was,” <a href="https://www.reddit.com/r/rails/comments/17qvwsz/my_thoughts_on_the_rise_and_fall_of_ruby_on_rails/">wrote one long-time Redditor</a>. “The amount of jobs are way down and the pay is too.” Another chimed in: “It’s not COBOL — nothing that critical was written in it. Rails will eventually die.”</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-134"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-132">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-133'
	>
	But not everyone’s buying the obituary. Rails defenders argue it’s simply matured. It might no longer be trendy, but it’s still incredibly efficient. It does what it promises. It allows small teams to build and ship real products fast, without the overhead of piecing together half a dozen libraries. In an era where VC money is drying up and lean teams are the norm, that’s a value prop worth paying attention to.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-137"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-135">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-136'
	>
	We see this play out with companies we work with, many of which are organizations that run massive products on large Rails codebases. One client, with a market cap north of $2 billion, has definitely felt the pull to rebuild in something “modern.” But when it comes to cost and risk, the appeal fades fast. Some functionality is being moved to other stacks where it makes sense, but the core will likely stay on Rails for years. There’s simply no silver bullet waiting on the other side.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-140"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-138">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-139'
	>
	COBOL walked so Rails could… maintain</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-141">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-142'
	>
	To understand where Rails might be headed, it’s worth studying COBOL’s fate.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-144">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-145'
	>
	COBOL hasn’t been hot in decades, yet as of 2017, <strong>220 billion lines</strong> of it still powered key systems. Some estimates say <strong>43% of banking platforms</strong> and <strong>95% of ATM swipes</strong> involve COBOL code. Why? Because rewriting complex financial logic that’s business-critical (and often undocumented) is risky and expensive.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-149"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-147">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-148'
	>
	The kicker? Most COBOL developers are nearing retirement. In 2020, some U.S. states literally had to <a href="https://www.businessinsider.com/new-jersey-cobol-programmers-coronavirus-experts-mainframe-2020-4"><em>beg</em> for COBOL engineers</a> to fix outdated unemployment systems. And those engineers? They’re making bank.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-150">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-151'
	>
	COBOL is a classic case of technological inertia. As a consequence, it’s created a niche economy where a small number of specialists quietly hold the keys to critical systems. And they command serious salaries for doing so.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-153">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-154'
	>
	Rails is starting to look a lot like COBOL</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-158"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-156">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-157'
	>
	Just to be clear: Rails isn’t COBOL. But the trajectory? It rhymes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-161"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-159">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-160'
	>
	Many foundational platforms still run on Rails. Shopify’s massive monolith? Rails. GitHub? Rails. Basecamp? Rails, obviously. These companies aren’t rushing to rewrite their cores in Elixir or Go. Instead, they’re optimizing what works — and contributing back to the Rails ecosystem in the process.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-164"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-162">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-163'
	>
	Rails roles are also becoming more specialized. Junior opportunities are scarcer; most open positions are for mid-to-senior engineers with years of experience. But those who <em>are</em> experienced? They’re doing just fine. <a href="https://survey.stackoverflow.co/2023/">Stack Overflow’s 2023 survey</a> ranked Ruby as the <strong>4th highest-paying tech globally</strong>. Senior Rails engineers in the U.S. regularly clear six figures.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-165">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-166'
	>
	This is where the COBOL parallel kicks in: <strong>high compensation, low visibility, and a shrinking pipeline of new devs</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-168">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-169'
	>
	Less hype, more output</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-173"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-171">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-172'
	>
	Let’s kill the idea that Rails is frozen in time. It’s not.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-176"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-174">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-175'
	>
	Both Rails 7 and 8 are pushing forward with features that sidestep frontend fatigue. <a href="https://hotwired.dev/">Hotwire</a>, Turbo, and Stimulus let you build snappy UIs without reaching for React or Vue. Want realtime updates without drowning in JavaScript? Rails has that baked in.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-179"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-177">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-178'
	>
	On the backend, <strong>Ruby is still evolving</strong>. Turning 30 next year,<strong> it’s the same age as JavaScript, and it remains in active development</strong>. The Ruby 3&#215;3 initiative, launched back in 2015, <a href="https://www.heroku.com/blog/ruby-3-by-3/">committed</a> to making Ruby 3 three times faster than Ruby 2. That milestone was reached in 2020, and the momentum hasn’t stopped. Recent versions continue to bring performance gains through JIT compilers like YJIT and RJIT, as well as improvements to memory efficiency and startup times.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-182"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-180">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-181'
	>
	<strong>Rails 8 builds on this foundation</strong>. It is the version of Rails that remembers why people fell in love with it in the first place: fast setup, clear conventions, and a full-stack story that doesn’t require Kubernetes on day one. It even introduces <a href="https://github.com/rails/solid_queue">“Solid Queue”</a> for background jobs — no Redis, no drama.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-185"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-183">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-184'
	>
	And beyond the tooling, there’s still joy in writing Rails. As DHH recently pointed out in his post <a href="https://world.hey.com/dhh/coding-should-be-a-vibe-50908f49">Coding should be a vibe!</a>:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-187"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-186'
	>
	<em>Disgruntled programmers have finally realized that an escape from nasty syntax, boilerplate galore, and ecosystem hyper-churn is possible. That’s the appeal of AI: having it hide away all that unpleasantness. Only it’s like cleaning your room by stuffing the mess under the bed — it doesn’t make it go away!</em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-190"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-188">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-189'
	>
	If developers are racing to offload coding to AI, maybe the problem lies in the stack itself.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-193"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-191">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-192'
	>
	Rails and Ruby offer a different path. It’s one that doesn’t require hiding the mess. Instead, they strip away unnecessary layers and let you <strong>build fast, clean, and human-readable code from day one</strong>. In that world, simplicity and elegance aren’t limitations. They’re advantages.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-196"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-194">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-195'
	>
	That’s also why we don’t skip upgrades. All of our active projects are already on Rails 7, and a couple have already adopted Rails 8. We use Hotwire and Turbo where it makes sense. Not because it’s fashionable, but because it solves real problems. Staying current gives us access to the latest features, but more importantly, it keeps our clients’ products secure.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-199"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-197">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-198'
	>
	Rails in a niche future</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-202"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-200">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-201'
	>
	So, is Rails becoming the boutique skillset for aging SaaS platforms?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-205"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-203">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-204'
	>
	Maybe. And that’s not a bad thing.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-208"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-206">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-207'
	>
	Rails still excels at building internal tools, MVPs, and stable CRUD-heavy platforms — especially for teams that value clarity over cleverness. Its “boring is good” philosophy is a feature, not a bug.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-211"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-209">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-210'
	>
	The community remains active, too. The main <a href="https://github.com/rails/rails">Rails repo</a> has seen over <strong>6,500 commits</strong> and <strong>1,500 issues closed</strong> in the past year. RailsConf draws a mix of grizzled veterans and Hotwire-happy newbies. Tools like <a href="https://docs.stimulusreflex.com/">StimulusReflex</a> and <a href="https://github.com/github/view_component">view components</a> show there’s still innovation happening, just at a more grounded pace.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-214"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-212">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-213'
	>
	The language and framework remain deeply aligned around developer happiness and productivity. Drastic deviations are unlikely to succeed, because <strong>what’s here doesn’t just work, it works very well</strong>. Newer languages and frameworks have their place, but Rails wasn’t built for the same constraints or audiences.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-217"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-215">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-216'
	>
	Rails isn’t a zombie. It’s simply not chasing trends anymore. It’s found its lane, and for the right teams, it’s still a dream to work with.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-220"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-218">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-219'
	>
	Not dead. Just different.</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-223"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-221">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-222'
	>
	Ruby on Rails isn’t dying. It’s aging into its next role. Think less rockstar, more session musician. Still sharp, still useful, still quietly keeping the show running.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-226"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-224">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-225'
	>
	It might not be the framework new grads rush to learn, and it might not top the charts anymore. But for many companies, Rails is still a pragmatic choice. It delivers. It scales (when engineered well). And in a tech world increasingly obsessed with complexity, Rails dares to stay simple.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-229"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-227">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-228'
	>
	Smart engineering teams are well-aware: smart, stable software never goes out of style. So maybe, in 10 years, we’ll talk about Rails the same way we talk about COBOL: a relic, yes — but a reliable one. And in the end, reliability is underrated.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-232"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-230">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-231'
	>
	At Infinum, <strong>we’re here for both sides of the Rails story</strong>. Both if you’re looking to extend the life of a legacy system, or weighing Rails against shinier options for a new build. Check out our <a href="https://infinum.com/rails-support-maintenance/"><strong>Rails Maintenance &amp; Support services</strong></a> if your app needs some love (or a performance tune-up), or reach out if you’re on the fence about which tech stack fits your product best.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/is-ruby-on-rails-becoming-the-new-cobol/">Is Ruby on Rails Becoming the New COBOL?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19262893https://infinum.com/uploads/2025/02/outsource-vs-hire_in-house.webp</url>
				</image>
				<title>The Rails Project Dilemma – Should You Build In-House or Outsource?</title>
				<link>https://infinum.com/blog/hire-vs-outsource-rails-companies/</link>
				<pubDate>Mon, 10 Feb 2025 11:11:17 +0000</pubDate>
				<dc:creator>Jaka Šušteršič</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19262893</guid>
				<description>
					<![CDATA[<p>The hire vs outsource Rails companies dilemma can be tricky, so we weigh the pros and cons to help you choose the best path for your project.</p>
<p>The post <a href="https://infinum.com/blog/hire-vs-outsource-rails-companies/">The Rails Project Dilemma – Should You Build In-House or Outsource?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-412"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-235">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-238"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-236">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-237'
	>
	<strong><strong>Deciding whether to build your Ruby on Rails product in-house or find an outsourcing company?</strong></strong> <strong>The hire vs outsource Rails companies dilemma can be tricky, so we weigh the pros and cons of both approaches to help you choose the best path for your project.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-241"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-239">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-240'
	>
	Ruby on Rails, affectionately known as <em>Rails</em>, has been a cornerstone of web development for nearly two decades. With its &#8220;convention over configuration&#8221; philosophy and robust ecosystem, Rails development can produce scalable and maintainable applications at speed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-244"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-242">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-243'
	>
	Not the latest, trendiest technology, Ruby on Rails is a powerful and flexible framework backed by one of the most active and supportive developer communities. It’s no wonder that companies like Airbnb, GitHub, SoundCloud, Netflix, and Shopify grew from startups to <a href="https://infinum.com/blog/ruby-on-rails-development-companies/">industry leaders with Rails</a> as the foundation of their tech stack.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-246"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-245'
	>
	<strong>Mature and stable, in 2025, Ruby on Rails will remain the technology of choice for many startups and large enterprises</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-249"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-247">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-248'
	>
	Mature and stable, in 2025, Ruby on Rails will remain the technology of choice for many startups and large enterprises. However, deciding whether to build your product with an in-house team or to outsource the work to a Rails development company can be as intricate as the framework itself.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-252"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-250">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-251'
	>
	While we’ve already reviewed the matter of <a href="https://infinum.com/blog/in-house-software-development-vs-outsourcing/" target="_blank" rel="noreferrer noopener">in-house development vs outsourcing</a> in general, this article explores the unique considerations for Ruby on Rails development to help you make the right choice for your business.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-255"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-253">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-254'
	>
	Keeping Rails development in-house</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-258"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-256">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-257'
	>
	Pros</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-261"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-259">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-260'
	>
	Deep domain-specific Rails expertise</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-264"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-262">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-263'
	>
	In-house developers familiar with your business domain and Rails-specific practices can be a great asset. Over time, the team develops a deep understanding of your industry’s nuances and can tailor Ruby on Rails’ conventions to fit specialized needs. This can be particularly valuable for organizations whose entire core business revolves around a Rails-powered product, and who are prepared to invest in building and maintaining a dedicated team for the long haul.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-267"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-265">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-266'
	>
	Simpler collaboration with internal stakeholders</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-270"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-268">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-269'
	>
	When your Ruby on Rails developers and other key roles (designers, project managers, etc.) all work in the same physical space, the development process can benefit from more organic, day-to-day interactions. It gives you the option of impromptu discussions and quick clarifications – especially if face-to-face collaboration is the norm in your organization.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-273"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-271">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-272'
	>
	Continuous skill development in the Rails ecosystem</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-276"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-274">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-275'
	>
	Investing in an internal team means growing their expertise in the Ruby on Rails framework (conventions, best practices, upgrades) and supporting libraries like RSpec. If you already have robust processes in place for continuous learning and knowledge-sharing, the team’s expertise can grow significantly over time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-279"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-277">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-278'
	>
	Long-term institutional knowledge of your specific Rails infrastructure</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-282"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-280">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-281'
	>
	As an internal dedicated team builds and maintains your Rails application, they develop a deep understanding of its quirks, dependencies, and overall structure. This institutional knowledge can mean faster troubleshooting and fewer knowledge-transfer hurdles down the road.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-285"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-283">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-284'
	>
	Cons</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-288"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-286">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-287'
	>
	Increasing difficulty acquiring top-tier Rails talent</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-291"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-289">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-290'
	>
	Ruby on Rails developers, especially those with deep expertise, are highly sought after and increasingly scarce. Finding and retaining such talent can be time-consuming and expensive, especially if your company doesn’t position itself as a major tech employer with compelling Rails-specific growth paths.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-294"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-292">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-293'
	>
	High recruitment and retention costs</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-297"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-295">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-296'
	>
	Beyond salaries (which are also expected to rise as developers advance), recruiting and retaining a Ruby on Rails team involves substantial costs, including the hiring process, continual training, and providing the resources for tools the team will need in their work. Over time, these costs add up and might not be justifiable unless Rails development is a central pillar of your business.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-300"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-298">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-299'
	>
	Limited exposure to diverse Rails implementations</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-303"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-301">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-302'
	>
	While in-house teams develop strong domain-specific knowledge, they focus on a single project and may lack experience with the broader Rails ecosystem. Outsourcing companies often have experienced developers who have worked on different project types and scales, which equips them to suggest unconventional but effective solutions that your team may not have encountered.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-306"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-304">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-305'
	>
	Risk of technological stagnation</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-309"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-307">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-308'
	>
	Ruby on Rails is mature but still evolving – new gems, patterns, and framework improvements surface regularly. Without exposure to the broader community or external experts, an in-house team risks falling behind on Rails trends, which could limit your product’s development velocity, long-term health, and ability to stay current and competitive.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-312"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-310">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-311'
	>
	Building Ruby on Rails products with an outsourcing company</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-315"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-313">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-314'
	>
	Pros</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-318"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-316">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-317'
	>
	Access to skilled developers with diverse project experiences</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-321"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-319">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-320'
	>
	An experienced Ruby on Rails agency typically works across multiple industries and project types – for example, our engineers have worked on over a hundred different development projects! This broad expertise often leads to creative, well-informed solutions – like optimizing complex queries in ActiveRecord or setting up scalable background job processing infrastructure specific to Sidekiq.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-324"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-322">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-323'
	>
	Immediate availability of mature Rails expertise</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-327"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-325">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-326'
	>
	The hiring process for building a team from scratch can take months, while outsourcing provides instant access to a full-fledged team of Ruby on Rails professionals. This rapid onboarding is especially valuable if you need to go to market quickly, tackle a technically complex project, or start a long-postponed <a href="https://infinum.com/blog/open-source-dependency-upgrade-process/" target="_blank" rel="noreferrer noopener">dependency upgrade process</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-330"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-328">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-329'
	>
	Flexible team scaling aligned with project needs</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-333"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-331">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-332'
	>
	A development company can scale your outsourced team up or down, depending on your current project requirements. For instance, you might need additional backend developers during the early development phase and fewer resources post-launch. With outsourcing, you only pay for the capacity you require rather than sustaining a large full-time team year-round.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-336"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-334">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-335'
	>
	Comprehensive understanding of current Rails best practices</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-339"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-337">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-338'
	>
	Specialized agencies are immersed in the Ruby on Rails ecosystem. They stay up to date on everything from performance optimizations to <a href="https://infinum.com/blog/open-source-dependency-upgrade-process/" target="_blank" rel="noreferrer noopener">compatibility with the latest versions</a>. Their exposure to a wide range of challenges – and their corresponding solutions – can support rapid Rails development and significantly enhance your project. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-342"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-340">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-341'
	>
	Cons</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-345"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-343">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-344'
	>
	Potential misalignment with internal technical culture</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-348"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-346">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-347'
	>
	External developers may not fully mirror your internal processes or business context on day one. Depending on your choice of outsourcing company, seamless integration can be challenging, but a reputable partner will prioritize understanding your workflows and domain to minimize disruptions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-351"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-349">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-350'
	>
	Less direct control over day-to-day development</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-354"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-352">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-353'
	>
	If you&#8217;re outsourcing Ruby on Rails development, it can mean relinquishing some oversight on the nitty-gritty of engineering. However, transparent processes, frequent check-ins, and collaborative project management tools (like Jira or <a href="https://productive.io/" target="_blank" rel="noreferrer noopener">Productive</a>) can ensure you always know what your outsourced team is working on.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-357"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-355">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-356'
	>
	Communication and knowledge transfer challenges</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-360"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-358">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-359'
	>
	Handing over an existing codebase or domain knowledge can feel challenging. Clear documentation, regular syncs, and well-defined onboarding processes go a long way here – and experienced outsourcing partners often have protocols in place for those scenarios. It also helps when an agency <a href="https://infinum.com/blog/ruby-on-rails-upgrade/" target="_blank" rel="noreferrer noopener">knows what to ask</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-363"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-361">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-362'
	>
	Potential inconsistencies in code quality</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-366"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-364">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-365'
	>
	Code quality can vary among outsourced teams. When outsourcing Ruby on Rails development, it’s crucial to choose a partner that adheres to <a href="https://infinum.com/handbook/rails" target="_blank" rel="noreferrer noopener">Rails best practices</a>, invests in thorough code reviews, and enforces consistent standards – so that your product remains maintainable and future-proof.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-369"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-367">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-368'
	>
	Outsourcing Ruby on Rails development? Here&#8217;s how to make the most of it</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-372"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-370">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-371'
	>
	If you decide to outsource your Ruby on Rails development project, here are a few tips from an experienced partner agency to make sure you reap all the benefits – and none of the pitfalls:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-376"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-373">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-374'
	>
	<strong>Define your goals and workflows up front</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-375'
	>
	Make sure your outsourcing partner understands not just the technical specs but also your overarching business objectives. Clear alignment on timelines, deliverables, and communication channels goes a long way toward avoiding missteps.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-380"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-377">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-378'
	>
	<strong>Prioritize transparent and effective communication</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-379'
	>
	Regular check-ins, shared project management tools, and open Slack channels keep everyone on the same page. Look for an agency that values real-time collaboration and proactive updates so you never feel out of the loop.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-384"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-381">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-382'
	>
	<strong>Seek proven Ruby on Rails expertise and consistent code quality</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-383'
	>
	Ask about the agency’s approach to code reviews, testing, and best practices. If you were to ask us, for instance, the answers would be: 1) at least two pairs of eyes on every line of code, 2) incredibly thorough, and 3) we’ve literally written <a href="https://infinum.com/handbook/rails" target="_blank" rel="noreferrer noopener">a handbook</a> on them. Your thoroughness here ensures your codebase remains maintainable and future-proof, even if multiple developers work on it.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-388"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-385">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-386'
	>
	<strong>Ensure a cultural and process fit</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-387'
	>
	Outsourcing shouldn’t feel like handing off your project to strangers. A good partner will strive to understand your internal culture, adopt similar workflows, and integrate smoothly with your existing team.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-392"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-389">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-390'
	>
	<strong>Insist on knowledge-sharing and documentation</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-391'
	>
	Whether you’re starting fresh or bringing an external team into an existing codebase, clear documentation and knowledge-transfer protocols help prevent bottlenecks – both now and in the future.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-395"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-393">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-394'
	>
	If you&#8217;re outsourcing Ruby on Rails development, this checklist can help sidestep the usual concerns. By choosing the right agency partner, you can tap into the full potential of a specialized Rails team – no compromises necessary.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-398"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-396">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-397'
	>
	Hire vs outsource Rails companies: which approach works for you?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-401"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-399">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-400'
	>
	Ruby on Rails is a powerful tool for building modern web applications, and it comes with its own set of nuances – everything from major version upgrades to discovering the perfect gem for a particular task. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-404"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-402">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-403'
	>
	The decision whether to hire vs outsource Rails companies ultimately hinges on your immediate project needs, long-term goals, and the unique challenges of the ecosystem. As you weigh in-house vs outsourced software development, consider the extent to which you can sustain the costs, recruitment efforts, and ongoing learning a Ruby on Rails team requires.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-407"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-405">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-406'
	>
	However, this choice doesn’t have to be an either/or scenario. However, this choice doesn&#8217;t have to be an either/or scenario. You can also tap into development services through hybrid models like <a href="https://infinum.com/blog/team-augmentation/" target="_blank" rel="noreferrer noopener">team augmentation</a>, combining the strengths of both approaches. For instance, an in-house team can define the core vision and maintain the product post-launch, while an outsourced partner provides expertise during development and scales resources as needed. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-410"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-408">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-409'
	>
	With the right balance, you can leverage Ruby on Rails’ full potential to build a product that aligns with your business goals and evolves with your users’ needs. If you need any help with development services, <a href="https://infinum.com/ruby-on-rails-development-services/" target="_blank" rel="noreferrer noopener">check out what our Rails team can do for you</a>. </p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/hire-vs-outsource-rails-companies/">The Rails Project Dilemma – Should You Build In-House or Outsource?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19260280https://infinum.com/uploads/2024/12/Ruby-on-rails-upgrade-questions.webp</url>
				</image>
				<title>6 Questions We Ask Before a Ruby on Rails Upgrade</title>
				<link>https://infinum.com/blog/ruby-on-rails-upgrade/</link>
				<pubDate>Wed, 11 Dec 2024 14:54:39 +0000</pubDate>
				<dc:creator>Jaka Šušteršič</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19260280</guid>
				<description>
					<![CDATA[<p>Before you dive into a Ruby on Rails upgrade, there are things to consider. Discover what the best agencies ask to make your upgrade a success.</p>
<p>The post <a href="https://infinum.com/blog/ruby-on-rails-upgrade/">6 Questions We Ask Before a Ruby on Rails Upgrade</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-556"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-413">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-416"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-414">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-415'
	>
	<strong>A Ruby on Rails upgrade is not just a technical task  – it’s a strategic move to keep your app healthy. But before you dive in, there are some key considerations to ensure a smooth transition. We explore what the best agencies ask to ensure your upgrade is a success.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-419"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-417">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-418'
	>
	Modern applications depend on hundreds of downstream dependencies. If you want to ensure your <a href="https://infinum.com/ruby-on-rails-development-services/">Rails app </a>stays stable, secure, and healthy overall, keeping them updated is a must. However, just as we tend to procrastinate on healthy eating and regular exercise until we’re met with a health scare, a <a href="https://infinum.com/rails-support-maintenance/">Ruby on Rails upgrade</a> often lands in the backlog, never to be mentioned again until a critical need arises. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-422"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-420">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-421'
	>
	Whether you’re in a situation where you can’t delay the upgrade any longer or you want to be proactive about dependency health – no judgment in any scenario – a seasoned agency can help you make the process efficient and stress-free, keeping the wheels of your business running smoothly through every change.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-425"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-423">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-424'
	>
	This can only be achieved through careful and structured planning, so before diving into a Ruby on Rails upgrade, here’s what you need to consider and what the experienced agencies will ask to make it happen seamlessly.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-428"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-426">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-427'
	>
	Updating your dependencies is like eating your veggies</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-431"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-429">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-430'
	>
	When applications are built on hundreds of interconnected dependencies, it’s easy to think of them as effortless solutions. After all, these convenient code add-ons are designed to reduce developers’ workload by introducing functionalities that would otherwise require countless engineering hours.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-434"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-432">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-433'
	>
	However, as useful as they are, dependencies come with a catch: they require long-term upkeep. Dependency authors know their library’s behavior well, while your teams know your business logic – but no one can guarantee the two will continue to play nicely together with each new gem version.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-436"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-435'
	>
	<strong><strong>Dependencies get updated over time, and if the matter is left unattended, a team can easily end up with hundreds of outdated dependencies in less than a year.</strong></strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-439"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-437">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-438'
	>
	A Ruby on Rails upgrade process requires so much expert knowledge and causes so much friction that most development teams just sweep the matter under the rug. Bugs, outages, and delays in delivering new features are common side effects of dependency upgrades, which can make the process feel daunting. But dependencies get updated over time, and if the matter is left unattended, a team can easily end up with hundreds of outdated dependencies in less than a year.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-445"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<a	class="card-simple js-card-simple card-simple--is-ad block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-440"
	 target='_blank' rel='noopener noreferrer' href='https://infinum.com/rails-support-maintenance/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<p	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-441'
	>
	Whether you’re still on version 4.x or preparing for the latest Rails upgrade, we can help you get back on track. Let our experienced engineers handle the upgrade process and enjoy the latest features, enhanced security, and better performance.</p>		</div>

		<button	class="btn btn--color-infinum btn--size-small btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-442"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-443'
	>
	Learn more </div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-444'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-448"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-446">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-447'
	>
	What to consider before a Ruby on Rails upgrade (and what the best agencies will ask)</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-451"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-449">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-450'
	>
	When it comes to upgrading Ruby dependencies, preparation is key. An experienced agency will take the time to understand your app’s unique needs and constraints before jumping into the upgrade process.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-454"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-452">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-453'
	>
	From pinpointing your specific reasons for upgrading to mapping out an efficient release strategy, these initial questions help tailor the process to your business. Here are the key areas to consider – and the questions an expert partner will ask – to ensure your Ruby on Rails upgrade goes as smoothly as possible.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-457"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-455">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-456'
	>
	1. Why do you want to upgrade your dependencies?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-460"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-458">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-459'
	>
	Keeping your app updated is an industry best practice, but as we’ve noted before, for most teams, there’s usually a trigger such as:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-463"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-461">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-462'
	>
	<li>Failed upgrade attempts</li><li>Bugs and outages caused by a recent upgrade</li><li>Preparation for a security audit</li><li>A security breach</li><li>A need to access features available in the latest dependency versions</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-466"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-464">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-465'
	>
	To tailor our service to each project, we have to understand your engineering context and stakeholder goals. Depending on your needs, our approach may vary – from prioritizing upgrades for critical security vulnerabilities to focusing on high-impact components like Ruby, Rails, and core gems first.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-469"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-467">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-468'
	>
	Some clients are primarily looking to meet security standards and may want detailed upgrade reports, while others see the process as an opportunity to upskill their team in dependency management. Whatever your aim is, we adapt our process to fit your goals and timeline, ensuring the upgrade aligns with your broader objectives.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-472"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-470">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-471'
	>
	2. What is the scope of your Ruby on Rails upgrade?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-475"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-473">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-474'
	>
	Keeping your Rails app up-to-date and secure goes beyond just managing your Ruby dependencies. So-called dependency rot can affect all downstream components, including those less visible yet equally crucial, such as your operating system, database, and external libraries. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-478"
	 data-animation-target='inner-items'>
		
			<div class="block-group" data-id=es-477>
	
<div
	class="wrapper"
	data-id="es-476"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			
<figure class="wp-block-table aligncenter is-style-regular" style="font-size:20px"><table><tbody><tr><td><strong>Dependency</strong></td><td class="has-text-align-center" data-align="center"><strong>Minor</strong> <strong>versions</strong></td><td class="has-text-align-center" data-align="center"><strong>CVE</strong> <strong>count</strong></td></tr><tr><td>Debian 11 “Bullseye”</td><td class="has-text-align-center" data-align="center">11</td><td class="has-text-align-center" data-align="center"><a href="https://snyk.io/test/docker/debian%3A11">6</a><a href="https://snyk.io/test/docker/debian%3A11" target="_blank" rel="noreferrer noopener">1</a>*</td></tr><tr><td>PostgreSQL 16</td><td class="has-text-align-center" data-align="center">4</td><td class="has-text-align-center" data-align="center"><a href="https://www.cvedetails.com/vulnerability-list/vendor_id-336/product_id-575/version_id-1726422/Postgresql-Postgresql-16.0.html" target="_blank" rel="noreferrer noopener">5</a></td></tr><tr><td>ImageMagick</td><td class="has-text-align-center" data-align="center">15</td><td class="has-text-align-center" data-align="center"><a href="https://www.cvedetails.com/vulnerability-list/vendor_id-1749/product_id-3034/version_id-690599/Imagemagick-Imagemagick-7.1.0-27.html">2</a><a href="https://www.cvedetails.com/vulnerability-list/vendor_id-1749/product_id-3034/version_id-690599/Imagemagick-Imagemagick-7.1.0-27.html" target="_blank" rel="noreferrer noopener">7</a></td></tr></tbody></table></figure>
		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-481"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-479">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-480'
	>
	* Docker image for Debian 11</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-484"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-482">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-483'
	>
	Skipping upgrade cycles for these core dependencies means missing out on critical bug and <a href="https://www.postgresql.org/support/security/CVE-2024-4317/" target="_blank" rel="noreferrer noopener">security fixes</a>, <a href="https://www.crunchydata.com/blog/real-world-performance-gains-with-postgres-17-btree-bulk-scans" target="_blank" rel="noreferrer noopener">performance enhancements</a>, and <a href="https://www.enterprisedb.com/blog/exploring-postgresql-17-new-features-enhancements" target="_blank" rel="noreferrer noopener">new features</a> available in the current version. <br />
<br />
While keeping everything up to date requires significant engineering effort, it’s essential to prioritize it for a secure and efficient system. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-487"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-485">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-486'
	>
	Each upgrade effort comes with a trade-off in terms of time and resources, so weighing these investments against the benefits: reduced exposure to vulnerabilities, improved performance, and access to the latest features is important. We can help you estimate these efforts and assess potential risks so you can make informed decisions on the most valuable upgrades for your application.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-490"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-488">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-489'
	>
	3. How will we ensure your Ruby on Rails upgrade is safe?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-493"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-491">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-492'
	>
	Upgrading a severely outdated application is inherently risky. When we update core dependencies, we’re essentially reconstructing the foundation of an application while keeping its business functionality intact. Even the most minor changes have the potential to trigger a bug or an outage, so it’s important to have a strong verification process in place. While automated tests are the industry norm, we still see applications that either aren’t tested at all or lack coverage for key customer flows. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-495"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-494'
	>
	<strong>Upgrades are rarely just about dependency updates – the biggest challenges lie at the intersection of dependencies and your application’s core logic.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-498"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-496">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-497'
	>
	A solid test suite is the first line of defense. If your automated test coverage is not up to par, we’ll work together to improve it or develop a detailed manual test plan that covers the most important flows and assertions. Since you’re the one who knows your application best, mapping out these flows will require your expert input.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-501"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-499">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-500'
	>
	Once the upgrade process is set in motion, we’re also likely to reach out to you several times daily. To perform the upgrade as safely as possible, we need to understand the context of your past technical decisions and current business logic. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-504"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-502">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-503'
	>
	Upgrades are rarely just about dependency updates – the biggest challenges lie at the intersection of dependencies and your application’s core logic. With thorough preparation, comprehensive testing, and your input, we can perform a safe and effective Ruby on Rails upgrade without unpleasant surprises.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-507"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-505">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-506'
	>
	4. What is your long-term upgrade strategy?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-510"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-508">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-509'
	>
	Software development agencies have a unique perspective on dependency upgrades. We interact with various codebases and have seen the common challenges and long-term pitfalls first-hand. This experience taught us that managing dependencies is not a one-off project – it’s a marathon, not a sprint.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-513"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-511">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-512'
	>
	Partnering with a skilled partner for a Ruby on Rails upgrade can give your application a significant health boost today. However, dependencies are continuously evolving, and within a couple of years, even the best-maintained code can start to show signs of dependency rot if updates aren’t prioritized.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-515"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-514'
	>
	<strong>Without a proactive upgrade strategy, you could quickly end up in the same situation as before in a matter of months, with outdated dependencies piling up.</strong></p></div>	</div>



<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-518"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-516">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-517'
	>
	If you want to focus on your app’s long-term health, your team must learn how to upgrade dependencies safely and implement an ongoing upgrade process. We can help with this by organizing tailored workshops and providing consulting services. In fact, we consider our work successful when we’ve effectively worked ourselves out of a job – and your team has the skills and confidence to manage Ruby on Rails upgrades independently, keeping your app in top shape for the long run. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-521"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-519">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-520'
	>
	5. How comfortable are you with frequent releases?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-524"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-522">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-523'
	>
	From experience, releasing small, frequent, and incremental dependency upgrades is the best way to minimize accidental defects. With minor changes, we can deliver immediate improvements to your application – even on day one – while keeping the “blast radius” manageable and reducing risk to your end users.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-527"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-525">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-526'
	>
	Ideally, we’d release these incremental changes multiple times daily. However, we are aware that many applications face technical, regulatory, or even cultural constraints that prevent us from deploying changes that frequently. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-530"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-528">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-529'
	>
	A full upgrade can involve more than 50 separate pull requests, so it’s important to assess your current release process beforehand and find the right balance between upgrade efficiency and any constraints you might face. Reducing the wait time between releases can significantly impact the total time and cost of your Ruby on Rails upgrade process.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-533"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-531">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-532'
	>
	6. What is your error budget?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-536"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-534">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-535'
	>
	Major dependency upgrades <strong>always</strong> bring unexpected changes. While our experience and best practices help us keep them down to a minimum, some issues are inevitable. For each upgrade, we carefully balance the research, implementation, and verification effort against its potential impact on your application.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-539"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-537">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-538'
	>
	For example, upgrading an internal, non-business critical application with a handful of occasional users involves minimal operational risk, so we take a more liberal approach to research and verification. But we need a steadier, more cautious process for customer-facing applications – where even a minute of downtime can translate to lost revenue.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-542"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-540">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-541'
	>
	Since you know your application best, we rely on your expertise to identify key business transactions in advance. Before we even begin the dependency upgrade process, we also need to make sure your automated monitoring is set up correctly so we can catch any issues early. During a Ruby on Rails upgrade, we’ll pay special attention to the areas of your codebase most affected by the changes, implementing additional safety measures and manual testing as needed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-545"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-543">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-544'
	>
	Never downplay a Ruby on Rails upgrade</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-548"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-546">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-547'
	>
	Too often relegated to the bottom of the backlog, upgrading Ruby on Rails dependencies is a vital step in keeping your app healthy, stable, and ready for future challenges. However, it’s not a process to be taken lightly.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-551"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-549">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-550'
	>
	To ensure everything runs smoothly, safely, and without disruptions to your business operations, it’s important to plan ahead. From defining the scope and determining the order of upgrades between stable versions to verifying updates and establishing a sustainable release cadence, every decision matters.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-554"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-552">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-553'
	>
	We hope this article has highlighted the key considerations when preparing for a Ruby on Rails upgrade. If you’re ready to take the next step or want to learn more about the process, <a href="https://infinum.com/rails-support-maintenance/">our Ruby team is here to help</a>. </p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/ruby-on-rails-upgrade/">6 Questions We Ask Before a Ruby on Rails Upgrade</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>45947https://infinum.com/uploads/2025/02/Lessons_from_escaping_the_Rails_dependency_maze.webp</url>
				</image>
				<title>How We Escaped the Dependency Upgrade Maze on 20+ Projects</title>
				<link>https://infinum.com/blog/open-source-dependency-upgrade-process/</link>
				<pubDate>Wed, 22 Nov 2023 14:12:41 +0000</pubDate>
				<dc:creator>Jaka Šušteršič</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=45947</guid>
				<description>
					<![CDATA[<p>Optimizing our open-source dependency upgrade process, we got 20+ Ruby on Rails projects updated to the latest version, hassle-free. </p>
<p>The post <a href="https://infinum.com/blog/open-source-dependency-upgrade-process/">How We Escaped the Dependency Upgrade Maze on 20+ Projects</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-684"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-557">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-560"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-558">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-559'
	>
	<strong>Open-source dependencies are practical, convenient, time-saving – and sure to make your life miserable if left unattended. Read on to learn how we optimized our dependency maintenance process and got all our Ruby on Rails projects updated to the latest versions with minimum time loss. </strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-563"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-561">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-562'
	>
	Modern applications and frameworks are composed of hundreds of individual dependencies.  Using third-party libraries, frameworks, and other ready-made software components is a time-saver during development. However, dependencies can also incur an often overlooked maintenance cost.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-566"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-564">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-565'
	>
	As a digital agency, we often find ourselves in a situation where we need to perform maintenance on applications with severely outdated dependencies that haven’t been updated in years. These apps present a series of challenges – upgrade efforts are estimated in months, the development pace is slower, and they are often susceptible to numerous security vulnerabilities.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-569"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-567">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-568'
	>
	In this article we will present our process and tooling improvements that helped us increase dependency health for more than 20 <a href="https://infinum.com/ruby-on-rails-development-services/">Ruby on Rails projects</a> under our maintenance in the last couple of years.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-572"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-570">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-571'
	>
	The open-source dependency blind spot</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-575"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-573">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-574'
	>
	Modern software development relies heavily on open-source dependencies. The developer community maintains countless dependencies for all possible use cases in the diverse software landscape. Feature development used to take a lot of effort, and now a large portion of it can be easily replaced by adding a single line to the Gemfile and setting some initializer options. It’s an elegant solution – why write lines and lines of code when the dependency’s author already designed, implemented, reviewed, and tested the exact functionality your project requires; all you have to do is include it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-577"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-576'
	>
	<strong>We’re living in the golden age of software reusability. Rails allows us to hit the ground running and develop MVPs in days. Do you need authentication? Just add <code>devise</code>. Need an admin dashboard as well? Just add <code>active_admin</code> and head out to lunch!</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-580"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-578">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-579'
	>
	This is not reserved only for the Ruby ecosystem; other software development camps also <a href="https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code" target="_blank" rel="noreferrer noopener">heavily rely on the work of open-source authors</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-583"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-581">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-582'
	>
	However, the problem with using third-party components is that we tend to take care of our own code garden and rarely think about maintaining downstream dependencies. Our codebases evolve, but so do our dependencies.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-586"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-584">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-585'
	>
	Open-source authors spend considerable time maintaining their libraries during their support life cycle. They introduce new features, fix bugs, and even introduce performance enhancements. All we have to do to reap the benefits is to upgrade to the current version, yet we seldom do so.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-589"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-587">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-588'
	>
	Horror stories from the field</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-592"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-590">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-591'
	>
	One of the benefits of agency work is the variety of projects and situations that we encounter. During the last 18 years, we’ve worked with countless client applications, and at any given moment, we’re also actively maintaining around ten internal ones.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-595"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-593">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-594'
	>
	It’s not uncommon for us to take over a larger client project that is two or more Ruby on Rails versions behind. Just recently, we started supporting a Ruby on Rails project started seven years ago, and dependency upgrades were the first order of business. Bringing the application to the latest major Ruby and Rails version took more than 500 hours of development work. That’s a big chunk of time to pay for a one-time upgrade.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-598"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-596">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-597'
	>
	However, this situation is far from uncommon – even <a href="https://github.blog/2018-09-28-upgrading-github-from-rails-3-2-to-5-2/" target="_blank" rel="noreferrer noopener">GitHub took a year and a half to upgrade Rails from 3.2 to 5.2</a> before they adopted a continual upgrade strategy.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-600"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-599'
	>
	<strong>Dependency upgrades are typically low priority and, as such, often deferred. The resulting cost is not immediate, and the incurred debt is usually paid in bulk after several years of development with considerable interest.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-603"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-601">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-602'
	>
	Understanding framework changes, auxiliary gem changes, and how they interact with your codebase is a big undertaking. Running <code>bundle update devise</code> for a single dependency is trivial, but understanding the change described in a dependency changelog requires a lot of context. Good automated test coverage helps build confidence in the upgrade, but we’re still often pushing out a risky code change we aren’t entirely comfortable with.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-610"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<a	class="card-simple js-card-simple card-simple--is-ad block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-604"
	 target='_blank' rel='noopener noreferrer' href='https://infinum.com/rails-support-maintenance/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<h2	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-605'
	>
	Whether you’re still on version 4.x or preparing for the latest Rails upgrade, we can help you get back on track. Let our experienced engineers handle the upgrade process and enjoy the latest features, enhanced security, and better performance.</h2>		</div>

		<button	class="btn btn--color-infinum btn--size-small btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-607"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-608'
	>
	Learn more </div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-609'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-613"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-611">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-612'
	>
	The wake-up call</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-616"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-614">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-615'
	>
	Always focusing on client-requested feature work, we were also guilty of often sweeping our dependency updates under the carpet. When Rails 7 was introduced around two years ago, we were faced with the exact amount of our technical debt. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-619"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-617">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-618'
	>
	Wanting to capitalize on all the newly related features (<a href="https://guides.rubyonrails.org/active_record_encryption.html" target="_blank" rel="noreferrer noopener">ActiveRecord encryption</a>, <a href="https://edgeapi.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-load_async" target="_blank" rel="noreferrer noopener">ActiveRecord load_async</a>) across all projects under our care, we decided to conduct a fleet dependency health review.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-622"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-620">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-621'
	>
	Most applications shared some common characteristics:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-625"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-623">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-624'
	>
	<li>One or two major Ruby on Rails versions behind</li><li>Strong focus on feature development </li><li>Minimal amount of dependency upgrades</li><li>Core gems (e.g., sidekiq, devise, axlsx, …) two or more major versions behind</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-628"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-626">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-627'
	>
	Bringing just one project up to date seemed like a big chore and getting all of them back on track seemed infeasible. We have performed considerable dependency upgrades before, but planning, estimating, and safely executing a mass wave of upgrades on applications under our care was uncharted territory.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-631"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-629">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-630'
	>
	We realized that we couldn’t continue on the same upgrade path. Our team needed to improve our dependency upgrade culture and processes to repay the debt and prevent it from accruing again. It was time to figure out how to perform the upgrades safely and do a better job of tracking and executing dependency upgrades on internal and client projects in the future.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-634"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-632">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-633'
	>
	Our dependency upgrade initiative</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-637"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-635">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-636'
	>
	After interviewing several internal project teams and looking at <a href="https://shopify.engineering/living-on-the-edge-of-rails" target="_blank" rel="noreferrer noopener">industry</a> <a href="https://github.blog/2018-09-28-upgrading-github-from-rails-3-2-to-5-2/">best</a> <a href="https://engineering.gusto.com/how-we-upgraded-rails-safely/">practices</a>, we identified the weakest points in our dependency upgrade culture and came up with a set of resources and guidelines to help us get to the next level.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-640"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-638">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-639'
	>
	Mandated upgrades</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-643"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-641">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-642'
	>
	The most significant change we introduced was mandating <strong>small but</strong> <strong>frequent</strong> dependency upgrades <strong>on all projects</strong>. Regular (and minor) dependency upgrades are more predictable, safer, and easier to plan than large ones. With a little inventiveness, all upgrades can be performed in bite-size chunks. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-646"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-644">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-645'
	>
	Dependency triage</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-649"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-647">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-648'
	>
	Upgrading dependencies is a never-ending process since new versions are released daily. To stay on top, we need to be as efficient as possible. Not all dependency upgrades have the same impact, and we should prioritize them accordingly:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-652"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-650">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-651'
	>
	<li>Security upgrades</li><li>Rails upgrades</li><li>Ruby upgrades</li><li>Direct dependency (e.g., devise, sidekiq, action_policy, …) upgrades</li><li>Transitive dependency (e.g., aws-sdk-s3, down, …) upgrades</li><li>Development/test dependency upgrades</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-655"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-653">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-654'
	>
	Prioritizing security upgrades</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-658"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-656">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-657'
	>
	We emphasized the urgency of the security upgrade by requiring all project teams to perform CVE triage and resolution within one business day. Each additional day of exposure to a CVE in the wild increases the likelihood that an automated vulnerability scanner will find the application and exploit it. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-661"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-659">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-660'
	>
	Planning major upgrades</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-664"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-662">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-663'
	>
	Rails upgrades should be carefully researched and planned in multiple stages as defined by our <a href="https://infinum.com/handbook/rails/workflows/rails-upgrades" target="_blank" rel="noreferrer noopener">guide</a>. Revolutionary upgrades are strongly discouraged. We want to move in small, predictable, and reversible steps to reduce the likelihood of regressions. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-667"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-665">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-666'
	>
	Tracking upgrades over time</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-670"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-668">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-669'
	>
	Project dependency health should be easy to determine programmatically. Tracking it for all projects under our care over time allows us to gauge our progress and hold data-backed discussions with stakeholders.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-673"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-671">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-672'
	>
	Implementing these changes required not only changing the process but also some new tooling.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-676"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-674">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-675'
	>
	<strong>Tracking dependency health with Revisor and Polariscope</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-679"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-677">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-678'
	>
	Tracking dependency health over time can be performed manually for individual projects, but keeping up with the 20+ active projects we support requires some automation. We decided to invest some time into building basic and effective tooling that would enable us to easily keep an eye on the health of our applications.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-682"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-680">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-681'
	>
	For this purpose, we built an application called Revisor. It periodically aggregates Ruby dependency health data of all the projects in a GitHub organization and exposes it in a simple dashboard.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-687"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-685"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-686">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/11/revisor_dashboard.webp"
					class="image__img block-media__image-img"
					alt=""
										height="891"
															width="1372"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-693"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-688">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-691"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-689">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-690'
	>
	The core logic is simple: we query all Ruby repositories in our Github organization daily and evaluate their <code>Gemfile.lock</code>. Each project is then assigned a dependency health score, which is based on the following formula:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-696"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-694"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-695">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/11/formula-2-1400x527.webp				media='(max-width: 699px)'
				type=image/webp								height="527"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/11/formula-2-2400x903.webp				media='(max-width: 1199px)'
				type=image/webp								height="903"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/11/formula-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1028"
															width="2732"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-699"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-697"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-698">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/11/formula-1-1400x527.webp				media='(max-width: 699px)'
				type=image/webp								height="527"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/11/formula-1-2400x903.webp				media='(max-width: 1199px)'
				type=image/webp								height="903"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/11/formula-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1028"
															width="2732"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-705"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-700">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-703"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-701">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-702'
	>
	The data is presented on a simple dashboard for software developers, but we also decided to periodically showcase the information on project Slack channels so stakeholders can see our progress.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-708"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-706"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-707">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/11/Screenshot-2023-11-22-at-13.28.29.webp"
					class="image__img block-media__image-img"
					alt=""
										height="820"
															width="1322"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-758"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-709">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-712"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-710">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-711'
	>
	We’ve extracted the dependency health calculation logic from Revisor into a gem called <a href="https://github.com/infinum/polariscope">Polariscope</a>. To use it, make sure you’re running Ruby 3.0.0 or later.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-715"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-713">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-714'
	>
	The health score is most useful as a relative measure. It starts at 100 and decreases as new versions or security issues emerge. For example, your project might have a score of 99 one day, but it could drop to 90 the next — indicating something significant happened, like a security advisory for an important dependency (e.g., Rails) or the release of a new major version of Ruby. On the other hand, a drop from 99 to 97 might just mean a minor version update for one of your dependencies.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-718"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-716">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-717'
	>
	It’s up to you to decide when to act: either when the score drops suddenly (to address immediate issues) or when it falls below a certain threshold (to update multiple dependencies at once).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-721"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-719">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-720'
	>
	Ranking the projects proved to be a great incentive for both the development teams and stakeholders. Development teams take pride in having the least amount of outdated dependencies and patching the newest CVE first. On the other hand, stakeholders sometimes get curious about how other project teams are getting better results and what it would take to catch up with them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-724"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-722">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-723'
	>
	Improving stakeholder awareness</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-727"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-725">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-726'
	>
	Before we launched our initiative, most project stakeholders weren’t accustomed to dependency upgrades. We discussed and executed general software maintenance items before, but we didn’t put much emphasis on dependency upgrades besides the occasional Rails upgrade. They were suddenly faced with an additional (recurring!) amount of work that would reduce our feature output in the mid-term. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-729"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-728'
	>
	<strong>On average, we spend about eight hours per month to keep up with dependency upgrades on a healthy project continually. We can easily plan for that and perform it seamlessly with feature development going on in parallel. </strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-732"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-730">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-731'
	>
	On the other hand, upgrading severely outdated projects requires months of development time and blocks most feature delivery.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-735"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-733">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-734'
	>
	With internal projects, we had strong support from technical leadership as we had seen the effects and cost of deferring upgrades firsthand. Introducing our new standard to client projects was a longer discussion, but our incentives turned out to be very much aligned. We all want to make our dependency upgrade process as lean and predictable as possible so that feature output can be continuous.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-738"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-736">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-737'
	>
	Regular, smaller dependency upgrades allow us to meet all of those requirements. Keeping the application healthy for optimal development speed is just the icing on the cake.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-741"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-739">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-740'
	>
	Tracking progress over time</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-744"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-742">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-743'
	>
	Introducing culture and process changes is a noble goal in itself, but we also wanted to get some empirical data on the changes we introduced. The idea was to visualize the past state and evaluate whether our decisions led us to a better overall outcome.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-747"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-745">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-746'
	>
	Revisor provides us with a current project dependency health score and answers the question “What’s the current dependency health of the project?”. On the other hand, to answer “How has our dependency health progressed over the last year?” requires historical data.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-750"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-748">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-749'
	>
	When we posed this second question, Revisor was still in its infancy, so we relied on another data source – Rubygems.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-753"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-751">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-752'
	>
	Rubygems holds historical data (version, release date) about all published gems. This allows us to obtain <a href="https://rubygems.org/pages/data">a publicly available database dump</a> and determine which version of a specific gem was the most recent one at any point in time. The last remaining input is the exact version of the gem that the project had used at a point in time, which can be determined through git history.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-756"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-754">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-755'
	>
	Our script iterates over the defined date range, checks out <code>Gemfile.lock</code> from a specific date, and counts the number of outdated gems in the lock file on that date. A gem is considered outdated if a higher version was released before the specific date we’re evaluating. Outdated gem counts per date are then printed to standard output for further plotting.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-761"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-759"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-760">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/11/dependency_graph_2-1400x861.webp				media='(max-width: 699px)'
				type=image/webp								height="861"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2023/11/dependency_graph_2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1010"
															width="1642"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-809"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-762">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-765"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-763">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-764'
	>
	Interpreting the graphs is not an exact science, but generally speaking, we expect the number of outdated gems to rise over time as new gem versions are released. The effort of the development team is seen when the number of outdated gems is reduced, either through dependency upgrades or dependency removals. We can observe the frequency and scale of those changes to determine if the trend points downward. With these graphs, both the development team and the stakeholders get a clear picture of the project dependency health trajectory.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-768"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-766">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-767'
	>
	We’ve recently discovered a new tool that helps visualize this historical data: <a href="https://github.com/infinum/rails-infinum-gemorama/" target="_blank" rel="noreferrer noopener"><strong>Gemorama</strong></a>. It’s a public Rails application that generates charts showing the number of outdated gems in Ruby projects over time. Gemorama creates a timeline for each date, making it easier to spot trends and assess dependency health. While it’s not live yet, you can clone it. The README includes detailed instructions on how to set it up and use it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-771"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-769">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-770'
	>
	Goals achieved</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-774"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-772">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-773'
	>
	Improving our dependency update posture took a while, but I can happily say that our efforts have paid off. In the end, we’ve managed to accomplish all of our goals:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-777"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-775">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-776'
	>
	<li>All projects receive (bi)weekly dependency upgrades</li><li>The vast majority of CVEs are resolved within a business day</li><li>All projects are using the latest major version of Rails</li><li>All projects are using the latest major version of Ruby</li><li>We have a good understanding and visualization of dependency health across all projects</li><li>The vast majority of projects have a dependency health score higher than 70</li><li>Dependency upgrades are prioritized and planned</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-780"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-778">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-779'
	>
	What’s more, we have also amassed a great deal of upgrade experience over the past two years. We’re now better versed in researching, planning, and executing complex dependency upgrades.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-783"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-781">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-782'
	>
	<strong>Automating dependency management</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-786"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-784">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-785'
	>
	As part of our ongoing effort to streamline dependency maintenance, we decided to introduce automation to handle repetitive tasks such as minor upgrades and patches. For this purpose, we use Dependabot, with a <a href="https://gist.github.com/cilim/4bfbc1beedb8edd2a6cb6db128b0108f" target="_blank" rel="noreferrer noopener">configuration </a>that has been tested and proven in production on our apps. This setup automatically creates three pull requests (PRs) for each update cycle, covering both direct and transitive dependencies, as well as non-major production gems, development and test gems, and Rubocop gems.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-789"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-787">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-788'
	>
	However, we don’t advise merging all three PRs at once. Instead, apply them one by one and deploy each to a staging environment first. Gemfile.lock conflicts can be tricky, so handling each PR individually helps avoid potential issues. We typically perform a quick deployment to staging, run basic smoke tests on a few apps to verify everything is functioning correctly, and once we’re confident, we merge to production. After merging one PR, you can leave a comment on the next one, and Dependabot will automatically reopen it and resolve any conflicts. Then, repeat the process for the third PR.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-792"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-790">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-791'
	>
	This entire workflow usually takes less than eight hours, after which your application is fully up to date. The best part is that all gem changelogs are available in one place, so you can review any changes before merging. And if you have a CI/CD pipeline with GitHub Actions, passing specs provide an extra level of confidence. Once everything checks out, you can move forward with the changes, knowing your app remains stable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-795"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-793">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-794'
	>
	Refining the dependency upgrade process brings extra value</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-798"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-796">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-797'
	>
	The number of projects we maintain as an agency presents a unique set of challenges. However, our foray into improving dependency upgrade processes and internal tooling has allowed us to bring our service to the next level.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-801"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-799">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-800'
	>
	Starting with a very grim report sheet – a large portion of our projects more than two major Ruby and Ruby on Rails versions behind, we’ve now brought all of our projects up to date with the latest major Ruby and Ruby on Rails versions.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-804"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-802">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-803'
	>
	Dependency upgrades are a core part of our service, and most projects are on a bi-weekly upgrade schedule. By increasing the frequency of dependency upgrades, we drastically reduced their difficulty but also brought additional value to our clients – their apps are now faster, safer, and up to date.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-807"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-805">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-806'
	>
	<em>If you need any help getting your dependencies in order, check out our <a href="https://infinum.com/rails-support-maintenance/" target="_blank" rel="noreferrer noopener">Rails support and maintenance services</a>. </em></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/open-source-dependency-upgrade-process/">How We Escaped the Dependency Upgrade Maze on 20+ Projects</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>