Rails Upgrades
Keynote: The Past, Present and Future of Rails at GitHub

Summarized using AI

Keynote: The Past, Present and Future of Rails at GitHub

Eileen M. Uchitelle • May 17, 2019 • Sofia, Bulgaria

In her talk titled "The Past, Present and Future of Rails at GitHub" at Balkan Ruby 2019, Eileen Uchitelle, an engineer at GitHub and a member of the Rails core team, discusses the journey of upgrading GitHub’s application from old versions of Rails to modern ones. The talk explores the relationship between GitHub and Rails, illustrating how decisions made long ago resulted in a significant technical debt that complicated their ability to upgrade. Eileen emphasizes the importance of understanding the consequences of technical debt, recounting the history of Rails and GitHub’s early use of Rails, including when they forked Rails due to various performance issues. She highlights the struggles faced during major upgrades, specifically covering the seven-year period it took to upgrade from Rails 3 to 5.2.

Key points discussed include:
- The historical context of Rails and its evolution since its inception in 2004.
- GitHub's early decisions to fork Rails, which led to increased technical debt over the years.
- The cost of not upgrading, including security vulnerabilities, challenges in hiring, and adopting new features.
- The strategic implementation of an upgrade plan, including creating a dedicated team for the upgrade effort and developing tools to ease the transition.
- The successful upgrade processes used at GitHub, showcasing the use of dual booting to allow testing for multiple Rails versions simultaneously.
- The long-term benefits of maintaining a current version of Rails, such as improved security, performance, and the ability to contribute back to the Rails community.
- The speaker concludes by encouraging others not to fear upgrading, emphasizing that continuous upgrades lead to a healthier code base and a sustained ability to innovate.

Ultimately, the talk illustrates that while the upgrade path is challenging, it is crucial for the long-term success of applications that rely on frameworks like Rails, fostering an environment for community contributions and technological advancements.

Keynote: The Past, Present and Future of Rails at GitHub
Eileen M. Uchitelle • May 17, 2019 • Sofia, Bulgaria

Balkan Ruby 2019

00:00:24.390 Just to be clear, it was Paris's fault that I missed my flight. The passport line was really long, and I don’t know, they just didn’t want to wait for me.
00:00:37.920 As mentioned, I'm Eileen Uchitelle. You can find me anywhere online at the handle 'EileenCodes'. That's on Twitter, GitHub, my blog, which I never write in, and my email.
00:00:52.649 I’m an engineer at GitHub. I work on the Ruby architecture team, where our team is responsible for looking at how our application can work better with Rails and Ruby, and how Rails and Ruby can support our application.
00:01:04.769 We set standards, consult on other projects, assess the existing system—basically, we deal with technical debt. I’m on the Rails core team. For those of you who are not familiar with how the Rails team operates, the core team is responsible for the future of the framework.
00:01:17.159 We decide what’s going to go into the next release, when to release, and all that good stuff that goes along with releasing. Each year I reflect on what I’ve learned, the work I’ve been doing, and what I’d like to share with you all at upcoming conferences.
00:01:36.390 When I started writing the abstract for this talk, I originally thought that I wanted to talk about the intimate details of upgrading Rails at GitHub. I had spent a year and a half upgrading GitHub from Rails 3 to 2.5.
00:01:48.030 I certainly could talk about it for hours, maybe even days, until you were all bored. But as I started to explore the themes around upgrading, I realized that there was a deeper story that I wanted to explore.
00:02:09.599 I began wondering how we ended up so far behind Rails master in the first place. What decisions did we make that caused the upgrade to be so much more difficult than it should have been? What drove us to upgrade when we were so far behind?
00:02:28.980 The story that I want to tell you is about the past, present, and future of Rails at GitHub. We've been using Rails at GitHub since day one, and at times, GitHub and Rails have had our differences.
00:02:39.270 Many years ago, we forked Rails and practically wrote our own version. We fought against the framework, we deviated from it, and we even wondered if Rails was right for us at all.
00:02:57.480 But at the end of the day, GitHub is successful because of Rails, and Rails is successful because of GitHub. Our upgrade didn’t just make for a good blog post for Hacker News to criticize; the upgrade made it possible for us to use and invest in Rails for the long haul.
00:03:13.290 We can change and influence the framework for our needs while also benefiting the broader Rails community and open-source ecosystem. This story is partly historical; we'll look back at the beginning and how GitHub ended up maintaining a custom fork of Rails 2.
00:03:26.700 It’s also part technical, exploring what compelled us to upgrade our process and why it was so difficult. We’ll look at the costs of not upgrading and how technical debt accumulates in your application until it starts working against your framework.
00:03:43.620 Lastly, this story is part forward-looking; we’ll highlight our effort at GitHub to clean up technical debt, our commitment to open source, and our responsibility to support Rails for the long haul.
00:04:00.480 Let’s go back to the beginning. In 2004, DHH announced a new Ruby framework called Ruby on Rails. Immediately, Rails caught the attention of the Ruby community.
00:04:14.310 At RubyConf that year, DHH talked about Rails—the history of Rails, how it came to be, and of course, why it was better than existing Ruby frameworks. He went on to discuss his philosophy behind building the framework, most notably that many frameworks fail because they are built without an application in mind.
00:04:36.180 He stated that frameworks are retrospectives; they should be extracted, not built. Rails was attractive and successful because it was extracted from a real application: Basecamp.
00:04:55.830 In the early years, Rails' complexity grew slowly. Rails 1.0 was released in December of 2005, followed by Rails 1.2 two years later. That same year, Tom Preston-Warner, at a Ruby meetup in San Francisco, showed his friend Chris Wanstrath a tool called Grit.
00:05:12.370 Grit was a Ruby tool that allowed you to view Git repositories in an object-oriented way and would later become the basis for Git repositories on GitHub. After seeing Grit, Chris was immediately hooked, and a few days later, the GitHub Rails application was born.
00:05:29.520 GitHub was created using Rails 1.2.3, and after a brief beta, it was launched publicly in April of 2008. The next day, Rails moved from their own SVN server to GitHub.
00:05:43.150 In 2009, Rails 2.3 was released, and in the early days, whenever Rails would release a new version, GitHub would quickly upgrade to take advantage of new features and bug fixes.
00:05:50.760 But sometime between 2008 and 2009, GitHub had forked Rails. I couldn’t find an exact date because we vendored our gems at GitHub, and there weren’t any commits that made it clear when we forked. Personally, I had always thought that we forked Rails for 3.0 because it was very slow—slow enough that many applications couldn’t upgrade.
00:06:21.150 But it turns out that had nothing to do with why we forked Rails, and it was long before we even knew 3.0 was a problem. Now remember, this was the Wild West of Rails startups. Nobody really knew what the future of Rails or GitHub was going to be.
00:06:33.130 We weren’t yet discussing the importance of upgrading or staying current with Rails master, and honestly, Rails wasn’t as stable as it is today. I don’t want to say that Rails didn’t care about performance at that time, but many app developers felt that way.
00:06:51.080 Maybe that was because we were all inexperienced back then, or maybe it was because Rails was good enough for its most important user, Basecamp. Or maybe it was because we at GitHub didn’t contribute enough upstream.
00:07:03.680 I'm not criticizing the past, but it's important to examine why we ended up here, so we can learn for the future. The real problem was that GitHub didn’t just fork Rails and add a bug fix here or a performance improvement there.
00:07:34.090 It wasn’t just backports from upstream on the fork; GitHub forked Rails with custom code just for GitHub. It was Rails morphed into a different framework built specifically for GitHub, similar to how Rails was built for Basecamp.
00:07:52.490 As GitHub doubled down on their fork and added more and more functionality, Rails continued to progress at a rapid pace.
00:08:02.330 At this time, nobody could predict or understand the cost that forking Rails would have on GitHub’s application and engineering team. In 2010, Rails 3.0 was released, but many applications couldn't upgrade due to the performance concerns I mentioned earlier.
00:08:20.210 The performance issues in Rails 3.0 were a big deal; users saw an unacceptable increase in response times. Some applications experienced request times that took as long as twice as long.
00:08:36.680 After it was found that Active Record in Rails 3 was five times slower than Rails 2, despite knowing about these concerns, an engineer at GitHub known as TMM1 started working on upgrading GitHub from Rails 3 to Rails 3 and Ruby 1.9.
00:08:55.260 GitHub hadn’t just forked Rails before Ruby 2, which made our upgrades even more difficult. The Rails 3 upgrade wasn’t pointing at Rails 3 upstream either; it was still a fork of Rails 3 with custom patches added on top.
00:09:15.620 From experience, I can tell you that maintaining a fork while trying to upgrade and simultaneously adding all the new stuff on top of that old version can be enough to make one want to quit programming. I don’t recommend it.
00:09:35.440 In 2012, Rails 3.2 was released, and most of the performance concerns were fixed by Iron Ruby and other contributors. In the same year the performance issues were addressed, GitHub’s progress on the Rails upgrades stalled.
00:09:55.620 It had been two years since they started the 3.0 upgrade, and the engineering team started questioning whether the effort was worth it at all. They asked each other: Why upgrade when this version isn’t causing us pain? Why upgrade when Rails 3.0 just isn’t that great? Why upgrade when our fork has more features?
00:10:18.890 Looking at these questions, the engineering team decided the upgrade wasn’t worth their time and focused their attention on other projects. The truth is that, at that time, GitHub wasn’t yet feeling the pain of being on a fork of Rails.
00:10:36.900 It’s really difficult to convince a team to upgrade when they’re still feeling productive. You improve your tests when they feel too slow; you refactor complexity of that class when you need to add functionality. But when do you upgrade? What’s the incentive?
00:10:55.280 If the new version isn’t better and your fork is working just fine, if you're not feeling the pain of being on a fork or an old version, you're not going to be compelled to upgrade.
00:11:08.050 Eventually, all of these 'why should we upgrade?' questions became suffocating for the engineering team. It became harder and harder to delineate where the framework ended and the application began.
00:11:22.910 As GitHub engineers started to fight against the fork, the application security backward compatibility was a nightmare. Each time Rails announced a security vulnerability, GitHub was forced to manually patch that vulnerability.
00:11:39.390 Hiring became increasingly difficult; nobody wanted to work on a Rails 2 to 3 application that didn’t resemble Rails 2. It was harder to get up to speed, and you couldn't Google search how to do anything.
00:11:58.730 Dependencies were brittle and unsupported as gem authors focused on new versions of Rails; development was slow and painful. Working with an application that’s tied so heavily to a custom fork makes adding features or refactoring code increasingly difficult.
00:12:16.600 We realized we had to get off of the fork; that fork was going to suffocate the application. In 2014, a team of four full-time engineers, along with a few volunteers, banded together, wrote an upgrade plan, and started to work.
00:12:31.030 It took the team six months of full-time coordinated effort to deploy Rails 3.2 to production, and a few months later, they deployed Rails 3.2 as well. It’s important to remember here that 3.0 and 3.2 are still forks of Rails with custom GitHub patches added on top.
00:12:46.530 By this time, the Rails 3 series was only receiving security patches, so even though the upgrade was a success, the fork was still very far behind. The effort put into upgrading from 3.0 to 3.2 was massive, and motivation dwindled after that.
00:13:07.260 It would be another two years before the full upgrade was started. That same year, Rails 5.0 came out, and it felt as if GitHub was never going to catch up. Rails was constantly releasing new versions, and GitHub was still so far behind.
00:13:23.070 In 2017, I joined GitHub. At this point, the Rails 4.0 upgrade wasn’t in good shape; there was no dedicated team working on it, and the upgrade had fallen by the wayside.
00:13:39.230 On my first day, I asked Huw to run the Rails 4.0 tests and noticed there were over 4,000 failures. Luckily, Huw can’t count, and the number was more like two and a half thousand—really easy, right?
00:13:55.050 After the 3.0 upgrade, GitHub engineers had at least added some tooling to help make Rails upgrades easier. We had a system that allowed us to dual boot the application in multiple Rails versions.
00:14:14.450 This means that we don't need to maintain long-running upgrade branches. By adding the ability to dual boot, we can focus only on test failures instead of merge conflicts.
00:14:29.850 Unfortunately, this method also requires us to hack Bundler, but I'd rather hack Bundler than use a fork of Rails. With this method, we were able to boot the application server console and run tests in multiple Rails versions.
00:14:46.300 It made it easy to compare and contrast behavior between the version we were using in production and the version we were trying to upgrade to. This process allowed us to incrementally upgrade Rails and prevent regressions.
00:15:04.110 Once we had an upgraded version, everyone had to write code that worked in both 3.2 and 4.0. When we got the 4.1 build green, everyone had to write code that passed in both versions, and we continued that process until we got to 5.2.
00:15:20.180 Now, we do 5.2 and 6 concurrently in the application code. We use helper methods that easily allow us to condition for different Rails versions: we always put the production version in the 'if' clause and the future code in the 'else'.
00:15:40.310 That way, when we upgrade to 4.2, we don’t fall into the 3.2 code path; we fall into the 'else' code path. In March of 2018, a year and three months after I started at GitHub, we deployed 4.2 to production with zero downtime and no customer impact.
00:15:55.800 After deploying 4.2 to production, I wanted to get started on 5.0 right away because I didn't want what happened with the 4.0 upgrade to happen to the 5.0 upgrade. However, I was really burned out.
00:16:10.600 I felt like this Mac over here, just like the blue screen of death. I had been the only engineer working full-time on the Rails upgrade. There were engineers at GitHub helping out when they had time, but it was on a volunteer basis.
00:16:25.390 Upgrading Rails was a difficult and lonely task, and I decided there was no way I would do the 5.0 series alone. So, for the Rails 5 series, I led a team of four full-time engineers.
00:16:38.230 By this time, we had learned what processes worked and what didn’t, so I used GitHub projects in the tool and our CI to create issues out of the unique failures in the build. This prevented duplicate work and made tracking progress on the upgrade easier.
00:16:55.050 Because we had a dedicated team and a streamlined process, the upgrade from 4.2 to 5.0 took only five months. In August of 2018, we deployed Rails 5.0 to production, also with zero downtime and no customer impact.
00:17:10.350 We learned a lot from the 4.0 upgrade, so we were less nervous about deploying the 5.0 version. Our test suite is relatively solid, at least for upgrade purposes, and we had a very clear rollout plan.
00:17:24.170 This was a huge milestone. It was the first time in ten years that GitHub wasn’t on a fork of Rails; it was the first time in ten years that GitHub was on the most recent version of Rails.
00:17:47.310 That's ten years of cumulative technical debt from being on a fork and years of fighting that fork in our application. We had finally started to pay that debt off by upgrading.
00:18:01.920 We don’t eliminate technical debt, but we create breathing room in the application that we hadn’t had in a decade. I hope that learning about our upgrade hasn’t scared you from doing your own.
00:18:24.430 The point of this talk isn’t to share horror stories; it’s to show you that there’s a cost to not upgrading, and that cost is cumulative. After hearing about the Rails upgrade at GitHub, many engineers come to me asking how they can convince their leadership team to support an upgrade.
00:18:45.780 They often say they don't have the resources, or it's not in their roadmap, or they think it will be too expensive. It’s true that upgrading Rails is expensive and time-consuming; I won’t lie to you.
00:19:06.030 But it’s a lot easier to say, 'This upgrade will need X number of engineers at Y number of dollars for Z number of hours.' You can measure that cost and decide whether it’s too expensive.
00:19:25.500 At the end of the day, it doesn’t matter how expensive or how much it really costs to upgrade your application—because the cost of not upgrading your application is immeasurable.
00:19:47.050 Not upgrading your application will cost you more money than any upgrade due to the debt that will accumulate over time. When you don’t upgrade Rails, you have to become a security expert.
00:20:08.750 The Rails core team only supports patching security issues in the main current version and major versions of the previous version. This means that once 6.0 comes out, we will only be supporting 5.0, 5.1, and 6.0.
00:20:27.060 That means Rails 4.0 won’t be supported anymore after 6.0 comes out, and there’s no grace period—it’s just done. So if you’re using Rails, your team is going to have to patch those security vulnerabilities yourself.
00:20:42.480 And it’s really hard to get this right because we try not to reveal how to exploit any vulnerabilities in Rails to protect users. You can’t upgrade; not upgrading means that your team has to know how to patch vulnerabilities.
00:21:03.670 When you don’t upgrade Rails, you lose great talent: bootcamp grads, college grads, and engineers who are changing careers. Every engineer wants to work with the latest and greatest tools.
00:21:24.520 If you're still on Rails 3.2, they’re not learning that old version, and they're definitely not learning your weird custom fork. Those engineers don’t just not want to work on an old version; they lack the knowledge of how that version even worked.
00:21:42.400 Engineers will turn down opportunities to work for you if you're on an old version, because that version doesn't let them contribute upstream. It’s no longer Google-able, and it’s ten years old.
00:22:03.350 When you don’t upgrade Rails, some of the gems you rely on will get abandoned or deprecated, which means you’ll either have to live with bugs or fork yet another dependency. New gems may not support old versions of Rails.
00:22:22.570 This makes development harder. Every choice that you have regarding dependencies becomes more difficult as you fall further behind. Maintaining old gems on top of your old framework will become tedious and annoying very quickly.
00:22:45.560 When you don’t upgrade Rails, you end up building more on top of your fragile application. I've seen this firsthand at GitHub; we have tons of infrastructure code in our app that doesn’t belong there.
00:23:04.160 Multiple databases, CI tooling, our own job queue—all of these things complicate our application unnecessarily. Ideally, your application should consist only of the code that makes your application do what it's supposed to do.
00:23:22.020 GitHub’s value is not in having code that makes multiple databases work; our value lies in our community, our issues, our data, and our repositories.
00:23:36.260 Multiple databases allow us to keep our application up and running, but they are not what customers use our application for. This infrastructure code complicates development and creates pain due to tightly coupling your application to the framework.
00:23:54.230 Minor changes can quickly turn into massive multi-week refactorings or even an abandoned project altogether.
00:24:04.940 But the biggest consequence of not upgrading Rails is that someday someone at your company will decide that using Rails is just too expensive and that it was a mistake. Then it will be time to carve your application into microservices.
00:24:23.790 Now, this isn’t a language war talk, and I’m not criticizing Go or how other people build their apps or services. But we are at a Ruby conference, so I’m going to assume that you at least like writing Ruby.
00:24:40.630 I love writing Ruby and I want to keep getting paid to write it. It might seem like an exaggeration, but if we don't upgrade Rails, we don't get to keep writing Ruby.
00:24:54.180 The Ruby ecosystem won't improve; our applications will degrade severely, and we’ll be faced with an expensive rewrite. Upgrades might cost a lot, or rewrites have a hefty price tag as well—they might even cost you your job.
00:25:16.450 The key to upgrading Rails is to incrementally pay off the cumulative technical debt that you’ve incurred and devise a plan to keep that debt paid down.
00:25:35.250 I won’t stand here and lie to you and say that upgrading Rails will be easy. I’ll leave that to the person on Hacker News who wondered why I couldn’t do it faster because they upgraded in a weekend. Clearly, I must just be doing something wrong.
00:25:54.640 The upgrade did take a long time, but it wasn’t all I worked on. I also took time to delete unused features, rewrote our custom test framework, and improved our database handling and development tests.
00:26:14.250 It's unfair for someone to look at our upgrade timeline and conclude that because of that, using Rails is too expensive. We made choices at GitHub that made our upgrade take longer.
00:26:30.320 You have made choices in your application that will make your upgrade harder, but that doesn’t mean that Rails is a bad choice. Technical debt is real, and you need to decide what debt you’re willing to put up with.
00:26:54.360 At GitHub, we’ve decided that being behind Rails master is not a technical debt we’re willing to put up with. You can slowly work on technical debt and upgrade your Rails application to reach a better place.
00:27:04.320 There are a few things you should consider when upgrading and mistakes to avoid to prevent a seven-year upgrade like we did at GitHub.
00:27:14.590 The most important step is to build a team. Upgrades are difficult, and it's helpful to have a team that can support one another, bounce ideas off each other, and ensure that the momentum keeps up.
00:27:37.850 If you have a one-person upgrade team, and that person leaves your company, your upgrade will be stalled or possibly stopped altogether. Create redundancy and support for such a vital project.
00:27:54.420 If you have a small team and need to upgrade, consider hiring a contractor to help you get out of the weeds. It’s going to be expensive, but it’s cheaper than not upgrading.
00:28:10.540 They can also help you institute best practices to ensure that you don’t fall behind in the future. Another thing that makes upgrades easier is taking time to plan your upgrade.
00:28:28.320 Your team should ask themselves if they want to upgrade from 3 to 4, or from 4 to 5, or do they want to go straight from 3 to 5? You may want to incrementally upgrade to see all the deprecation warnings, or you might prefer to just rip the band-aid off.
00:28:54.390 Our upgrade was long enough that it made sense to work incrementally so we had a sense of accomplishment and could stay motivated. This same process may not make sense for your team.
00:29:15.110 You should also consider whether you want to use a long-running branch or get your application booting in multiple Rails versions. It might not be feasible for you to do either, such as booting the application or setting up extra CI builds.
00:29:35.890 These are things to consider before starting the upgrade, because upfront investment may save you time later. You can facilitate your Upgrade by fixing deprecation warnings early instead of ignoring them.
00:29:54.460 Some deprecations are related to major changes, and ignoring them can block your application from booting until fixed. One example of this is the deprecated alias method chain change in Rails 5.0.
00:30:12.190 If you ignore it, it can stall your upgrade, as only one person will be able to work on it until you address the actual test failures. Once you upgrade to the most recent version, make a plan for future upgrades.
00:30:30.520 How often will your team upgrade in the future? Are you willing to test new releases of Rails in the beta or release candidate phases? This will make future upgrades easier because you can provide feedback to the Rails team.
00:30:52.000 If you can’t run Rails master in production, you can invest in dual booting CI to test Rails 5.2 and 6.0 simultaneously, like we do at GitHub. If you invest in upgrading, it makes sense to also invest in future upgrade tooling.
00:31:11.340 Now that we've looked at considerations to make when upgrading, let's look at things you should not do because you will regret them. There are many choices you may make in your application that will complicate upgrades.
00:31:31.670 One thing you’re likely to regret is forking Rails. Avoid this. The decision to fork Rails and deviate from upstream was the single most expensive choice we made regarding our application at GitHub.
00:31:51.150 This had a compounding effect on the state of the codebase, which was the reason our upgrade from 2.0 to 5.0 took seven years. If you absolutely must fork Rails, try to at least track upstream as closely as possible.
00:32:15.510 Use the fork only to backport bug fixes or features you need. If you add features that you never intend to upstream to Rails, your fork will deviate from upstream, and upgrading will become more challenging.
00:32:35.240 Another thing that you may regret down the road is falling behind Rails upgrades until the Rails team no longer supports your version. If you need to stay on an unsupported version of Rails, you should use Rails long-term support.
00:32:55.210 At least long-term support will maintain the fork for you and ensure security patches remain accurate. If you fall behind Rails upgrades and end up writing your own patches, you might do it wrong and create an unsecured endpoint.
00:33:12.520 In general, the best way to apply a security patch is to rely on Rails upstream. Ensuring your application tracks the most recent version of Rails can help reduce surprises when applying security patches.
00:33:24.900 If you’re using old unsupported gems, your upgrade will be more difficult because you will be required to upgrade those gems before you can upgrade Rails. Ensure that you upgrade your dependencies often to align with Rails requirements.
00:33:39.180 This will also prevent you from relying on a gem that gets abandoned by its maintainer because we at the Rails team aren’t going to keep recommending or adding unsupported gems.
00:33:54.580 You may also regret using private Rails APIs. Private APIs are code that’s purposely undocumented or under the private namespace. We reserve the right to change these APIs without deprecation.
00:34:08.720 If your application relies on the behavior of these APIs, they can be removed or deprecated without warning. It’s always best to use public documented methods in Rails.
00:34:22.910 All of these choices can compound the cost of your upgrade; it’s easy to see how these decisions contribute to accumulating debt in our applications.
00:34:36.080 I hope that by now you’re feeling more confident that you can tackle an upgrade. I know it’s going to be hard; you might cry, you’ll definitely get angry, and you may even curse past engineers who no longer work at your company.
00:34:50.890 I definitely did, and I apologize to all of those engineers. But I want you to know that you can do it; I have faith in you.
00:35:05.670 You might think, 'Well Eileen, maybe it wasn’t easy for you because you are on the Rails core team and work at GitHub, but I just don’t have the talent to pull off this upgrade.'
00:35:19.860 Let me tell you something that I have shared with many, and they have seemed surprised by it: before the Rails 3.2 to 5.0 upgrade at GitHub, I had never accomplished a major multi-version upgrade and deployed it to production.
00:35:33.270 If I can do it, you can do it! I’m not smarter than you, and I’m not better than you. Upgrading isn’t going to be easy.
00:35:46.590 But especially if you carry the cumulative costs we've discussed, it’s essential while you work on your upgrade to remember a few key things.
00:36:07.690 Firstly, you don’t have to solve all of your technical problems tomorrow. You can pay down your debt incrementally. Start with that one class that uses a private Rails API, remove it or document your monkey patches, and identify which Rails dependencies are out of date.
00:36:23.320 Rails upgrades are not a sprint; they’re a marathon. If you and your team incrementally pay down the debt you’ve incurred, the upgrade will eventually be possible and completed.
00:36:38.070 Also, remember that you’re not alone. Many before you have navigated an upgrade, and many will do it after you. Find other companies that are upgrading alongside you and lean on each other for support.
00:36:52.540 When I did the upgrade at GitHub, I knew that Shopify had just finished their Rails upgrade, and I felt comfortable asking them for advice and support.
00:37:07.130 Lastly, remember that the payoff is worth it. Upgrades take time and are difficult, but being afraid of upgrading won’t make it go away. When you upgrade your application, it will be in a better state.
00:37:23.040 In addition to better security, easier hiring, and more manageable dependencies, doing the hard work of upgrading will provide you with improved APIs.
00:37:40.020 Major version upgrades allow the Rails team to rethink how previous features were designed and if we can improve them in the next version. In Rails 6, we improved APIs for handling multiple databases.
00:37:56.630 Before Rails 6, managing multiple databases in a Rails application was very painful; you had to write a ton of code yourself. But in Rails 6, we added new APIs for establishing and handling connections, along with improved Active Record database configurations.
00:38:10.150 Without upgrading, you won't have access to these improvements. Upgrading to new versions of Rails also enhances security.
00:38:21.430 Besides making security upgrades easier, each Rails version adds new features to protect your application from bad actors. In Rails 5, we introduced perform CSRF tokens, and Rails 5.2 added encrypted secrets.
00:38:39.060 Rails 6 will ship with improved security features around potentially dangerous URL methods. These features help keep your application secure.
00:38:49.620 And since these are security features and not vulnerability patches, the only way to get them is to upgrade your application. Although Rails 3.0 was plagued with performance issues, newer versions have focused on better performance.
00:39:03.960 The Rails team is always looking for ways to make Rails faster in all environments. Rails 6 is shipping with fixed memory leaks for view loading in development and faster Active Support notifications.
00:39:19.230 Upgrading Rails also grants you access to new libraries. Rails 6 is shipping with brand new frameworks like Action Text and Action Mailbox.
00:39:36.630 By upgrading, you can rely on fantastic new features in Rails without having to build your own infrastructure tooling into your application. If your application needs to send mail, it shouldn’t need to implement how to send mail; Rails should take care of that for you.
00:39:53.420 Upgrading Rails helps maintain a clear separation between where your Rails application concludes and your custom application begins.
00:40:09.050 Lastly, upgrading your application gives you a chance to contribute upstream. It’s challenging to fix bugs, add features, and influence the future of Rails from an old unsupported version.
00:40:25.900 While it’s not a requirement to contribute if you’re on a new version, it definitely opens doors that are otherwise closed. As DHH said in 2004 and has repeated many times since, frameworks are extracted.
00:40:43.750 If those needs are stuck back in Rails 2.3, it’s hard to make a case for extraction. GitHub needs all of these reasons to upgrade.
00:40:59.050 This is the most important reason that kept me going; it was why I spent a year and a half on the Rails upgrade—so that GitHub could influence the future of Rails.
00:41:19.430 This is the biggest and most important reason to upgrade: by absorbing features, fixing bugs, and supporting Rails' future, we support our own future as well.
00:41:34.920 When I look back at the 3.2 to 5.2 upgrade, the thought of being on a modern version of Rails and actively contributing felt like an unachievable fairy tale.
00:41:46.140 We were so far behind that I often wasn’t sure we’d finish it, at least not while maintaining my sanity.
00:42:02.510 But now, regularly contributing to Rails and supporting the future of Rails is GitHub's present and future state. Since upgrading, GitHub engineers have submitted over 75 pull requests that improve performance, fix bugs, and add major functionality.
00:42:21.470 Before we upgraded, we were often forced to add a monkey patch or find overly complex workarounds for bugs. Using Rails 5.2 has allowed us to not only contribute upstream but to make choices that improve our application instead of hinder it.
00:42:42.760 All of you benefit from those changes as well. In addition to bug fixes and performance improvements, we've extracted major functionality from GitHub.
00:43:00.960 We don’t have time to discuss technical details, but we've extracted our handling for multiple databases in Rails 6. We used our knowledge and experience in database handling to create an easy-to-use, robust new API.
00:43:15.560 By upgrading, we’re reducing complexity in our application. Our goal is to never fall behind again. We’re investing in our application and Rails.
00:43:32.970 Every week, we bump our Rails gem and run all of GitHub's tests against that new version. This allows us to find regressions and fixes before we release that version.
00:43:46.720 It also lets us test GitHub code in Rails 5.2 and 6.0 simultaneously. Because we did the difficult work of upgrading major versions, we hope we'll never fall behind.
00:44:01.400 Upgrades won't be easy, but doing continuous upgrades and our contributions to Rails show that for the first time in GitHub's history we’re not just using Rails.
00:44:19.800 We are pioneering the future of Rails. We’re extracting code from GitHub, building new features into Rails that will help you scale your applications, and giving back to open source.
00:44:37.230 It makes good sense for us to do this. Not only do we give back to the community, but it also helps keep our application focused on our product.
00:44:54.710 We can reduce complexity while improving resilience, all whilst contributing to the future of Rails. At GitHub, we need to do this for our application, but we also have a responsibility to support Rails.
00:45:10.050 We owe part of our success to the Rails framework, and we have the influence, expertise, and application to push Rails forward.
00:45:30.250 Upgrading Rails was a huge investment; it wasn’t cheap, but it was absolutely worth it. Upgrading Rails opens up a ton of opportunities for the future, and we have a bright path ahead.
00:45:50.600 We’re building features faster, we’re more confident our code base is stable, and we’re improving the scalability of Rails. All while giving back to the open-source community.
00:46:10.080 At a minimum, by upgrading, we transitioned from being crushed by Rails and the decisions we made to building up our application, building up Rails, and focusing on strengthening our community.
00:46:27.650 Upgrading Rails has given us the freedom and flexibility that we didn’t have before, enabling our engineers to build more and build better.
00:46:40.740 In 2007, GitHub was born, and eleven years later, we are finally at a position where we have caught up with Rails master. It took seven years from when the 3.0 upgrade began to complete the 5.2 upgrade.
00:46:59.640 The future is bright, and I can't wait to see how the next ten years allow us to extract from GitHub, build in Rails, and watch the community thrive.
00:47:13.340 At GitHub, we will continue to contribute to and invest in the future of Rails and our community—because we have to, because we want to, and because we need to.
00:47:36.029 We'll keep investing in the future because GitHub and Rails are in this together for the long haul, and I hope you are too. Thank you!
Explore all talks recorded at Balkan Ruby 2019
+4