Rails Upgrades

Summarized using AI

Keynote

Aaron Patterson • April 12, 2021 • online

In the keynote presentation at RailsConf 2021, Aaron Patterson, also known as Tender Love, addressed the audience with a mix of humor and technical insight, covering various developments in Ruby on Rails. The theme centered around improvements in the Rails framework, his experiences during the pandemic, and ongoing enhancements in Ruby's performance.

Key Points Discussed:
- Personal Journey and Humor: Aaron opened the presentation by joking about the challenges of remote conferencing, sharing anecdotes about incorporating cats into meetings and his newfound hobbies during the pandemic, including baking bread and making cheese.

  • Contributions to Ruby on Rails: As a core member of both the Ruby and Rails teams, he highlighted significant ongoing projects, including a Just-In-Time (JIT) compilation for Ruby and improvements to Rails, particularly in speed and functionality.

  • Perceptions of Stability in Rails: Aaron addressed a common misconception regarding Rails' stability, arguing that upgrading difficulty often distorts perceptions of instability. He emphasized the importance of incremental upgrades and ongoing feedback to ensure smoother transitions.

  • Performance Considerations: He suggested that while many view web apps as primarily I/O-bound, there is substantial unnoticed CPU usage in Rails apps that can impact performance. He encouraged developers to profile their apps and optimize code instead of solely relying on rewriting them in different languages for performance gains.

  • New Features in Rails 7: Patterson introduced exciting new features slated for Rails 7, such as asynchronous queries allowing deferred loading of data and improved preload capabilities that reduce database queries.

  • Technical Improvements: He discussed the optimization of class variable access times and the reduction of redundant processes within Rails to improve overall application performance. Specifically, he shared advancements made with inline caching techniques, significantly speeding up class variable reads.

Examples:
- Aaron provided a humorous advertisement demo for an 'Analog Terminal Bell', demonstrating the quirky innovations developed by his startup during the pandemic.
- He humorously explored the historical context of the carriage return, connecting it to coding practices today.

Conclusions:
- Aaron's nuanced discussion highlighted that advancements in Ruby on Rails are driven by community involvement and responsiveness to developer needs.
- He encouraged developers to engage with performance improvements actively, asserting that all contributions, no matter how small, can foster significant enhancements in the framework. He closed by inviting developers to continue collaborating in the growth of Ruby and Rails, asserting their capabilities to learn and develop the framework further.

Keynote
Aaron Patterson • April 12, 2021 • online

RailsConf 2021

00:00:04.860 I didn't need to be somewhere today. Oh, that's right! I need to get to RailsConf; I better hurry!
00:00:34.860 Hi, Evie! I gotta get to RailsConf.
00:00:45.120 Hi everybody! Welcome to RailsConf! All right, I just need to get my jacket off here and put on a microphone.
00:01:12.380 I'm so happy to welcome you to the conference that should have been an email.
00:01:29.759 My name is Aaron Patterson, also known as Tender Love on the internet. I've changed my icons, so I look like this now. This is my icon on the internet.
00:01:37.619 I work for a company called Shopify, where I am a full-time Ruby and Rails contributor.
00:01:43.680 Shopify invests in the technologies it uses, and we utilize a ton of Ruby and Rails. My particular team works on improvements to Ruby and Rails, focusing on speed improvements and new features.
00:01:55.259 We are currently working on a JIT implementation for Ruby as well as improvements to Rails, like deferred queries, which I will be discussing later in the presentation.
00:02:01.020 As Megan mentioned, I'm on the Ruby core team and also the Rails core team. And as a good representative of the Rails core team, I need to clarify that this is not, in fact, an octopus leg.
00:02:06.979 It is a railway track! Now that you've seen the octopus leg, I'm sorry, you can't unsee it. It's great to be here on March 422 of the great year of 2020. But seriously, I really hope to be seeing all of you in person this year.
00:02:40.920 Initially, when I found out we were doing this conference online again, I thought I was going to be recording it. I got an email from the organizers asking when my recording would be ready, but I was on the mailing list with all the other speakers. I thought, okay, I'll have the recording ready, and they told me, "No, you're doing it live!" So, I have to do it live.
00:03:03.900 I find it quite challenging to give a presentation without a live audience, so I decided to bring a few guests. I have my cat, my other cat, and also some mystery guests with me.
00:03:28.260 One interesting thing about having the conference online is that I can take selfies with all of the keynote presenters. I got a selfie with DHH, which was really great. I also got a selfie with Brian Cantrell, and I was really excited during his presentation when he said, "But at what cost?" So, I got a selfie with Brian, but at what cost?
00:03:44.280 I was also able to get a selfie with myself, which was a special treat! I had to do that to prevent any potential rips in the fabric of time. You might be wondering how I was able to take a selfie with myself during a live presentation. I assure you, this is definitely a live recording.
00:04:30.240 One other thing I appreciate about online presentations is I get to enjoy all the talks that are pre-recorded and released, allowing me to watch them at 2x speed, which makes me very happy. I know I'm a 2X developer, but I've learned that I am definitely not a Forex developer; I can't do that!
00:05:10.800 Speaking of the pandemic, I know that it has changed everyone's lives, including mine. We're all doing a lot more working from home these days, and this can lead to some awkward situations. Even for me; I was working from home before the pandemic, but now it's impacted my life.
00:05:42.900 Awkward stuff can happen, interfering with your life in ways you didn't expect. One thing you have to do is to ensure you have a good Zoom background. I have made a collection of Zoom backgrounds. Most people like to use nature or abstract patterns, but I prefer to keep mine real. I use a Zoom background of my own office.
00:06:20.400 For example, this is what it looks like when I'm in chat. You can see that I have a nice person assisting me with my chair. I also bought a green screen and a lighting setup, which allows me to create nice videos and show interesting content.
00:07:05.100 I've also experimented with using a selfie stick, which I have only used once, and I'm sure all of you have seen the fruits of my labor. The other thing I've been doing is baking a lot of bread. I learned how to bake bread and can show you a photo of some I made.
00:07:41.370 Here's the crumb of the bread! I think I did a pretty good job of it. Of course, I need something to go along with the bread, so I also began making cheese. This is a cheddar I made; I've also been crafting Camembert, which is delicious.
00:08:28.740 I want to share a little about my cheese-making process. I age the cheese in my basement, and here is a drawing of my basement from above. I have two cheese aging fridges situated near my central air unit. I need to flip the Camembert once a day. When I do that, the smell wafts out and makes its way throughout the house. Some people, namely me, enjoy this, while others living here are not so excited about this feature.
00:09:06.899 The other thing that’s quite cool about the Camembert is that if you cut a wedge out of it, it looks like a pie chart. Interestingly, in France, people use 'Camembert' to refer to pie charts. I personally love Camembert more than pie, so I wish we would call them Camembert charts too!
00:09:43.680 Additionally, I've been getting more involved with electronics and improving my skills. I've built a Wi-Fi-based temperature, humidity, and air quality sensor. Here's the dashboard I use to track the air quality in my home, which I called Tender Home.
00:10:25.680 By the way, I should mention that this sensor does not detect cheese smell! Now, on another note, I bought this device here, which is a MIDI controller. The interesting thing about it is that it's much easier for me to give a presentation in front of a live audience.
00:10:54.750 So, I set this up to do something. Whenever I make a really good joke, I can hit this button, and it plays sound effects, and the room fills with applause, so yes! In addition to cheese smells throughout the house, I've been testing it, and I can tell you, everyone here is super excited about this.
00:11:48.880 Now, the other thing I want to mention is that last year I read an article by Paul Graham stating that everyone gets rich by making startups. I took this to heart because I want to be rich as well, so I decided I have to create a startup!
00:12:01.380 I established a startup that I call Tender Lab, and I'd like to present to you some products that we've been working on. The first product, which we developed last year, is called the Analog Terminal Bell. Let me play the ad for you now.
00:12:35.900 [Plays Ad] "Has this ever happened to you? Trying to run 'git' in the wrong directory? If only you'd heard the terminal bell! With the Analog Terminal Bell, you'll never miss a terminal bell notification again! The Analog Terminal Bell rings anytime a bell character is displayed on your terminal. Simply plug it into a USB port, enable it in your terminal settings, and it works with your shell, Vim, and even Dev View Random. Thanks to the Analog Terminal Bell, you'll never miss a terminal bell notification again! Go to analogterminalbell.com today to get your very own Analog Terminal Bell!" Please note that the Analog Terminal Bell is not actually for sale and requires a custom build. Other restrictions may apply; see the website for details.
00:13:09.860 That was the Analog Terminal Bell! Now, I want to share our next big product, which our very talented team developed last year. I want to introduce you to the Analog Carriage Return. Many of you have likely encountered the very frustrating situation when you are typing away, and all of a sudden your code exceeds the 80th column. You might be thinking, "How did this happen?" Now you have to go back and reformat your code to fit within the required limits—to avoid this wasted time, we designed this product.
00:14:32.000 Brian Cantrell spoke about the history of computing, focusing specifically on Moore's Law, so I thought it would be valuable to discuss the history of the Carriage Return.
00:14:36.480 We've often seen the terms 'Carriage Return' and 'New Line' together. This terminology traces back to the 1880s in the Wild West. In those days, people had to ride in horse-drawn carriages. Not everyone could afford their own carriage, so ride sharing was very common. A horse-drawn carriage would come pick people up, take them to their destinations, and then return to the original stop.
00:15:01.139 When the carriage returned to the original stop, people would line up again, leading to the concept of a carriage return and a new line. So how does this relate to computing? In those days, calculations were done by hand using pieces of wood with graphite embedded inside for writing.
00:15:19.120 I have one of these instruments, and I'm going to give you a demonstration today. This is an example of a calculation being done. Interestingly, these tools weren't only used for math problems but also to keep track of people waiting to ride on the carriage. You'll notice a carriage return followed by a new line, demonstrating how seamlessly computing has evolved.
00:15:46.200 Now, ever since Apple invented computers, we have been able to move these calculations into the digital realm. Let me return to my presentation; I might have strayed a little off topic, but if you've seen any of my talks in the past, you might notice that I usually follow a certain format. I typically do an introduction, make a few good jokes, present a technical segment, and conclude.
00:16:15.300 This year I have 90 minutes to present, and I've been grappling with how to fill that time. So I decided to introduce something new—a ranting section. Given the amount of time, I thought it might be appropriate to voice some complaints or grievances.
00:16:29.580 The first topic I want to address is stability. I've seen some tweets on Twitter from people claiming Rails is unstable. I tend to view this as a meme to some extent. Is Rails truly unstable? I don’t believe that it is. What I think people are trying to convey is that they find the upgrade process challenging.
00:16:40.560 In actuality, I don’t think Rails is crashing randomly or shaking beneath our feet. The sentiment regarding Rails’ instability bothers me for a few reasons. Firstly, it's somewhat personal—our team works very hard to avoid breaking things. We do not want to break your application; our goal is to make sure everything operates smoothly.
00:17:18.180 Another issue is the abundance of gems in your Gemfile. If we look at the responsibilities assigned to the gems in your application—like Nokogiri parsing XML or Stack Prof profiling—then think about the wide range of things Rails does, handling requests, rendering templates, conducting database queries, etc. The API surface area of Rails is quite large.
00:17:52.800 If we calculate the potential bugs or issues in context with the extensive API surface area, I believe we would find that Rails is as stable as or more stable than many of the gems in your application.
00:18:25.980 I went through and calculated these ratios, and for Rails, it is approximately 0.001, while for other gems, it is around 0.01. I might not be a mathematician, but these figures imply that Rails is actually ten times more stable than other gems.
00:19:07.020 I think the underlying problem arises during significant upgrades to Rails. When we upgrade, we often upgrade a multitude of things simultaneously, not just one specific area. While we strive to maintain a low breakage rate, the likelihood of encountering a bug remains relatively high.
00:19:22.320 If your company has resources similar to what we have at Shopify and what GitHub does, you can track Rails main with your application, allowing you to upgrade incrementally over time. It might seem a bit daunting, but we on the Rails core team ensure that the main branch remains stable for production.
00:19:53.580 For those companies that do not have such resources, I highly encourage keeping up with point releases. We do everything we can to ensure these are stable and easy to upgrade.
00:20:02.460 Once you've completed the current point release, you can move on to the next major release. It may not be perfect, but it is a strategy. If you hit any bumps along the way while upgrading, please let us know about those incompatibilities. If your application breaks, inform us while still exploring fixes, as we welcome patches to mitigate backward compatibility.
00:20:35.760 We genuinely strive to avoid breaking anything, and if it does happen, it likely is unintentional. The main point is we work diligently not to disrupt your workflow, so if you can run your applications against the main branch, please do so!
00:21:02.520 The next discussion point is regarding the notion of web applications being I/O bound. Many people say web apps don’t require concern about the speed of the programming language since the bulk of work involves database queries, reading, writing to sockets, and file operations.
00:21:39.780 However, this consideration leaves me uneasy. I’ve heard stories where people rewrote applications in a different language and experienced increased speed. The challenge is that I/O is typically the same speed across programming languages. For instance, reading a file in Ruby isn’t necessarily slower than it would be in Go.
00:22:06.180 This raises several questions. There's either a discrepancy in comparisons that we’re making—or the I/O isn’t genuinely the bottleneck. My hypothesis is that Rails apps spend more CPU time than we might realize or want.
00:22:32.260 Ideally, we want to assert that web apps are I/O bound. In reality, the processing resembles a situation where we are spending some time in I/O while still spending significant time on the CPU. As time progresses, we get blocked, and do not get to conduct those I/O-bound operations because we are waiting for CPU processing.
00:23:10.320 It would be ideal to have a setup where we can run I/O and CPU operations in parallel rather than getting blocked on the I/O calls. I’ll revisit this topic soon, but the key takeaway here is the importance of enhancing Ruby and Rails in the domain of CPU time.
00:23:36.380 On a side note, I want to clarify that Ruby does have real threads. A common question I get is whether Ruby is capable of performing operations concurrently. It truly can! For instance, if a file takes 10 seconds to read, executing this task 100 times across different threads would just take 10 seconds.
00:24:14.220 Puma and Sidekiq leverage this fact, as both are designed to maximize I/O operations independently in parallel, yielding lower overhead. However, one caveat is that in MRI, CPU-bound operations cannot be conducted in parallel.
00:24:51.840 If your application, however, is found to be CPU-bound, it might be worth exploring JRuby or Truffle Ruby. If web applications are indeed I/O bound, then rewriting applications should not have made a difference!
00:25:21.920 This leads me to the next point, which pertains to application rewrites. Frequently, I hear people say they rewrote their applications in Fortran or another language, and now they’re faster. While that's fair, I do not think we can draw definite conclusions from such claims.
00:25:54.580 The core problem lies in the learning experiences derived from mistakes we make along the way. It seems ironic to say it, but we learn from mistakes! A rewrite will never be a like-for-like comparison with the original application.
00:26:30.780 The new application often is impacted by insights gained during the first iteration. All we can say is that we rewrote the application, and now it’s faster; that doesn’t serve as an honest appraisal of the prior code. In the ensuing weeks, post-rewrite, we will likely uncover missing business requirements or new demands, leading to slower systems.
00:27:06.220 When we reinstall macOS, everything feels great and fast initially, but as we add Slack, Chrome, and other apps necessary for our tasks, we eventually see a drop in performance. One might argue that despite this, 'at least it seems faster than before.' A fine statement—but the truth remains that we cannot genuinely ascertain speed improvements using a qualitative measure.
00:27:42.460 Ultimately, the question you must ask yourself is whether that speed enhancement is worth the happiness that comes with using a familiar programming language and framework that boosts productivity. I strongly advocate for profiling; we should focus on learning to optimize our applications using existing languages such as Ruby.
00:28:20.320 Doing performance work certainly is a harder sell than layering development for features. It requires a different skill set, and lacks the shine that feature development often provides. But I assure you, toward the end, I will address how performance work is accessible to all developers.
00:29:02.640 This code exists because humans designed and created it—and that means you, too, can learn and understand it! We must also endeavor to make performance work more appealing to others. How can we convey our performance work in a story-like format? What evidence did we gather? How did we test and what impact did it yield?
00:29:48.440 It’s also worth noting that performance work can coincide with improving legacy code systems as well. If we refactor these systems, we may create a more efficient development process for feature teams.
00:30:24.779 Now let’s transition to Rails itself. I usually do not have any thrilling announcements at Rails, but I am excited to share a few new features coming to Rails 7. The first is Async Queries. You can check out the pull requests regarding this feature. Earlier, I mentioned making our apps I/O bound, and this feature is instrumental in addressing that.
00:30:58.360 It was originally developed by Jean Boussier, who is part of my team at Shopify. This feature allows us to defer queries. For example, when a query is added, we can say 'load async' at the end, and the query is placed in a pool to be executed in the background. This means that when we later access the data, it's either already loaded or will wait until the query has executed. This process is totally transparent, letting us express, 'I know I’m going to need this data eventually; please load it in the background, and I will use it once it’s available.' The second feature I want to introduce is Smart Preloader.
00:31:53.900 This has been written by Jay Hawthorne and Diana She, and it is one of my favorite features because it seamlessly works without requiring any action on your part. This feature directly impacts the preload function. For instance, if we look at an author who has many posts and also has favorite authors with their own posts, preloading them in two locations would usually generate two queries against the posts table. Thanks to smart preloading, the system recognizes that two queries for the same table are being requested and streamlines it to do just one query!
00:32:51.430 Now, let’s talk about Faster Constantize. This feature, implemented by John Lucier, speeds up the constantizing process. The operation itself has become five times faster. The history of this performance improvement is significant. Back in 2012, we discussed the need for a more efficient constant lookup mechanism within Ruby itself. However, a previous feature limited our ability to use it in Rails, which was embarrassing for me.
00:33:41.840 Next, I introduced a patch adding dynamic lookup capabilities in Ruby 2.0. Unfortunately, this also didn’t simplify the process for Rails, as we couldn’t intercept when constants were required. Fast-forward to 2019 when implementation shortcuts were found, and we capitalized on this to provide more efficient reloading and constant miss behavior in Rails. To highlight the significance of this development, when Ruby 2.7 revolutionized our approach to handling namespaces effectively, we could finally integrate a simpler structure, ultimately resulting in a marked improvement that took nearly nine years to manifest.
00:35:48.570 Next, I want to address the concern about the 'magic' within Rails. Many have noted that there's too much abstraction in the framework. I'm happy to announce that in Rails 7, we have actually removed much of this magic. I feel that this is a clapping moment—no more magic!
00:36:20.590 In summary, I wanted to take a more introspective approach this year, reviewing some of the underlying Rails code that sometimes leads to laughs. I explored oddities and perplexities within the code base, playing with heuristics to identify certain patterns.
00:37:11.220 For instance, I sought to evaluate the longest class names present in Rails, which produced interesting results. Finding long class names can provide insight into complexities that have been included in the framework's design. Several names were amusing to explore, and I also evaluated the longest methods, or rather 'how long is too long' when defining methods?
00:37:58.180 I embarked on analyzing metaprogramming instances, distinguishing between methods that had been dynamically defined through techniques such as Define Method, and those that were created using normal methods where programmers typed out lengthy commands. This exploration yields more interesting insights into how we work internally within Rails.
00:38:29.080 I then examined discrepancies pertaining to class variables, particularly how instances of class variables can often lead to unexpected results between classes, making it challenging to manage code effectively. Observing how changes in one class can potentially impact sibling classes often creates confusing outcomes in object-oriented programming environments.
00:39:09.000 Finally, I discussed class variable inline caches—our recent work on enhancing performance to accommodate effective reading and writing across Rails classes by creating inline caches to optimize repeated access patterns. This advancement results in remarkable performance gains while removing complications from our previous methodologies. Seeing effective improvements across our benchmarks is cause for excitement!
00:40:01.300 As I wrap up today, remember that we shared jokes, presented compelling views on how to choose a framework or language that supports you in your work, and discovered intriguing new Rails features. It's about embracing stability and dynamic improvement, allowing you as developers to engage meaningfully in your development journeys.
00:40:53.520 You should know that every piece of code in Rails was constructed by people, making it accessible for you to learn, work with, and contribute back into the open-source ecosystem too! I want to extend my gratitude to those developers who have molded this language and community, especially the team members from Shopify who support my efforts, and I encourage everyone on board to work collaboratively and forge genius implementations!
Explore all talks recorded at RailsConf 2021
+65