Rails 7.1 uses query cache for runner scripts

In Rails 7.1 this ‘rails runner’ script will use the query cache:

$ cat script/test_cache.rb
u1 = User.last
u2 = User.last

Rails 7.1:

$ rails r script/test_cache.rb
  User Load (1.2ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
  CACHE User Load (0.0ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]

but in Rails 7 this does not happen:

$ rails r script/test_cache.rb               
  User Load (2.2ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
  User Load (0.3ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]

I was wondering if this is intentional as it can cause significant behavior changes in, for example, long running background scripts. I could not find this change mentioned in the 7.1 release notes, and the guide documentation for the query cache states that it is associated with a Rails action and hence does not work in the console.

The query cache becoming enabled is a side-effect of this: Wrap rails runner in executor by casperisfine · Pull Request #44999 · rails/rails · GitHub

The the Rails Executor manages a number of things, including error reporting, database connections state, constant reloading… and query cache.

Rails is moving towards all application code being wrapped in an Executor. Example: Call Executor#wrap around each test by casperisfine · Pull Request #43550 · rails/rails · GitHub

2 Likes