Eric / Brooklyn

Random 5

Operator as Methods

Web Accounts

Honeypot Bots

Stripe and Tap

Git Save

Whitespace Problems

Ruby Exits

Appending in Javascript

Sendgrid Ban

Clean URLs

Integer Division

Multi-tab Websockets

Bad Content

JS Data Chutzpah

Responsive tables

Concerns

Cookies

Emoji Bits

Git

Ruby vs. Ruby

Extending Devise

Rails UJS

ENV Variables

See All

Max_threads ENV Vars

Jan 2020

With Heroku Pipelines and Figaro

This is probably one of the most boring posts on the internet, but I’m planning to forget the following in 30 seconds, so let’s write it down quickly.

We’re building a Rails application that uses a Postgres database, Redis, Sidekiq, and Puma.

A default rails app will try to use the environment variable RAILS_MAX_THREADS in a lot of these places.

How to choose your RAILS_MAX_THREADS depends on a lot of things that are out of the bounds of this blog post or my understanding. Heroku has some good info if you’re curious.

Where is RAILS_MAX_THREADS being reused?

Currently, we’re using RAILS_MAX_THREADS in our:

  • puma.rb config (this is the web server that runs the app).
  • sidekiq.yml config (this is what we’re using to run jobs)
  • database.yml config (how many connections the app can make with the database)

Where to put RAILS_MAX_THREADS?

Since we’re reusing RAILS_MAX_THREADS in many places, where should we put this global variable so that it’s available where it needs to be?

Where not to put them?

Our couple attempts at setting this up failed, we at least we know a couple of places where we shouldn’t put them.

(1) Don’t put RAILS_MAX_THREADS in your Credentials file. This is because our Credentials file is not available to things in our config folder (puma.rb, sidekiq.yml, etc.). This appears to be a timing thing, as the config files are parsed before the app is built (and Credentials generated).

(2) Don’t put RAILS_MAX_THREADS in a confusing global variable. Initially I created a global.yml file containing the RAILS_MAX_THREADS in config. Then, I added:

GLOBAL_SETTINGS = YAML.load_file(Rails.root.join("config/global.yml"))

to an initializer, assuming I’d be able to call

 <%= GLOBAL_SETTINGS["RAILS_MAX_THREADS"] %>

inside the config folder.

Nope, this doesn’t work, probably for similar reasons as number 1 above.

Where to put them?!

For each environment, we will be able to access our RAILS_MAX_THREADS as

<%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

where 5 is just the back-up value if the ENV var is not found.

Development

For DEV, we use the Figaro Gem, which allows us to specify ENV variables in an application.yml file.

Even though our max_threads isn’t too sensitive, application.yml is ignored from version control, in case we end up adding more ENV variables later on.

# application.yml

development:
  RAILS_MAX_THREADS: 5
  RAILS_MIN_THREADS: 5

Review Apps

We’re using Heroku Pipelines, so we create Review Apps every so often.

Rather than having to manually set the ENV variables for each Review App, we can specify the ENV variables in our app.json. This file lays out details about how our new heroku apps will be built.

{
  "description": "Learning and Teaching",
  "website": "https://bounce.so",

  "env": {
    "RAILS_ENV": "staging",
    "RACK_ENV": "staging",
    "RAILS_MAX_THREADS": "10",
    "RAILS_MIN_THREADS": "10"
  }
 ...

}

Note that strings are required for environment variables in our app.json.

Staging App

Perhaps we want our RAILS_MAX_THREADS to be different than our review apps, because we’re trying to mimic production here, (and have the associtated bigger plans).

For this, we’ll go into our config vars on heroku and manually set them. This can be done from the UI or the terminal. this isn’t too much of a pain, because this only really needs to be set once, or any time we want to tinker with performance.

Had the app.json been loaded with that env variable from the start, our config vars for Staging would already have the thread value set (though of course we can override it).

Production

Same story as Staging, we can manually update them on Heroku dash, or via command line.

Conclusion

Congratulations on reading the most boring post on the internet. There are others that rival this elsewhere on the site if you’re interested.