Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
T

the-ultimate-guide-to-ruby-timeouts

> 编程语言
Open source

Timeouts for popular Ruby gems

2.5K stars0 likes2 views
WebsiteGitHub

About

Timeouts for popular Ruby gems

The Ultimate Guide to Ruby Timeouts

An unresponsive service can be worse than a down one. It can tie up your entire system if not handled properly. All network requests should have a timeout.

Here’s how to add timeouts for popular Ruby gems. All have been tested. You should avoid Ruby’s Timeout module. The default is no timeout, unless otherwise specified. Enjoy!

Also available for Python, Node, Go, PHP, and Rust

Timeout Types

  • connect (or open) - time to open the connection
  • read (or receive) - time to receive data after connected
  • write (or send) - time to send data after connected
  • checkout - time to checkout a connection from the pool
  • statement - time to execute a database statement
  • lock (or acquisition) - time to acquire a lock
  • request (or service) - time to process a request
  • wait - time to start processing a queued request
  • command - time to run a command
  • solve - time to solve an optimization problem

Statement Timeouts

For many apps, the single most important thing to do (if you use a relational database)

  • PostgreSQL
  • MySQL
  • MariaDB

Gems

Standard Library

  • io
  • net/ftp
  • net/http
  • net/imap
  • net/pop
  • net/smtp
  • open-uri
  • regexp
  • socket

Data Stores

  • activerecord
  • bunny
  • cassandra-driver
  • connection_pool
  • couchrest
  • dalli
  • drill-sergeant
  • elasticsearch
  • hiredis
  • immudb
  • influxdb
  • influxdb-client
  • meilisearch
  • mongo
  • mongoid
  • mysql2
  • neo4j
  • pg
  • presto-client
  • redis
  • redis-client
  • riddle
  • rsolr
  • ruby-druid
  • ruby-kafka
  • searchkick
  • sequel
  • trino-client
  • typesense

HTTP Clients

  • curb
  • down
  • em-http-client
  • excon
  • faraday
  • http
  • httparty
  • httpclient
  • httpi
  • patron
  • rest-client
  • typhoeus

Commands

  • mixlib-shellout
  • posix-spawn
  • tty-command

Web Servers

  • puma
  • unicorn

Rack Middleware

  • rack-timeout
  • slowpoke

Solvers

  • or-tools
  • osqp
  • ruby-cbc
  • scs

Distributed Locks

  • activerecord
  • mlanett-redis-lock
  • redlock
  • suo
  • with_advisory_lock

3rd Party Services

  • airrecord
  • airtable
  • algoliasearch
  • aws-sdk
  • azure
  • bitly
  • boxr
  • checkr-official
  • clearbit
  • dogapi
  • dropbox-sdk
  • droplet_kit
  • fastly
  • firebase
  • flickraw
  • gibbon
  • github_api
  • gitlab
  • google-api-client
  • google-cloud
  • intercom
  • jira-ruby
  • koala
  • linkedin
  • octokit
  • pusher
  • pwned
  • restforce
  • rspotify
  • ruby-trello
  • sentry-ruby
  • shopify_api
  • sift
  • slack-notifier
  • slack-ruby-client
  • smartystreets_ruby_sdk
  • soda-ruby
  • soundcloud
  • stripe
  • tamber
  • twilio-ruby
  • twitter
  • yt
  • zendesk_api

Other

  • acme-client
  • actionmailer
  • activemerchant
  • activeresource
  • carrot2
  • docker-api
  • etcd
  • etcdv3
  • fastimage
  • geocoder
  • graphql-client
  • grpc
  • hexspace
  • ignite-client
  • kubeclient
  • mail
  • mechanize
  • nats-pure
  • nestful
  • net-dns
  • net-ldap
  • net-ntp
  • net-scp
  • net-sftp
  • net-ssh
  • net-telnet
  • omniauth-oauth2
  • rbhive
  • reversed
  • savon
  • spidr
  • spyke
  • stomp
  • thrift
  • thrift_client
  • vault
  • whois
  • zk
  • zookeeper

Statement Timeouts

Prevent single queries from taking up all of your database’s resources.

PostgreSQL

If you use Rails, add to your config/database.yml

production:
  variables:
    statement_timeout: 5s # or ms, min, etc

or set it on your database role

ALTER ROLE myuser SET statement_timeout = '5s';

Test with

SELECT pg_sleep(6);

To set for a single transaction, use

BEGIN;
SET LOCAL statement_timeout = '5s';
...
COMMIT;

For migrations, you likely want to set a longer statement timeout. You can do this with

production:
  variables:
    statement_timeout: <%= ENV["STATEMENT_TIMEOUT"] || "5s" %>

And use

STATEMENT_TIMEOUT=90s rails db:migrate

MySQL

Note: Only applies to read-only SELECT statements (more info)

If you use Rails, add to your config/database.yml

production:
  variables:
    max_execution_time: 5000 # ms

or set it directly on each connection

SET SESSION max_execution_time = 5000;

Test with

SELECT 1 FROM information_schema.tables WHERE sleep(6);

To set for a single statement, use an optimizer hint

SELECT /*+ MAX_EXECUTION_TIME(5000) */ ...

MariaDB

If you use Rails, add to your config/database.yml

production:
  variables:
    max_statement_time: 5 # sec

or set it directly on each connection

SET SESSION max_statement_time = 5;

Test with

SELECT 1 FROM information_schema.tables WHERE sleep(6);

To set for a single statement, use

SET STATEMENT max_statement_time=5 FOR
  SELECT ...

For migrations, you likely want to set a longer statement timeout. You can do this with

production:
  variables:
    max_statement_time: <%= ENV['MAX_STATEMENT_TIME'] || 5 %>

And use

MAX_STATEMENT_TIME=90 rails db:migrate

Official docs

Standard Library

io

Note: Requires Ruby 3.2+

STDIN.timeout = 1

Raises IO::TimeoutError

net/ftp

Net::FTP.new(host, open_timeout: 1, read_timeout: 1)

Raises

  • Net::OpenTimeout on connect timeout
  • Net::ReadTimeout on read timeout

net/http

Net::HTTP.start(host, port, open_timeout: 1, read_timeout: 1, write_timeout: 1) do
  # ...
end

or

http = Net::HTTP.new(host, port)
http.open_timeout = 1
http.read_timeout = 1
http.write_timeout = 1

Raises

  • Net::OpenTimeout on connect timeout
  • Net::ReadTimeout on read timeout
  • Net::WriteTimeout on write timeout

Default: 60s connect timeout, 60s read timeout, 60s write timeout

Read timeouts are retried once automatically for idempotent methods like GET. You can set the max number of retries with http.max_retries = 1.

net/imap

Net::IMAP.new(host, open_timeout: 1)

Read timeout is not configurable at the moment

Raises Net::OpenTimeout on connect timeout

net/pop

pop = Net::POP.new(host)
pop.open_timeout = 1
pop.read_timeout = 1

Raises

  • Net::OpenTimeout on connect timeout
  • Net::ReadTimeout on read timeout

net/smtp

smtp = Net::SMTP.new(host, 25)
smtp.open_timeout = 1
smtp.read_timeout = 1

Raises

  • Net::OpenTimeout on connect timeout
  • Net::ReadTimeout on read timeout

open-uri

URI.parse(url).open(open_timeout: 1, read_timeout: 1)

Raises

  • Net::OpenTimeout on connect timeout
  • Net::ReadTimeout on read timeout

regexp

Note: Requires Ruby 3.2+

Regexp.timeout = 1
# or
Regexp.new(regexp, timeout: 1)

Raises Regexp::TimeoutError

socket

Socket.tcp(host, 80, connect_timeout: 1) do |sock|
  # ...
end

Raises Errno::ETIMEDOUT

Data Stores

activerecord

  • postgres adapter

    ActiveRecord::Base.establish_connection(connect_timeout: 1, checkout_timeout: 1, ...)
    

    or in config/database.yml

    production:
      connect_timeout: 1
      checkout_timeout: 1
    

    Raises

    • ActiveRecord::ConnectionNotEstablished on connect and read timeouts
    • ActiveRecord::ConnectionTimeoutError on checkout timeout

    See also PostgreSQL statement timeouts

  • mysql2 adapter

    ActiveRecord::Base.establish_connection(connect_timeout: 1, read_timeout: 1, write_timeout: 1, checkout_timeout: 1, ...)
    

    or in config/database.yml

    production:
      connect_timeout: 1
      read_timeout: 1
      write_timeout: 1
      checkout_timeout: 1
    

    Raises

    • ActiveRecord::ConnectionNotEstablished on connect and read timeouts
    • ActiveRecord::ConnectionTimeoutError on checkout timeout

    See also MySQL statement timeouts

bunny

Bunny.new(connection_timeout: 1, read_timeout: 1, ...)

Raises

  • Bunny::TCPConnectionFailedForAllHosts on connect timeout
  • Bunny::NetworkFailure on read timeout

cassandra-driver

Cassandra.cluster(connect_timeout: 1, timeout: 1)

Default: 10s connect timeout, 12s read timeout

Raises

  • Cassandra::Errors::NoHostsAvailable on connect timeout
  • Cassandra::Errors::TimeoutError on read timeout

connection_pool

ConnectionPool.new(timeout: 1) { ... }

Raises ConnectionPool::TimeoutError

couchrest

CouchRest.new(url, open_timeout: 1, read_timeout: 1, timeout: 1)

Raises

  • HTTPClient::ConnectTimeoutError on connect timeout
  • HTTPClient::ReceiveTimeoutError on read timeout

dalli

Dalli::Client.new(host, socket_timeout: 1, ...)

Default: 1s

Raises Dalli::RingError

drill-sergeant

Drill.new(url: url, open_timeout: 1, read_timeout: 1)

Default: 3s connect timeout, no read timeout

Raises

  • Net::OpenTimeout on connect timeout
  • Net::ReadTimeout on read timeout

elasticsearch

Elasticsearch::Client.new(transport_options: {request: {timeout: 1}}, ...)

Raises Elastic::Transport::Transport::Error

hiredis

conn = Hiredis::Connection.new
conn.timeout = 1_000_000 # microseconds

Raises

  • Errno::ETIMEDOUT on connect timeout
  • Errno::EAGAIN on read timeout

immudb

Immudb::Client.new(host, timeout: 1)

Raises GRPC::DeadlineExceeded

influxdb

InfluxDB::Client.new(open_timeout: 1, read_timeout: 1)

Raises InfluxDB::ConnectionError

influxdb-client

InfluxDB2::Client.new(url, token, open_timeout: 1, read

GitHub Issues· 0 open

View all on GitHub

No open issues yet, or sync has not completed.

Highlights

  • •connect (or open) - time to open the connection
  • •read (or receive) - time to receive data after connected
  • •write (or send) - time to send data after connected
  • •checkout - time to checkout a connection from the pool
  • •statement - time to execute a database statement
  • •lock (or acquisition) - time to acquire a lock
  • •request (or service) - time to process a request
  • •wait - time to start processing a queued request
  • •command - time to run a command
  • •solve - time to solve an optimization problem

> Tags

Ruby

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言