Navigation
This version of the documentation is archived and no longer supported.

Creating a Client

Using Mongo::Client

To connect to a MongoDB deployment, create a Mongo::Client object. Provide a list of hosts and options or a connection string URI to the``Mongo::Client`` constructor. The client’s selected database defaults to admin.

By default, the driver will automatically detect the topology used by the deployment and connect appropriately.

To connect to a local standalone MongoDB deployment, specify the host and port of the server. In most cases you would also specify the database name to connect to; if no database name is specified, the client will use the admin database:

Mongo::Client.new([ '127.0.0.1:27017' ], database: 'mydb')

# Or using the URI syntax:
Mongo::Client.new("mongodb://127.0.0.1:27017/mydb")

Note

The hostname localhost is treated specially by the driver and will be resolved to IPv4 addresses only.

To connect to MongoDB Atlas, specify the Atlas deployment URI:

Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/mydb?w=majority")

The driver will discover all nodes in the cluster and connect to them as needed.

Block Syntax

Another way to create a Mongo::Client object is to use the block syntax:

Mongo::Client.new(...) do |client|
  # work with the client
end

Note that when creating a client using this syntax, the client is automatically closed after the block finishes executing.

Database Selection

By default, the client will connect to the admin database.

The admin database is a special database in MongoDB often used for administrative tasks and storing administrative data such as users and roles (although users and roles may also be defined in other databases). In a sharded cluster, the admin database exists on the config servers rather than the shard servers. Although it is possible to use the admin database for ordinary operations (such as storing application data), this is not recommended and the application should explicitly specify the database it wishes to use.

The database can be specified during Client construction:

# Using Ruby client options:
client = Mongo::Client.new(['localhost'], database: 'mydb')

# Using a MongoDB URI:
client = Mongo::Client.new('mongodb://localhost/mydb')

Given a Client instance, the use method can be invoked to obtain a new Client instance configured with the specified database:

client = Mongo::Client.new(['localhost'], database: 'mydb')

admin_client = client.use('admin')

# Issue an administrative command
admin_client.database.command(replSetGetConfig: 1).documents.first

There are other special databases in MongoDB which should be only used for their stated purposes:

Connection Types

Direct Connection

If the deployment is a replica set, the driver will by default discover all members of the replica set given the address of any one member, and will dispatch operations to the appropriate member (for example, writes would be dispatched to the primary).

To force all operations to be performed on the designated server, specify the direct_connection option:

Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', direct_connection: true)

# Or using the URI syntax:
Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?directConnection=true")

Replica Set Connection

To connect to a replica set deployment managed by a service providing SRV URIs (such as MongoDB Atlas), connect to the URI:

Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority")

If not using SRV URIs, it is sufficient to pass the address of any node in the replica set to the driver; the driver will then automatically discover the remaining nodes. However, it is recommended to specify all nodes that are part of the replica set, so that in the event of one or more nodes being unavailable (for example, due to maintenance or reconfiguration) the driver can still connect to the replica set.

Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ],
  :database => 'mydb', replica_set: 'myapp')

# Or using the URI syntax:
Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?replicaSet=myapp")

Sharded Cluster Connection

To connect to a sharded cluster deployment managed by a service providing SRV URIs (such as MongoDB Atlas), connect to the URI:

Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority")

When the driver connects to a sharded cluster via an SRV URI, it will monitor the SRV records of the address specified in the URI for changes and will automatically add and remove mongos hosts to/from its list of servers as they are added and removed to/from the sharded cluster.

If not using SRV URIs, pass the addresses of one or more mongos hosts. Unlike with replica set deployments, the driver is not able to discover all mongos nodes in a sharded cluster when not using SRV URIs. It is not required that all mongos node addresses are given to the driver - the driver will balance the operation load among the nodes it is given. Specifying more nodes will spread the operation load accordingly.

Mongo::Client.new([ '1.2.3.4:27017', '1.2.3.5:27017' ], :database => 'mydb')

Mongo::Client.new("mongodb://1.2.3.4:27017,1.2.3.5:27017/mydb")

SRV URIs

When the driver connects to a mongodb+srv protocol URI, keep in mind the following:

  1. SRV URI lookup is performed synchronously when the client is constructed. If this lookup fails for any reason, client construction will fail with an exception. When a client is constructed with a list of hosts, the driver will attempt to contact and monitor those hosts for as long as the client object exists. If one of these hosts does not resolve initially but becomes resolvable later, the driver will be able to establish a connection to such a host when it becomes available. The initial SRV URI lookup must succeed on the first attempt; subsequent host lookups will be retried by the driver as needed.
  2. The driver looks up URI options in the DNS TXT records corresponding to the SRV records. These options can be overridden by URI options specified in the URI and by Ruby options, in this order.
  3. If the topology of the constructed Client object is unknown or a sharded cluster, the driver will begin monitoring the specified SRV DNS records for changes and will automatically update the list of servers in the cluster. The updates will stop if the topology becomes a single or a replica set.

Client Options

Mongo::Client’s constructor accepts a number of options configuring the behavior of the driver. The options can be provided in the options hash as Ruby options, in the URI as URI options, or both. If both a Ruby option and the analogous URI option are provided, the Ruby option takes precedence.

Ruby Options

Note

The options passed directly should be symbols.

Note

Unless otherwise specified, Ruby options that deal with times are given in seconds.

Option Description Type Default
:app_name Application name that is printed to the mongod logs upon establishing a connection in server versions >= 3.4. String none
:auth_mech Specifies the authenticaion mechanism to use. Can be one of: :gssapi, :mongodb_cr, :mongodb_x509, :plain, :scram, :scram256. GSSAPI (Kerberos) authentication requires additional dependencies. Symbol If user credentials are not supplied, nil. If user credentials are supplied, the default depends on server version. MongoDB 4.0 and later: :scram256 if user credentials correspond to a user which supports SCRAM-SHA-256 authentication, otherwise :scram. MongoDB 3.0-3.6: :scram. MongoDB 2.6: :mongodb_cr
:auth_mech_properties

Provides additional authentication mechanism properties.

The keys in properties are interpreted case-insensitively. When the client is created, keys are lowercased.

Hash When using the GSSAPI authentication mechanism, the default properties are {service_name: "mongodb"}. Otherwise the default is nil.
:auth_source Specifies the authentication source. String For MongoDB 2.6 and later: admin if credentials are supplied, otherwise the current database
:auto_encryption_options

A Hash of options for configuring automatic encryption.

  • :key_vault_client - A client connected to the MongoDB instance storing the encryption data keys (Mongo::Client, defaults to the top-level client instance).
  • :key_vault_namespace - The namespace of the key vault collection in the format "database.collection" (String, required).
  • :kms_providers - Key management service configuration information. One or both of the keys :local and :aws must be specified (Hash, required). See the “The kms_providers option`` section of the Client-Side Encryption tutorial for more information about this option.
  • :schema_map - The JSONSchema for one or more collections specifying which fields should be encrypted (Hash, optional, defaults to nil).
  • :bypass_auto_encryption - Whether to skip automatic encryption when performing database operations (Boolean, defaults to false).
  • :extra_options - Options related to spawning mongocryptd (Hash, optional, defaults to nil).

For more information about formatting these options, see the “Auto-Encryption Options” section of the Client-Side Encryption tutorial.

Hash none
:bg_error_backtrace Experimental. Controls whether and how backtraces are logged when errors occur in background threads. If true, the driver will log complete backtraces. If set to a positive integer, the driver will log up to that many backtrace lines. If set to false or nil, no backtraces will be logged. Other values are an error. true, false, nil, Integer none
:compressors A list of potential compressors to use, in order of preference. Please see below for details on how the driver implements compression. Array<String> none
:connect Deprecated. Disables deployment topology discovery normally performed by the dirver and forces the cluster topology to a specific type. Choices: :direct, :replica_set or :sharded. Symbol none
:connect_timeout The number of seconds to wait to establish a socket connection before raising an exception. This timeout is also used for SRV DNS record resolution. nil and 0 mean no timeout. Client creation will fail with an error if an invalid timeout value is passed (such as a negative value or a non-numeric value). Float 10
:database The name of the database to connect to. String admin
:direct_connection Connect directly to the specified host, do not discover deployment topology. Boolean false
:heartbeat_frequency The number of seconds for the server monitors to refresh server states asynchronously. Float 10
:id_generator A custom object to generate ids for documents. Must respond to #generate. Object none
:local_threshold Specifies the maximum latency in seconds between the nearest server and the servers that can be available for selection to operate on. Float 0.015
:logger A custom logger. Object Logger
:max_idle_time The maximum seconds a socket can remain idle since it has been checked in to the pool. Integer none
:max_pool_size The maximum size of the connection pool for each server. Integer 5
:max_read_retries The maximum number of read retries, when legacy read retries are used. Set to 0 to disable legacy read retries. Integer 1
:max_write_retries The maximum number of write retries, when legacy write retries are used. Set to 0 to disable legacy write retries. Integer 1
:min_pool_size The minimum number of connections in the connection pool for each server. The driver does not create connections eagerly - a connection is only created when a MongoDB operation is to be executed and there are no available connections, and the total number of established connections to the target server is below :max_pool_size. However, once connections to a particular server are created, up to :min_pool_size connections will be kept in the connection pool by the driver. Integer 0
:monitoring The monitoring object. Object none
:password The password of the user to authenticate with. String none
:platform Platform information to include in the metadata printed to the mongod logs upon establishing a connection in server versions >= 3.4. String none
:read

Specifies the read preference mode and tag sets for selecting servers as a Hash. Allowed Keys in the hash are :mode, :tag_sets and :max_staleness.

{ read:
  { mode: :secondary,
    tag_sets: [ "data_center" => "berlin" ],
    max_staleness: 5,
  }
}

If tag sets are provided, they must be an array of hashes. A server satisfies the read preference if its tags match any one hash in the provided tag sets.

Each tag set must be a hash, and will be converted internally to a BSON::Document instance prior to being used for server selection. Hash keys can be strings or symbols. The keys are case sensitive. Hash values must be strings, and are matched exactly against the values in the replica set configuration.

Hash { :mode => :primary }
:read_concern Specifies the read concern options. The only valid key is level, for which the valid values are :local, :majority, and :snapshot. Hash none
:read_retry_interval The interval, in seconds, in which reads on a mongos are retried. Integer 5
:replica_set When connecting to a replica set, this is the name of the set to filter servers by. String none
:retry_writes If a single-statement write operation fails from a network error, the driver automatically retries it once when connected to server versions 3.6+. Boolean true
:sdam_proc

Since the client begins monitoring the deployment in background as soon as it is constructed, constructing a client and then subscribing to SDAM events in a separate statement may result in the subscriber not receiving some of the SDAM events. The :sdam_proc option permits adding event subscribers on the client being constructed before any SDAM events are published.

Pass a Proc which will be called with the Client as the argument after the client’s event subscription mechanism has been initialized but before any of the servers are added to the client. Use this Proc to set up SDAM event subscribers on the client.

Note: the client is not fully constructed when the Proc provided in :sdam_proc is invoked, in particular the cluster is nil at this time. ``:sdam_proc procedure should limit itself to calling Client#subscribe and Client#unsubscribe methods on on the passed client only.

Proc none
:server_api

The server API version requested. This is a hash with the following allowed items: - :version (String) - :strict (true or false) - :deprecation_errors (true or false)

Note that the server API version can only be specified as a Ruby option, not as a URI option, and it cannot be overridden for database and collection objects.

If server API version is changed on a client (such as via the with call), the entire API version hash is replaced with the new specification (the old and the new individual fields are NOT merged).

Hash none
:server_selection_timeout The number of seconds to wait for an appropriate server to be selected for an operation to be executed before raising an exception. Float 30
:socket_timeout The number of seconds to wait for an operation to execute on a socket before raising an exception. nil and 0 mean no timeout. Client creation will fail with an error if an invalid timeout value is passed (such as a negative value or a non-numeric value). Float none
:ssl Tell the client to connect to the servers via TLS. Boolean false
:ssl_ca_cert The file path containing concatenated certificate authority certificates used to validate certs passed from the other end of the connection. One of :ssl_ca_cert, :ssl_ca_cert_string or :ssl_ca_cert_object (in order of priority) is required for :ssl_verify. String none
:ssl_ca_cert_object An array of OpenSSL::X509::Certificate representing the certificate authority certificates used to validate certs passed from the other end of the connection. One of :ssl_ca_cert, :ssl_ca_cert_string or :ssl_ca_cert_object (in order of priority) is required for :ssl_verify. Array< OpenSSL::X509::Certificate > none
:ssl_ca_cert_string A string containing concatenated certificate authority certificates used to validate certs passed from the other end of the connection. One of :ssl_ca_cert, :ssl_ca_cert_string or :ssl_ca_cert_object (in order of priority) is required for :ssl_verify. String none
:ssl_cert

Path to the client certificate file used to identify the application to the MongoDB servers. The file may also contain the certificate’s private key; if so, the private key is ignored by this option. The file may also contain intermediate certificates forming the certificate chain from the client certificate to the CA certificate; any intermediate certificates will be parsed by the driver and provided to the OpenSSL context in extra_chain_cert attribute. If intermediate certificates are provided, they must follow the client certificate which must be the first certificate in the file.

This option, if present, takes precedence over :ssl_cert_string and :ssl_cert_object options.

String none
:ssl_cert_object The OpenSSL::X509::Certificate used to identify the application to the MongoDB servers. Only one certificate may be passed through this option. OpenSSL::X509::Certificate none
:ssl_cert_string

A string containing the PEM-encoded certificate used to identify the application to the MongoDB servers. The string may also contain the certificate’s private key; if so, the private key is ignored by this option. The string may also contain intermediate certificates forming the certificate chain from the client certificate to the CA certificate; any intermediate certificates will be parsed by the driver and provided to the OpenSSL context in extra_chain_cert attribute. If intermediate certificates are provided, they must follow the client certificate which must be the first certificatet in the string.

This option, if present, takes precedence over the :ssl_cert_object option.

String none
:ssl_key The private keyfile used to identify the connection against MongoDB. Note that even if the key is stored in the same file as the certificate, both need to be explicitly specified. This option, if present, takes precedence over the values of :ssl_key_string and :ssl_key_object. String none
:ssl_key_object The private key used to identify the connection against MongoDB. OpenSSL::PKey none
:ssl_key_pass_phrase A passphrase for the private key. String none
:ssl_key_string A string containing the PEM-encoded private key used to identify the connection against MongoDB. This parameter, if present, takes precedence over the value of option :ssl_key_object. String none
:ssl_verify Whether to perform peer certificate, hostname and OCSP endpoint validation. Note that the decision of whether to validate certificates will be overridden if :ssl_verify_certificate is set, the decision of whether to validate hostnames will be overridden if :ssl_verify_hostname is set and the decision of whether to validate OCSP endpoint will be overridden if :ssl_verify_ocsp_endpoint is set. Boolean true
:ssl_verify_certificate Whether to perform peer certificate validation. This setting overrides the :ssl_verify setting with respect to whether certificate validation is performed. Boolean true
:ssl_verify_hostname Whether to perform peer hostname validation. This setting overrides the :ssl_verify setting with respect to whether hostname validation is performed. Boolean true
:ssl_verify_ocsp_endpoint Whether to validate server-supplied certificate against the OCSP endpoint specified in the certificate, if the OCSP endpoint is specified in the certificate. This setting overrides :ssl_verify with respect to whether OCSP endpoint validation is performed. Boolean true
:truncate_logs Whether to truncate the logs at the default 250 characters. Boolean true
:user The name of the user to authenticate with. String none
:wait_queue_timeout The number of seconds to wait for a connection in the connection pool to become available. Float 10
:wrapping_libraries Information about libraries such as ODMs that are wrapping the driver. Specify the lower level libraries first. Allowed hash keys: :name, :version, :platform. Example: [name: 'Mongoid', version: '7.1.2'] Array<Hash> none
:write Deprecated. Equivalent to :write_concern option. If both :write and :write_concern are specified, their values must be identical. Hash { w: 1 }
:write_concern

Specifies write concern options as a Hash. Keys in the hash can be :w, :wtimeout, :j, :fsync. Note that :wtimeout is specified in milliseconds, not seconds.

{ write_concern: { w: 2 } }
Hash { w: 1 }
:zlib_compression_level The Zlib compression level to use, if using compression. See Ruby’s Zlib module for valid levels. Integer none

Note

The Ruby driver does not implement certificate revocation list (CRL) checking.

URI Options

Since the URI options are required to be in camel case, which is not the Ruby standard, the following table shows URI options and their corresponding Ruby options.

URI options are explained in detail in the Connection URI reference.

Note

Options that are set in milliseconds in the URI are represented as a float in Ruby and the units are seconds.

URI Option Ruby Option
appName=String :app_name => String
authMechanism=String

:auth_mech => Symbol

Auth mechanism values are converted as follows from URI options to Ruby options:

  • GSSAPI => :gssapi
  • MONGODB-CR => :mongodb_cr
  • MONGODB-X509 => :mongodb_x509
  • PLAIN => :plain
  • SCRAM-SHA-1 => :scram
  • SCRAM-SHA-256 => :scram256

If a different value is provided for auth mechanism, it is converted to the Ruby option unmodified and retains its String type. Note that, while currently the driver allows a Client instance to be constructed with an unrecognized auth mechanism, this behavior may change in a future version of the driver.

authMechanismProperties=Strings

{ :auth_mech_properties => { :service_realm => String, :canonicalize_host_name => true|false, :service_name => String } }

Specified as comma-separated key:value pairs, e.g. "SERVICE_REALM:foo,CANONICALIZE_HOST_NAME:TRUE".

authSource=String :auth_source => String
compressors=Strings

:compressors => Array<String>

A comma-separated list of potential compressors to use, in order of preference. Please see below for details on how the driver implements compression.

connect=String :connect => Symbol
connectTimeoutMS=Integer

:connect_timeout => Float

Unlike the corresponding Ruby option which fails client creation on invalid values (e.g. negative and non-numeric values), invalid values provided via this URI option are ignored with a warning.

directConnection=Boolean :direct_connection => Boolean
fsync=Boolean { :write_concern => { :fsync => true|false }}
heartbeatFrequencyMS=Integer :heartbeat_frequency => Float
journal=Boolean { :write_concern => { :j => true|false }}
localThresholdMS=Integer :local_threshold => Float
maxIdleTimeMS=Integer :max_idle_time => Float
maxStalenessSeconds=Integer

{ :read => { :max_staleness => Integer }}

If the maxStalenessSeconds URI option value is -1, the driver treats this as if the option was not given at all. Otherwise, if the option value is numeric, the Ruby option is set to the specified value converted to an Integer. Note that numeric values greater than 0 but less than 90, or less than -1, are accepted by the Client constructor but will cause server selection to fail (unless the option is changed via, for example, the with method prior to any operations being performed on the driver). If the option value is non-numeric, it is ignored and the driver treats this case as if the option was not given at all.

maxPoolSize=Integer :max_pool_size => Integer
minPoolSize=Integer :min_pool_size => Integer
readConcernLevel=String :read_concern => Hash
readPreference=String { :read => { :mode => Symbol }}
readPreferenceTags=Strings

{ :read => { :tag_sets => Array<Hash> }}

Each instance of the readPreferenceTags field is a comma-separated key:value pair which will appear in the :tag_sets array in the order they are specified. For instance, "readPreferenceTags=dc:ny,rack:1&readPreferenceTags=dc:ny" will be converted to [ { 'dc' => 'ny', 'rack' => '1' }, { 'dc' => 'ny' }].

replicaSet=String :replica_set => String
retryWrites=Boolean :retry_writes => boolean
serverSelectionTimeoutMS=Integer :server_selection_timeout => Float
socketTimeoutMS=Integer

:socket_timeout => Float

Unlike the corresponding Ruby option which fails client creation on invalid values (e.g. negative and non-numeric values), invalid values provided via this URI option are ignored with a warning.

ssl=Boolean :ssl => true|false
tls=Boolean :ssl => boolean
tlsAllowInvalidCertificates=Boolean

:ssl_verify_certificate => boolean

Because tlsAllowInvalidCertificates uses true to signify that verification should be disabled and ssl_verify_certificate uses false to signify that verification should be disabled, the boolean is inverted before being used to set ssl_verify_certificate.

tlsAllowInvalidHostnames=Boolean

:ssl_verify_hostname => boolean

Because tlsAllowInvalidHostnames uses true to signify that verification should be disabled and ssl_verify_hostname uses false to signify that verification should be disabled, the boolean is inverted before being used to set ssl_verify_hostname.

tlsCAFile=String :ssl_ca_cert => String
tlsCertificateKeyFile=String :ssl_cert => String
tlsCertificateKeyFile=String :ssl_key => String
tlsCertificateKeyFilePassword=String :ssl_key_pass_phrase => String
tlsDisableOCSPEndpointCheck=Boolean

:ssl_verify_ocsp_endpoint => boolean

Because tlsDisableOCSPEndpointCheck uses true to signify that verification should be disabled and ssl_verify_ocsp_endpoint uses false to signify that verification should be disabled, the boolean is inverted before being used to set ssl_verify_ocsp_endpoint.

tlsInsecure=Boolean

:ssl_verify => boolean

Because tlsInsecure uses true to signify that verification should be disabled and ssl_verify uses false to signify that verification should be disabled, the boolean is inverted before being used to set ssl_verify.

w=Integer|String { :write_concern => { :w => Integer|String }}
waitQueueTimeoutMS=Integer :wait_queue_timeout => Float
wtimeoutMS=Integer { :write_concern => { :wtimeout => Integer }}
zlibCompressionLevel=Integer :zlib_compression_level => Integer

Note

The Ruby driver only fails connections when it receives a definitive signed response indicating that the server’s certificate has been revoked. Because of this, the driver does not recognize the tlsDisableCertificateRevocationCheck URI option. If this option is provided in a URI, it will be ignored.

Timeout Options

server_selection_timeout

When executing an operation, the number of seconds to wait for the driver to find an appropriate server to send an operation to. Defaults to 30.

A value of 0 means no timeout.

When an invalid value (e.g. a negative value or a non-numeric value) is passed via the URI option, the invalid input is ignored with a warning. When an invalid value is passed directly to Client via a Ruby option, Client construction fails with an error.

In replica set deployments, this timeout should be set to exceed the typical replica set election times in order for the driver to transparently handle primary changes. This timeout also allows the application and the database to be started simultaneously; the application will wait up to this much time for the database to become available.

If the application server is behind a reverse proxy, server selection timeout should be lower than the request timeout configured on the reverse proxy (for example, this applies to deployments on Heroku which has a fixed 30 second timeout in the routing layer). In development this value can be lowered to provide quicker failure when the server is not running.

socket_timeout

The number of seconds to wait for a socket read or write to complete on regular (non-monitoring) connections. Default is no timeout.

A value of 0 means no timeout.

When an invalid value (e.g. a negative value or a non-numeric value) is passed via the URI option, the invalid input is ignored with a warning. When an invalid value is passed directly to Client via a Ruby option, Client construction fails with an error.

This timeout should take into account both network latency and operation duration. For example, setting this timeout to 5 seconds will abort queries taking more than 5 seconds to execute on the server with Mongo::Error::SocketTimeoutError.

Note that even though by default there is no socket timeout set, the operating system may still time out read operations depending on its configuration. The keepalive settings are intended to detect broken network connections (as opposed to aborting operations simply because they take a long time to execute).

Note that if an operation is timed out by the driver due to exceeding the socket_timeout value, it is not aborted on the server. For this reason it is recommended to use max_time_ms option for potentially long running operations, as this will abort their execution on the server.

This option does not apply to monitoring connections.

connect_timeout

The number of seconds to wait for a socket connection to be established to a server. Defaults to 10.

This timeout is also used as both connect timeout and socket timeout for monitoring connections.

When using a mongodb+srv:// URI, this timeout is also used for SRV and TXT DNS lookups. Note that the timeout applies per lookup; due to DNS suffix search lists, multiple lookups may be performed as part of a single name resolution.

wait_queue_timeout

The number of seconds to wait for a connection in the connection pool to become available. Defaults to 10.

As of driver version 2.11, this timeout should be set to a value at least as large as connect_timeout because connection pool now fully establishes connections prior to returning them, which may require several network round trips.

max_time_ms

Specified as an option on a particular operation, the number of milliseconds to allow the operation to execute for on the server. Not set by default.

Consider using this option instead of a socket_timeout for potentially long running operations to be interrupted on the server when they take too long.

wtimeout

The number of milliseconds to wait for a write to be acknowledged by the number of servers specified in the write concern. Not set by default, which instructs the server to apply its default. This option can be set globally on the client or passed to individual operations under :write_concern.

TLS Connections

To connect to the MongoDB deployment using TLS:

  • Enable TLS connections in Mongo::Client.
  • Specify the client TLS certificate.
  • Specify the CA certificate to verify the server’s TLS certificate.

Note

When using JRuby, ECDSA certificates are not currently supported.

TLS vs SSL Option Names

All MongoDB server versions supported by the Ruby driver (2.6 and higher) only implement TLS. 2.6 and higher servers do not use SSL.

For historical reasons, the Ruby option names pertaining to TLS configuration use the ssl rather than the tls prefix. The next major version of the Ruby driver (3.0) will use the tls prefix for Ruby option names.

The URI option names use the tls prefix, with one exception: there is a ssl URI option that is deprecated and equivalent to the tls URI option.

Enable TLS Connections

TLS must be explicitly requested on the client side when the deployment requires TLS connections - there is currently no automatic detection of whether the deployment requires TLS.

To request TLS connections, specify the following client options when constructing a Mongo::Client:

  • The :ssl Ruby option.
  • The tls URI option.
  • The ssl URI option (deprecated).

Specify Client TLS Certificate

By default, MongoDB server will attempt to verify the connecting clients’ TLS certificates, which requires the clients to specify their TLS certificates when connecting. This can be accomplished via:

  • The :ssl_cert/:ssl_cert_object/:ssl_cert_string and :ssl_key/:ssl_key_object/:ssl_key_string/:ssl_key_pass_phrase Ruby options.
  • The tlsCertificateKeyFile URI option.

When using the Ruby options, the client TLS certificate and the corresponding private key may be provided separately. For example, if the certificate is stored in client.crt and the private key is stored in client.key, a Mongo::Client may be constructed as follows:

client = Mongo::Client.new(["localhost:27017"],
  ssl: true,
  ssl_cert: 'path/to/client.crt',
  ssl_key: 'path/to/client.key',
  ssl_ca_cert: 'path/to/ca.crt',
)

ssl_cert, ssl_cert_string, ssl_key and ssl_key_string Ruby options also permit the certificate and the key to be provided in the same file or string, respectively. The files containing both certificate and private key frequently have the .pem extension. When both certificate and the private key are provided in the same file or string, both the certifcate and the key options must be utilized, as follows:

client = Mongo::Client.new(["localhost:27017"],
  ssl: true,
  ssl_cert: 'path/to/client.pem',
  ssl_key: 'path/to/client.pem',
  ssl_ca_cert: 'path/to/ca.crt',
)

When using the URI option, the certificate and the key must be stored in a file and both must be stored in the same file. Example usage:

client = Mongo::Client.new(
  "mongodb://localhost:27017/?tls=true&tlsCertificateKeyFile=path%2fto%2fclient.pem&tlsCertificateKeyFile=path%2fto%2fca.crt")

Note

URI option values must be properly URI escaped. This applies, for example, to slashes in the paths.

Modifying SSLContext

It may be desirable to further configure TLS options in the driver, for example by enabling or disabling certain ciphers. Currently, the Ruby driver does not provide a way to do this when initializing a Mongo::Client.

However, the Ruby driver provides a way to set global “TLS context hooks” – these are user-provided Proc``s that will be invoked before any TLS socket connection and can be used to modify the underlying ``OpenSSL::SSL::SSLContext object used by the socket.

To set the TLS context hooks, add Proc``s to the ``Mongo.tls_context_hooks array. This should be done before creating any Mongo::Client instances. For example, in a Rails application this code could be placed in an initializer.

Mongo.tls_context_hooks.push(
  Proc.new { |context|
    context.ciphers = ["AES256-SHA"]
  }
)

# Only the AES256-SHA cipher will be enabled from this point forward

Every Proc in Mongo.tls_context_hooks will be passed an OpenSSL::SSL::SSLContext object as its sole argument. These Proc``s will be executed sequentially during the creation of every ``Mongo::Socket::SSL object.

It is possible to assign the entire array of hooks calling Mongo.tls_context_hooks=, but doing so will remove any previously assigned hooks. It is recommended to use the Array#push or Array#unshift methods to add new hooks.

It is also possible to remove hooks from Mongo.tls_context_hooks by storing a reference to the Procs somewhere else in the application, and then using Array#delete_if to remove the desired hooks.

Warning

TLS context hooks are global and will affect every instance of Mongo::Client. Any library that allows applications to enable these hooks should expose methods to modify the hooks (which can be called by the application) rather than automatically enabling the hooks when the library is loaded.

Further information on configuring MongoDB server for TLS is available in the MongoDB manual.

Using Intermediate Certificates

It is possible to use certificate chains for both the client and the server certificates. When using chains, the certificate authority parameter should be configured to contain the trusted root certificates only; the intermediate certificates, if any, should be provided in the server or client certificates by concatenating them after the leaf server and client certificates, respectively.

:ssl_cert and :ssl_cert_string Ruby options, as well as tlsCertificateKeyFile URI option, support certificate chains. :ssl_cert_object Ruby option, which takes an instance of OpenSSL::X509::Certificate, does not support certificate chains.

The Ruby driver performs strict X.509 certificate verification, which requires that both of the following fields are set in the intermediate certificate(s):

  • X509v3 Basic Constraints: CA: TRUE – Can sign certificates
  • X509v3 Key Usage: Key Cert Sign – Can sign certificates

More information about these flags can be found in this Stack Overflow question.

It is a common pitfall to concatenate intermediate certificates to the root CA certificates passed in tlsCAFile / ssl_ca_cert options. By doing so, the intermediate certificates are elevated to trusted status and are themselves not verified against the actual CA root. More information on this issue is available in this mailing list post.

Specify CA Certificate

The driver will attempt to verify the server’s TLS certificate by default, and will abort the connection if this verification fails. By default, the driver will use the default system root certificate store as the trust anchor. To specify the CA certificate that the server’s certificate is signed with, use:

  • The :ssl_ca_cert/:ssl_ca_cert_string/:ssl_ca_cert_object Ruby options
  • The tlsCAFile URI option.

If any of these options are given, the server’s certificate will be verified only against the specified CA certificate and the default system root certificate store will not be used.

To not perform server TLS certificate verification, which is not recommended, specify the ssl_verify: false Ruby option or the tlsInsecure=true URI option.

Specifying Multiple CA Certificates

The :ssl_ca_cert Ruby option and tlsCAFile URI option can be used with a file containing multiple certificates. All certificates thus referenced will become trust anchors.

The :ssl_ca_cert_object option takes an array of certificates, and thus can also be used to add multiple certificates as certificate authorities.

The :ssl_ca_cert_string option supports specifying only one CA certificate.

Warning

Intermediate certificates must not be provided in files specified by the CA certificate options. Doing so would elevate the intermediate certificates to the status of root certificates, rather than verifying intermediate certificates against the root certificates.

If intermediate certificates need to be used, specify them as part of the client or server TLS certificate files.

OCSP Verification

If the certificate provided by the server contains an OCSP endpoint URI, the driver will issue an OCSP request to the specified endpoint to verify the validity of the certificate.

The OCSP endpoint check may be disabled by setting the :ssl_verify_ocsp_endpoint Ruby option to false or by setting the tlsDisableOCSPEndpointCheck URI option to true when creating a client.

Note

OCSP endpoint checking is not currently performed when running on JRuby, since JRuby does not correctly expose the OCSP endpoint URI.

IPv4/IPv6 Connections

When a client is constructed with localhost as the host name, it will attempt an IPv4 connection only (i.e. if localhost resolves to 127.0.0.1 and ::1, the driver will only try to connect to 127.0.0.1).

When a client is constructed with hostnames other than localhost, it will attempt both IPv4 and IPv6 connections depending on the addresses that the hostnames resolve to. The driver respects the order in which getaddrinfo returns the addresses, and will attempt to connect to them sequentially. The first successful connection will be used.

The driver does not currently implement the Happy Eyeballs algorithm.

TCP Keepalive Configuration

Where allowed by system configuration and the Ruby language runtime, the driver enables TCP keepalive and, for each of the keepalive parameters listed below, sets the value of the respective parameter to the specified value if the system value can be determined and is higher than the listed driver value:

  • tcp_keepalive_time: 120 seconds
  • tcp_keepalive_intvl: 10 seconds
  • tcp_keepalive_cnt: 9 probes

Note

As of JRuby 9.2.14.0, JRuby does not implement the APIs required to set the keepalive parameters. When using JRuby, the driver will not be able to set the keepalive parameters and the system configuration will be in effect.

To use lower values, or to change the parameters in environments like JRuby that do not expose the required APIs, please adjust the parameters at the system level as described in the MongoDB Diagnostics FAQ keepalive section.

Connection Pooling

Mongo::Client instances have a connection pool per server that the client is connected to. The pool creates connections on demand to support concurrent MongoDB operations issued by the application. There is no thread-affinity for connections.

The client instance opens one additional connection per known server for monitoring the server’s state.

The size of each connection pool is capped at max_pool_size, which defaults to 5. When a thread in the application begins an operation on MongoDB, it tries to retrieve a connection from the pool to send that operation on. If there are some connections available in the pool, it checks out a connection from the pool and uses it for the operation. If there are no connections available and the size of the pool is less than the max_pool_size, a new connection will be created. If all connections are in use and the pool has reached its maximum size, the thread waits for a connection to be returned to the pool by another thread.

The number of seconds the thread will wait for a connection to become available is configurable. This setting, called wait_queue_timeout, is defined in seconds. If this timeout is reached, a Timeout::Error is raised. The default is 1 second.

As of driver version 2.11, the driver eagerly creates connections up to min_pool_size setting. Prior to driver version 2.11, the driver always created connections on demand. In all versions of the driver, once a connection is established, it will be kept in the pool by the driver as long as the pool size does not exceed min_pool_size.

Note that, if min_pool_size is set to a value greater than zero, the driver will establish that many connections to secondaries in replica set deployments even if the application does not perform secondary reads. The purpose of these connections is to provide faster failover when the primary changes.

Here is an example of estimating the number of connections a multi-threaded application will open: A client connected to a 3-node replica set opens 3 monitoring sockets. It also opens as many sockets as needed to support a multi-threaded application’s concurrent operations on each server, up to max_pool_size. If the application only uses the primary (the default), then only the primary connection pool grows and the total connections is at most 8 (5 connections for the primary pool + 3 monitoring connections). If the application uses a read preference to query the secondaries, their pools also grow and the total connections can reach 18 (5 + 5 + 5 + 3).

The default configuration for a Mongo::Client works for most applications:

client = Mongo::Client.new(["localhost:27017"])

Create this client once for each process, and reuse it for all operations. It is a common mistake to create a new client for each request, which is very inefficient and not what the client was designed for.

To support extremely high numbers of concurrent MongoDB operations within one process, increase max_pool_size:

client = Mongo::Client.new(["localhost:27017"], max_pool_size: 200)

Any number of threads are allowed to wait for connections to become available, and they can wait the default (1 second) or the wait_queue_timeout setting:

client = Mongo::Client.new(["localhost:27017"], wait_queue_timeout: 0.5)

When #close is called on a client by any thread, all connections are closed:

client.close

Note that when creating a client using the block syntax described above, the client is automatically closed after the block finishes executing.

Usage with Forking Servers

Note

Applications using Mongoid should follow Mongoid’s forking guidance. The guidance and sample code below is provided for applications using the Ruby driver directly.

When using the Mongo Ruby driver in a Web application with a forking web server such as Unicorn, Puma or Passenger, or when the application otherwise forks, each process should generally each have their own Mongo::Client instances. This is because:

  1. The background threads remain in the parent process and are not transfered to the child process.
  2. File descriptors like network sockets are shared between parent and child processes.

The driver attempts to detect client use from forked processes and reestablish network connections when such use is detected, alleviating the issue of file descriptor sharing.

If both parent and child processes need to perform MongoDB operations, it is recommended for each of the processes to create their own Mongo::Client instances. Specifically, the child process should create its own client instance and not use any of the instances that were created in the parent.

If the parent continues to perform MongoDB operations using an already established client instance after forking children, this client instance will continue to operate normally as long as no child uses it in any way. The child processes will not inherit any of the monitoring threads, and will not perform background operations on the client instance.

If the parent does not need to perform MongoDB operation after forking children (which is what typically happens in web applications), the parent should close all of the client instances it created to free up connections and cease background monitoring:

client.reconnect

Note

If the parent process performs operations on the Mongo client and does not close it, the parent process will continue consuming a connection slot in the cluster and will continue monitoring the cluster for as long as the parent remains alive.

Reconnecting Client Instances

When the Ruby driver is used in a web application, it is recommended to not create any Mongo::Client instances in the management processes (prior to the workers being forked), and instead only create client instances in the workers.

It is possible, although not recommended, to use the same Mongo::Client instances in parent and child processes. In order to do so, the instance must be closed and reconnected in the child process so that the background threads can be recreated:

client.close
client.reconnect

Note

This pattern should be used with Ruby driver version 2.6.2 or higher. Previous driver versions did not recreate monitoring threads when reconnecting.

Note

When closing and reconnecting the client instance in the child, due to file descriptor sharing, the parent process may experience network and monitoring errors.

Web servers generally provide hooks that can be used by applications to perform actions when the worker processes are forked. The recommended hooks to use are:

  • For Puma, before_fork to close clients in the parent process and on_worker_boot to reconnect in the child processes.
  • For Unicorn, before_fork to close clients in the parent process and after_fork to reconnect clients in the child processes.
  • For Passenger, starting_worker_process to reconnect clients in the child processes (Passenger does not appear to have a pre-fork hook).

This documentation does not provide example code for using the aforementioned hooks, because there is no standard for client instance management when using the Ruby driver directly. Mongoid documentation however provides examples for closing clients in the parent process and reconnecting clients in the child processes.

Troubleshooting

The client’s summary method returns the current state of the client, including servers that the client is monitoring and their state. If any of the servers are not being monitored, this is indicated by the NO-MONITORING flag.

A normally operating client will produce a summary similar to the following:

client.summary
=> "#<Client cluster=#<Cluster
  topology=ReplicaSetWithPrimary[localhost:14420,localhost:14421,localhost:14422,localhost:14423,name=ruby-driver-rs,v=1,e=7fffffff000000000000001f]
  servers=[#<Server address=localhost:14420 PRIMARY replica_set=ruby-driver-rs pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>,
    #<Server address=localhost:14421 SECONDARY replica_set=ruby-driver-rs pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>,
    #<Server address=localhost:14422 SECONDARY replica_set=ruby-driver-rs pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>,
    #<Server address=localhost:14423 ARBITER replica_set=ruby-driver-rs>]>>"

A client that is missing background threads will produce a summary similar to the following:

client.summary
=> "#<Client cluster=#<Cluster
  topology=ReplicaSetWithPrimary[localhost:14420,localhost:14421,localhost:14422,localhost:14423,name=ruby-driver-rs,v=1,e=7fffffff000000000000001f]
  servers=[#<Server address=localhost:14420 PRIMARY replica_set=ruby-driver-rs NO-MONITORING pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>,
    #<Server address=localhost:14421 SECONDARY replica_set=ruby-driver-rs NO-MONITORING pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>,
    #<Server address=localhost:14422 SECONDARY replica_set=ruby-driver-rs NO-MONITORING pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>,
    #<Server address=localhost:14423 ARBITER replica_set=ruby-driver-rs>]>>"

Retryable Reads

The driver implements two mechanisms for retrying reads: modern and legacy. As of driver version 2.9.0, the modern mechanism is used by default, and the legacy mechanism is deprecated.

Modern Retryable Reads

When the modern mechanism is used, read operations are retried once in the event of a network error, a “not master” error, or a “node is recovering” error. The following operations are covered:

When an operation returns a cursor, only the initial read command can be retried. getMore operations on cursors are not retried by driver version 2.9.0 or newer. Additionally, when a read operation is retried, a new server for the operation is selected; this may result in the retry being sent to a different server from the one which received the first read.

The behavior of modern retryable reads is covered in detail by the retryable reads specification.

Note that the modern retryable reads can only be used with MongoDB 3.6 and higher servers. When used with MongoDB 3.4 and lower servers, Ruby driver version 2.9.0 and higher will not retry reads by default - the application must explicitly request legacy retryable reads by setting the retry_reads: false client option or using retryReads=false URI option.

Legacy Retryable Reads

The legacy read retry behavior of the Ruby driver is available by setting the retry_reads: false client option or passing the retryReads=false URI option to the client.

When using legacy read retry behavior, the number of retries can be set by specifying the max_read_retries client option. When using driver version 2.9.0 or higher, the set of operations which would be retried with legacy retryable reads is identical to the one described above for modern retryable reads. In older driver versions the behavior of legacy retryable writes was different in that some of the operations were not retried.

As of driver version 2.9.0, legacy read retries perform server selection prior to retrying the operation, as modern retriable writes do. In older driver versions read retries would be sent to the same server which the initial read was sent to.

Disabling Retryable Reads

To disable all read retries, set the following client options: retry_reads: false, max_read_retries: 0.

Retryable Writes

The driver implements two mechanisms for retrying writes: modern and legacy. As of driver version 2.9.0, the modern mechanism is used by default on servers that support it, and the legacy mechanism is deprecated and disabled by default on all server versions.

The following write methods used in day-to-day operations on collections are subject to write retries:

  • collection#insert_one
  • collection#update_one
  • collection#delete_one
  • collection#replace_one
  • collection#find_one_and_update
  • collection#find_one_and_replace
  • collection#find_one_and_delete
  • collection#bulk_write (for all single statement ops, i.e. not for update_many or delete_many)

Modern Retryable Writes

The modern mechanism will retry failing writes once when the driver is connected to a MongoDB 3.6 or higher replica set or a sharded cluster, because they require an oplog on the serer. Modern mechanism will not retry writes when the driver is connected to a standalone MongoDB server or server versions 3.4 or older.

The following errors will cause writes to be retried:

  • Network errors including timeouts
  • “not master” errors
  • “node is recovering” errors

Prior to retrying the write the driver will perform server selection, since the server that the original write was sent to is likely no longer usable.

Legacy Retryable Writes

If modern retryable writes mechanism is disabled by setting the client option retry_writes: false or by using the retryWrites=false URI option, the driver will utilize the legacy retryable writes mechanism. The legacy mechanism retries writes on the same operations as the modern mechanism. By default the legacy mechanism retries once, like the modern mechanism does; to change the number of retries, set :max_write_retries client option.

The difference between legacy and modern retry mechanisms is that the legacy mechanism retries writes for a different set of errors compared to the modern mechanism, and specifically does not retry writes when a network timeout is encountered.

Disabling Retryable Writes

To disable all write retries, set the following client options: retry_writes: false, max_write_retries: 0.

Logging

You can either use the default global driver logger or set your own. To set your own:

Mongo::Logger.logger = other_logger

See the Ruby Logger documentation for more information on the default logger API and available levels.

Changing the Logger Level

To change the logger level:

Mongo::Logger.logger.level = Logger::WARN

For more control, a logger can be passed to a client for per-client control over logging.

my_logger = Logger.new(STDOUT)
Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'test', :logger => my_logger )

Truncation

The default logging truncates logs at 250 characters by default. To turn this off pass an option to the client instance.

Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'test', :truncate_logs => false )

Compression

To use wire protocol compression, at least one compressor must be explicitly requested using either the :compressors Ruby option or the compressors URI option. If no compressors are explicitly requested, the driver will not use compression, even if the required dependencies for one or more compressors are present on the system.

The driver chooses the first compressor of the ones requested that is also supported by the server. The driver currently supports zstd, snappy and zlib compressors. zstd compressor is recommended as it produces the highest compression at the same CPU consumption compared to the other compressors. For maximum server compatibility all three compressors can be specified, e.g. as compressors: ["zstd", "snappy", "zlib"].

zstd compressor requires the zstd-ruby library to be installed. snappy compressor requires the snappy library to be installed. If zstd or snappy compression is requested, and the respective library is not loadable, the driver will raise an error during Mongo::Client creation. zlib compression requires the zlib standard library extension to be present.

The server support for various compressors is as follows:

  • zstd requires and is enabled by default in MongoDB 4.2 or higher.
  • snappy requires MongoDB 3.4 or higher and is enabled by default in MongoDB 3.6 or higher.
  • zlib requires MongoDB 3.6 or higher and is enabled by default in MongoDB 4.2 and higher.

Server API Parameters

Starting with MongoDB 5.0, applications can request that the server behaves in accordance with a particular server API version.

Server API parameters can be specified via the :server_api option to Client. These parameters cannot be provided via a URI.

Currently the only defined API version is "1". It can be requested as follows:

client = Mongo::Client.new(['localhost'], server_api: {version: "1"})

MongoDB server defines API versions as string values. For convenience, if the API version is provided as an integer, the Ruby driver will stringify it and send it to the server as a string:

client = Mongo::Client.new(['localhost'], server_api: {version: 1})

Note that the server may define API versions that are not stringified integers. Applications must not assume that all legal API versions can be expressed as integers.

When a particular API version is requested, operations which are part of that API version behave as specified in that API version. Operations which are not part of the specified API version behave as they would had the API version not been specified at all. Operations whose behavior is subject to the configured API version are commands including command arguments, queries, aggregation pipeline stages and arguments.

Applications may request that the server rejects all operations which are not part of the specified API version by setting the :strict option:

client = Mongo::Client.new(['localhost'], server_api: {version: "1", strict: true})

For example, since the :tailable option is not part of the server API version 1, the following query would fail:

client = Mongo::Client.new(['localhost'], server_api: {version: "1", strict: true})
client['collection'].find({}, tailable: true)
# => Mongo::Error::OperationFailure (BSON field 'FindCommand.tailable' is not allowed with apiStrict:true. (323) (on localhost:27017, modern retry, attempt 1))

Applications may request that the server rejects all operations which are deprecated in the specified API version by setting the :deprecation_errors option:

client = Mongo::Client.new(['localhost'], server_api: {version: "1", deprecation_errors: true})

Note that, as of this writing, there are no deprecated operations in API version "1".

If the server API parameters have been defined on a Client object, they will be sent by the client as part of each [*] executed operation.

[*]getMore commands and commands in transactions do not accept API parameters, thus the driver will not send them in these cases.

MongoDB servers prior to 5.0 do not recognize the API parameters, and will produce a variety of errors should the application configure them. The Ruby driver will send the API parameters to all MongoDB 3.6 and newer servers, but the API parameters should only be configured when the application is communicating with MongoDB 5.0 or newer servers. The API parameters cannot be sent to MongoDB 3.4 and older servers that use the legacy wire protocol; if an application configures the API parameters and connects to MongoDB 3.4 or older servers, the driver will produce an error on every operation.

The command helper permits the application to send manually constructed commands to the server. If the client is not configured with server API parameters, the command helper may be used to issue commands with API parameters:

client.database.command(
  ping: 1,
  apiVersion: "1",
  apiStrict: false,
  apiDeprecationErrors: false,
)

If the client is configured with server API parameters, the command helper may not be used to issue commands with server API parameters. This includes the case when the server API parameters provided to the client and to the command helper are identical. If a client is constructed with server API parameters, to send different API parameters (or none at all) a new client must be constructed, either from scratch or using the with method.

The server API parameters may only be specified on the client level. They may not be specified on the database, collection, session, transaction or individual operation level.

Development Configuration

Driver’s default configuration is suitable for production deployment. In development, some settings can be adjusted to provide a better developer experience.

  • :server_selection_timeout: set this to a low value (e.g., 1) if your MongoDB server is running locally and you start it manually. A low server selection timeout will cause the driver to fail quickly when there is no server running.

Production Configuration

Please consider the following when deploying an application using the Ruby driver in production:

  • As of driver version 2.11, the :min_pool_size client option is completely respected - the driver will create that many connections to each server identified as a standalone, primary or secondary. In previous driver versions the driver created connections on demand. Applications using :min_pool_size will see an increase in the number of idle connections to all servers as of driver version 2.11, and especially to secondaries in replica set deployments and to nodes in sharded clusters.
  • If the application is reverse proxied to by another web server or a load balancer, server_selection_timeout should generally be set to a lower value than the reverse proxy’s read timeout. For exampe, Heroku request timeout is 30 seconds and is not configurable; if deploying a Ruby application using MongoDB to Heroku, consider lowering server selection timeout to 20 or 15 seconds.