19

I'm using heroku and heroku postgresql. How do I set db command timeout so that I get an exception when a sql command takes longer than 10 seconds?

4 Answers 4

23

Configure your database.yml like this, the key bit being the variables hash:

defaults: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  min_messages: warning
  variables:
    statement_timeout: 5000
Sign up to request clarification or add additional context in comments.

5 Comments

You can SET other parameters per session as well: github.com/rails/rails/blob/4-2-stable/activerecord/lib/…
If I run rails dbconsole and then SHOW statement_timeout; it says that i've not got any statement timeout. If this works, is there a way to verify that it works?
I see the same behavior with rails db. The easiest way to validate it is something like User.select('pg_sleep(10)') from the rails console and verifying that it times out after 5 seconds or whatever you configured it to.
Is there any way to add this only to the frontend and not to background workers (Sidekiq)?
Sure. The database.yml can contain ERB (ruby logic) so you could do something like pass a command line flag or set an environment variable for that process type, then do an if on the timeout config.
6

I found a solution here: Ruby on Rails: How to set a database timeout in application configuration?

Add

ActiveRecord::Base.connection.execute('set statement_timeout to 10000')

in the end of the environment.rb file.

Does anyone see a better way?

2 Comments

This command runs the SQL command from the other answer through the ActiveRecord connection so that is remains true for the duration of the connection. It should be effective.
would this work in heroku? i.e heroku cutting your worker connection after 30 secs?
6

Adding

ActiveRecord::Base.connection.execute('set statement_timeout to 10000')

to the end of the environment.rb file did not work for me.

What worked was adding

ActiveRecord::Base.connection.execute("SET statement_timeout = '10s'")

to an initialize file.

Comments

5

I don't know ruby, but in PostgreSQL you can simply run this:

SET statement_timeout = '10s'

and afterwards, all queries in this connection (session) will have strict limit on runtime.

You can also change it in postgresql.conf as global default, or even make it default in given database or for given user like:

ALTER DATABASE web SET statement_timeout = '10s';
ALTER USER bad_user SET statement_timeout = '10s';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.