Rails 8 was released on November 7, 2024, and it comes with many changes that promise to help developers build faster and better applications using the framework.
Plenty of interesting developments are included in Rails 8, and they're more or less fueled with 37 Signals decision to move out of the cloud.
In this article, we will explore what's new with Rails 8 and why this is an exciting release for Rails developers all around the world.
Let's start by understanding the motivation behind Rails 8. If you're in a hurry, feel free to skip to the TL;DR
The motivation
As you may know, even though Rails development depends upon a large group of people that contribute to the project, its advancements are mostly dependent on extractions done from the needs and philosophies 37 Signals have.
Recent developments like Hotwire or import maps came from solving the needs they had when building Hey, their email service.
And Rails 8 is no exception: back in 2022, 37 Signals announced their decision to migrate out of the cloud to save money and simplify their infrastructure.
In September 2023, they announced ONCE, their new approach to selling software that promises to free users from the subscription madness by exchanging code and deployment instructions for a one-time fee: no more recurring payments or per-usage pricing.
What they've learned from their cloud exit and the need to simplify deployments so end-users can install and run Rails apps without much trouble is what ended up becoming Rails 8.
That's why the tagline for this release is “No PaaS Required” and it fuels the empowerment of developers worldwide that may have been too respectful of getting their hands dirty with servers and dev-ops to help them follow the path that 37 Signals paved with their cloud exit.
So let's learn what changes were introduced by talking about simplified deployments first:
Kamal and a new deployment era
Kamal, formerly known as MRSK, is a web-application deployment tool centered around a simplified Docker workflow.
With Kamal, you can manage your application's infrastructure and deploy it to a cloud VM or bare server without complications.
Actually, Kamal requires a fresh server with SSH access from the host, and it can deploy a Rails 8 application to it with the corresponding accessories—AKA: non-app long-running services—to a single machine without the need to immerse yourself into configuration hell or profound Docker knowledge.
All you need is a Dockerfile and some configuration and, luckily, Rails 8 comes with an optimized Dockerfile
and a deploy.yml
configuration file that greatly simplifies the deployment process.
Kamal 2, which is the latest version of the framework, includes a couple of improvements over the previous version:
- Thrusther: a proxy that sits in front of our application and replaces the need to have a web server like Nginx. It also provides asset caching, compression and
X-Sendfile
acceleration. - Kamal Proxy: a proxy that works internally within our containers to provide zero-downtime deployments, automated SSL certificates and support to deploy multiple applications within a single server. Kamal proxy replaces Traefik, the previously used solution.
- Aliases: they are shortcuts to easily access a Rails console, a shell, logs or database console, etc.
Even though Rails 8 comes with Kamal by default, it's not really tied to Rails or any other framework in particular, we can use it to deploy anything from a small microservice to a complete infrastructure that handles varying levels of usage.
The Solid Stack
With 37S migration out of the cloud, and on the same page as their “No Build” stance, Rails 8 comes packed with a set of tools to help developers get rid of many dependencies that were thought to be vital.
Namely, the Solid Stack allows us to remove dependencies like MySQL or Postgres as well as Redis in favor of the portable database engine SQLite using three adapters: Solid Queue, Solid Cable and Solid Cache.
Each one of them replaces external dependencies and the need to use Redis or other in-memory stores to handle tasks that were deemed as inadequate if done with writing and reading from disk.
Plus, SQLite being portable means we can deploy one or more applications to a single box without the need to handle a self-hosted or managed database service.
Let's explore the individual components of the stack starting with Solid Queue:
Solid Queue
Maybe the most convenient adapter of the stack: Solid Queue not only replaces Redis as the storage adapter, but it also replaces dependencies like Sidekiq and Resque which add up to the maintenance overhead of our application.
Besides the job enqueuing and processing, it supports: delayed jobs, recurring jobs, concurrency control, pausing queues, numeric priorities per job, priorities by queue order and bulk enqueueing.
The best part is that we can adopt Solid Queue incrementally by setting the queue_adapter
at the class level.
Solid Queue has been used in production by 37S to support an intense workload, which means that it's production ready and apt for the use cases of the immense majority of Rails applications.
Solid Cable
It's a database-backed Action Cable adapter that acts as a pub-sub server, which means it can relay messages between the application and connected clients.
By default, Solid Cable uses SQLite, but it can also use any Rails compatible database (MySQL, Postgres) given that we configure it using the cable
namespace in our database.yml
config file.
Solid Cable uses fast polling to achieve similar performance to their Redis equivalent, and it gets quite close. However, even if we don't achieve the same levels of performance, the fact that we can deploy Rails without worrying about accessories can make it worthwhile for plenty of applications.
Solid Cache
Solid Cable is a cache store that's backed by a database instead of an in-memory storage service like Redis or Memcached.
Besides getting rid of an accessory service, it provides the possibility of storing much larger caches at a fraction of the cost because of the pricing difference between disk and memory capacity.
This allows for larger cache storage, the ability to encrypt them and also add an explicit retention limit—because we can keep more than a couple of days of storage—to comply with privacy requirements.
According to this post, by 37 Signals cache reads are 40% slower than before, but their cache size is 6 times larger and their 95 percentile request duration fell from 375ms to 225ms because of the intensive use of fragment caching.
Like every other Solid adapter, Solid Cache is a convenient alternative to simplify deployments, and even though it's predictably slower than their in-memory alternatives, it's probably good enough for most of the applications built with the framework, especially if you don't know for a fact that caching performance is an issue.
Out of the box authentication
A “native” Rails authentication solution has been a very requested feature for a long time.
Developers complained about Devise—the most popular Rails auth library—because of the large number of features it packs and the complexity required to make changes if the auth use case deviated from the golden path.
Rails 8 comes with out-of-the box authentication via a generator that provides an auth flow including session tracking and password resets that can be installed using the bin/rails generate authentication
command which creates Session
and User
models that allow us to handle authentication while also tracking sessions.
This approach reduces the behind-the-scenes “magic” that authentication usually represents and gives us the ability to customize the behavior to our liking.
Because of its simplicity, some developers might consider it incomplete, especially for complex authentication flows but, it also pushes us to control authentication instead of delegating it to obscure third-parties without understanding what's going on behind the scenes.
Even though complex authentication flows may require extra work, having an opinionated off-the-shelf auth alternative is probably a step in the right direction, even if the current status of the solution doesn't please every developer out there.
Propshaft
Rails 8 replaces Sprockets with Propshaft, which provides two things: a load path for assets and a mechanism to stamp them with a digest to avoid a controlled expiration of the assets.
This simplification comes from the fact that, nowadays, CSS and JavaScript support advanced features that were supplemented by external dependencies like the ruby-sass
gems back in the day.
Most of the features Sprockets provided are no longer needed or replaced by other solutions, so Propshaft sticks to a basic set of features that make it a simpler solution to a problem that's increasingly solved by the browser and its newer specifications.
TL;DR
Rails 8 is all about developer empowerment:
- To deploy our apps to a bare server and lose the fear of managing our infrastructure.
- To get rid of external dependencies to handle async work, caching, web sockets, etc.
- To take control of what happens with our application's authentication code.
New Rails apps are Kamal ready and have a fine-tuned Dockerfile
and all we need to deploy with it is a fresh Linux box and SSH access from the deployment host, which is generally our computer.
The Solid Stack: Solid Queue, Solid Cable and Solid Cache is a database-backed set of adapters that allows us to get rid of in-memory storage dependencies.
Solid Queue also replaces third-party dependencies to handle async jobs like Resque, Sidekiq, etc. The good thing is that it can handle a workload that's similar to its alternatives without the need to deploy and manage an external service.
Likewise, Solid Cable replaces the need for Redis to act as the pub-sub server to relay messages to interested subscribers.
Solid Cache is the last piece of the Solid puzzle: it replaces in-memory caching with a database-backed alternative which means cache sizes can be larger, encrypted and have and incorporate a retention limit to comply with privacy requests.
Thanks to the work of Stephen Mergheim and Mike Dalessio, SQLite is now production-ready and can handle the workload required by the Solid Stack because of important developments they added to it.
Propshaft is also the new way to handle assets in Rails 8 that replaces Sprockets to simplify front-end development with Rails following the rhythm of CSS and JS developments.