rails: ActiveRecord schema info is not preloaded in production on first request
I know this isn’t stack overflow (great way to open an issue, eh?)… but I’ve been bashing my head at this one for awhile and think it might be an issue in rails.
I’m seeing these kind of queries being issued for each running process’ first request:
I’m doing vanilla ActiveRecord::Base.find
stuff. Both of these options are set:
config.cache_classes = true
config.eager_load = true
On production.
Puma configuration:
workers ENV.fetch('WEB_CONCURRENCY') { 2 }.to_i
threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i
threads threads_count, threads_count
# DB_POOL should be equal to max threads
preload_app!
rackup DefaultRackup
port ENV.fetch('PORT') { 3000 }
environment ENV.fetch('RACK_ENV') { 'development' }
on_worker_boot do
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.establish_connection
end
end
after_worker_boot do
end
before_fork do
ActiveRecord::Base.connection_pool.disconnect!
end
Steps to reproduce
- boot server
- Issue first request
- Inspect rack-mini-profiler stats
Expected behavior
The 50+ sql queries are not executed. The app preloads all that information on boot.
Actual behavior
Every process running (for me its 16) executes 50+ sql schema queries on its first request. So for me, I have 5 servers with 16 processes each, it takes 80 requests before my response times drop from 1 second + to 100-200ms.
System configuration
Rails version: 4.2.6
Ruby version: 2.3.0
Puma version: 3.1.0
pg version: 0.18.4
Heroku
Potentially relevant gems: identity-cache
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 2
- Comments: 15 (7 by maintainers)
Just an FYI to people out there looking for the same solution, I never did end up getting this to work.
No it doesn’t, and yeah it only cache for each model you check.
I never tried this workaround but you could use a
after_initialize
block with this code:In Rails 4 you would also need to backport https://github.com/rails/rails/pull/17632 and https://github.com/rails/rails/pull/20175 to all connections use the cache.
You would be surprised that there is no such thing like not being competent to contribute to Rails.
So to clarify, the
production
environment (or any environment for that matter) does not build this by default on boot if its not present? I definitely think it should, it’s adding 1s+ plus my requests. And from what I’m seeing, its not even fully loaded on the first request - it only caches the models that get hit. So if I go to a different page (2nd request) that has other models, I see these queries as well. (I should have mentioned that)Is there some workaround I could do in the meantime, given my constraints with Heroku? Can I trigger this rake task somewhere in code?
I’d love to help but I’m nowhere near competent enough to contribute to rails core 😃