Introduction
Rails 8 is less a pile of new methods than a point of view.
Its official announcement is titled No PaaS Required, and that’s the whole story. The release is built around one idea: you should be able to run a real production app on a plain server you own, without renting a queue, a cache, a WebSocket service and a deployment platform on top of it.
Most of the new features are in service of that stance. Here’s what actually ships, and why it hangs together.
The Solid trio: goodbye Redis
The most visible change is three database-backed adapters, on by default.
- Solid Queue is the Active Job backend, replacing Sidekiq, Resque or Delayed Job. It runs jobs out of your database — 37signals push tens of millions of jobs a day through it.
- Solid Cache is the cache store, replacing Redis or Memcached, and it’s built to hold far more than an in-memory store ever could.
- Solid Cable is the Action Cable adapter, carrying WebSocket pub/sub through the database instead of Redis.
The point isn’t that a database is faster than Redis. It’s that you now have one datastore to run, back up and reason about instead of four. For a huge share of apps, the Redis box was accidental complexity, and it’s gone.
Deploy it yourself: Kamal 2 and Thruster
Rails 8 ships preconfigured to deploy without a platform.
Kamal 2 takes your app, containerised, and deploys it to any Linux box you can SSH into. Its bundled Kamal Proxy replaces Traefik and gives you zero-downtime deploys and automatic SSL via Let’s Encrypt.
kamal setup # first deploy: provision + boot
kamal deploy # every deploy after that
In front of Puma sits Thruster, a small proxy that handles X-Sendfile, asset caching and compression. That’s the job nginx used to do, now built in and configured for you. Between Kamal and Thruster, “deploying Rails” no longer implies a PaaS bill or an afternoon of nginx config.
SQLite grows up
The surprising part is that all of the above runs on SQLite.
Rails 8 treats SQLite as a legitimate production database, not just a
development convenience. It sets sane defaults like WAL journaling and
IMMEDIATE transaction mode, and the Solid adapters all work on top of it. A
small-to-medium app can now run on a single file, on a single machine, with
no separate database server at all.
You don’t have to use SQLite. But the fact that the default stack can is what makes the “one box you own” story real rather than aspirational.
Propshaft replaces Sprockets
The asset pipeline default is now Propshaft, retiring the fifteen-year-old Sprockets.
Propshaft does deliberately little: it maintains a load path for your assets
and stamps them with digests for far-future caching. No transpilation, no
built-in minification, no directives. In a world of importmap and bundlers
run elsewhere, that smaller job is the right job.
Authentication without Devise
Rails 8 adds a generator for a real, session-based auth system:
bin/rails generate authentication
It creates User and Session models, a SessionsController, a
PasswordsMailer, and an Authentication concern — a working,
password-resettable starting point you own and can read end to end. It isn’t
trying to replace Devise for every case, but for a lot of apps it removes the
reflex of reaching for a gem to do something the framework can now scaffold.
params.expect: safer strong parameters
Strong parameters get a sharper tool. params.expect replaces the familiar
require/permit dance:
# Before
params.require(:post).permit(:title, :body)
# Rails 8
params.expect(post: [:title, :body])
Beyond reading better, expect is stricter about the shape of the input.
Malformed or tampered parameters (an array where a hash was expected, say)
are rejected with a 400, instead of slipping through. It’s a small change
you’ll use in every controller.
Smaller, but worth knowing
A few changes don’t make headlines but matter day to day:
Regexp.timeoutnow defaults to one second, a quiet guard against regular-expression denial-of-service.- On a fresh database, migrations load the schema first, then apply anything newer, which makes setting up a new environment faster and more predictable.
- Rails 8 requires Ruby 3.2 or newer.
My take
Rails 8 has a clear opinion: the default path should let you own your whole stack. Drop Redis for the Solid trio, drop nginx for Thruster, drop the PaaS for Kamal, and — if it fits — drop the database server for SQLite.
Whether that suits you depends on scale and appetite for running your own machines. Plenty of teams will still want managed infrastructure, and that’s fine; none of this is forced. But the framework’s defaults have shifted toward independence, and for the many apps that never needed all that rented plumbing, Rails 8 makes the simpler setup the obvious one.
Have comments or want to discuss this topic?
Send an email to ~bounga/public-inbox@lists.sr.ht