faraday

What are the default timeouts in Faraday and how can I change them?

Faraday’s default timeout behavior depends on the underlying HTTP adapter, but generally there are no timeouts set by default, which means requests can hang indefinitely. It’s recommended to always set explicit timeouts for production applications.

Default Timeout Behavior

When using the default Net::HTTP adapter without explicit configuration:

  • Open timeout: None (will wait indefinitely to establish connection)
  • Read timeout: None (will wait indefinitely for response)

Setting Timeouts

You can configure timeouts using the request options in your connection:

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'faraday'
end

conn = Faraday.new(url: 'https://api.example.com') do |f|
  f.options.timeout = 5           # Request timeout (seconds)
  f.options.open_timeout = 2      # Connection open timeout (seconds)
  f.adapter Faraday.default_adapter
end

response = conn.get('/endpoint')

Timeout Types

Open Timeout: Time allowed to establish the TCP connection to the server.

conn = Faraday.new do |f|
  f.options.open_timeout = 3  # 3 seconds to connect
  f.adapter Faraday.default_adapter
end

Read Timeout: Time allowed waiting for the server to send response data.

conn = Faraday.new do |f|
  f.options.timeout = 10  # 10 seconds to receive response
  f.adapter Faraday.default_adapter
end

Per-Request Timeouts

You can override connection-level timeouts for individual requests:

conn = Faraday.new(url: 'https://api.example.com') do |f|
  f.options.timeout = 5
  f.adapter Faraday.default_adapter
end

# Override for this specific request
response = conn.get('/slow-endpoint') do |req|
  req.options.timeout = 30        # 30 seconds for this request
  req.options.open_timeout = 5    # 5 seconds to connect
end

Handling Timeout Errors

Timeouts raise Faraday::TimeoutError exceptions:

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'faraday'
end

conn = Faraday.new(url: 'https://api.example.com') do |f|
  f.options.timeout = 5
  f.options.open_timeout = 2
  f.adapter Faraday.default_adapter
end

begin
  response = conn.get('/endpoint')
rescue Faraday::TimeoutError => e
  puts "Request timed out: #{e.message}"
  # Handle timeout (retry, log, fallback, etc.)
rescue Faraday::ConnectionFailed => e
  puts "Connection failed: #{e.message}"
end

For production applications, consider these baseline timeouts:

conn = Faraday.new(url: 'https://api.example.com') do |f|
  f.options.open_timeout = 5   # 5 seconds to establish connection
  f.options.timeout = 10       # 10 seconds for full request/response
  f.adapter Faraday.default_adapter
end

Adjust based on your API’s typical response times and requirements. Faster APIs might use 2-5 second timeouts, while slower APIs processing large data might need 30-60 seconds.

Adapter-Specific Behavior

Different adapters may handle timeouts differently:

  • Net::HTTP (default): Respects both open_timeout and timeout
  • Typhoeus: Uses timeout for total request time
  • Patron: Uses timeout and connect_timeout

Always test timeout behavior with your chosen adapter to ensure it works as expected.