Navigation

Creating a Client

Using Mongo::Client

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

To create a client to a standalone server, provide one host in the seed list. Optionally, you can force the cluster topology to be standalone without going through the auto-discovery steps.

Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'mydb')
Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'mydb', :connect => :direct)
Mongo::Client.new('mongodb://127.0.0.1:27017/mydb')

To connect to a replica set, pass one or more hosts and the replica set name. The driver’s auto-discovery feature finds all members of the replica set if they are not all provided.

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

To create a client to a sharded cluster, pass one or more mongos hosts. The auto-discovery feature can determine that the servers are mongos instances, but if you would like to bypass the auto-discovery, pass the sharded option to the client.

Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'mydb')
Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'mydb', :connect => :sharded)
Mongo::Client.new('mongodb://127.0.0.1:27017/mydb?connect=sharded')

The URI parser in the driver can also accept the protocol mongodb+srv as a logical pre-processing step before it considers the connection string and other options. In this protocol, the comma separated list of host names is replaced with a single host name. The format is:

Mongo::Client.new('mongodb+srv://test5.test.build.mongodb.cc')

Client Options

A number of different options can be passed to a Mongo::Client to configure driver behavior, either by providing them in the options hash to the constructor or by providing them in the URI.

Since the URI options are required in camel case, which is not the Ruby standard, the following table shows the option in the URI and its corresponding option if passed to the constructor in Ruby.

Note

The options passed directly should be symbols.

The 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 Options Conversions

URI Option Ruby Option
appName=String :app_name => String
authMechanism=String :auth_mech => Symbol
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>

Specified as a comma-separated list. Note that the Ruby driver only supports zlib compression; however, other drivers may support snappy. For maximum compatibility with drivers, specify "snappy,zlib"; if compatibility with other drivers is not a concern, specify "zlib". Compression is not enabled by default and when using MongoDB 4.0 and earlier, so zlib compression must be manually enabled on the server in order for the Ruby driver to compress wire protocol data.

connect=String :connect => Symbol
connectTimeoutMS=Integer :connect_timeout => Float
fsync=Boolean { :write => { :fsync => true|false }}
heartbeatFrequencyMS=Integer :heartbeat_frequency => Float
journal=Boolean { :write => { :j => true|false }}
localThresholdMS=Integer :local_threshold => Float
maxIdleTimeMS=Integer :max_idle_time => Float
maxStalenessSeconds=Integer :max_staleness => Float
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
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
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 => { :w => Integer|String }}
waitQueueTimeoutMS=Integer :wait_queue_timeout => Float
wtimeoutMS=Integer { :write => { :wtimeout => Float }}
zlibCompressionLevel=Integer :zlib_compression_level => Integer

Ruby Options

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. Hash none
:auth_source Specifies the authentication source. String For MongoDB 2.6 and later: admin if credentials are supplied, otherwise the current database
:compressors A list of potential compressors to use, in order of preference. The driver chooses the first compressor that is also supported by the server. Currently the driver only supports ‘zlib’. Array<String> none
:connect Overrides the auto-discovery feature of the driver 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. Float 10 seconds
:database The name of the database to connect to. String admin
: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 on mongos query failures. 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. Keys in the hash are :mode and :tag_sets.

{ :read =>
  { :mode => :secondary,
    :tag_sets => [ "berlin" ]
  }
}
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
: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. Float 5 seconds
:ssl Tell the client to connect to the servers via SSL. 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 The certificate file path used to identify the connection against MongoDB. This option, if present, takes precedence over the values of :ssl_cert_string and :ssl_cert_object. String none
:ssl_cert_object The OpenSSL::X509::Certificate used to identify the connection against MongoDB. OpenSSL::X509::Certificate none
:ssl_cert_string A string containing the PEM-encoded certificate used to identify the connection against MongoDB. This option, if present, takes precedence over the value of :ssl_cert_object. 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 validation and hostname verification. Note that the decision of whether to validate certificates will be overridden if :ssl_verify_certificate is set, and the decision of whether to validate hostnames will be overridden if :ssl_verify_hostname is set. Boolean true
:ssl_verify_certificate Whether to perform peer certificate validation. This setting overrides :ssl_verify with respect to whether certificate validation is performed. Boolean true
:ssl_verify_hostname Whether to perform peer hostname validation. This setting overrides :ssl_verify with respect to whether hostname 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 1
:write

Specifies write concern options as a Hash. Keys in the hash can be :w, :wtimeout, :j, :fsync.

{ :write => { :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

Details on Timeout Options

connect_timeout
On initialization of a connection to a server, this setting is the number of seconds to wait to connect before raising an exception. This timeout is also used when monitor threads ping their servers. The default is 10 seconds. See the socket timeout for monitoring specification for further explanation.
socket_timeout
The number of seconds to wait for an operation to execute on a socket before raising a timeout exception. It should take into account network latency and operation duration. The default is no value; the default is effectively infinity. Please consider using max_time_ms per-operation instead, as the socket_timeout does not stop the operation on the server; a long-running operation will continue to run on the server, beyond a socket timeout being reached. See the socket timeout for monitoring specification documentation for further information relating to server discovery and monitoring.
server_selection_timeout
The number of seconds to wait for the driver to find an appropriate server to which an operation can be sent before raising an exception. Defaults to 30. It should take the speed of elections during a failover into account. See the serverSelectionTimeoutMS specification for further information.
local_threshold
The maximum latency in seconds between the nearest server and the servers that can be considered available to send an operation to. Defaults to 0.015.

Note

This is not the latency window between the driver and a server, but rather the latency between the nearest server and other servers. See the localThresholdMS specification.

wait_queue_timeout
The number of seconds to wait for a connection in the connection pool to become available. You should consider increasing this number if you are seeing many Timeout errors while using many threads or when operations are long-running. Defaults to 1 second.
max_time_ms
Specified as an option on a particular operation. It defines a cumulative time limit in milliseconds for processing operations on a cursor. Consider using this option instead of a socket_timeout, if the operation should be interrupted on the server. See the CRUD specification for details on operations that support this option.

TCP Keepalive Configuration

The driver sets TCP keepalive by default. The following default values are also set if the system value can be determined and if the driver default value is less than the system value.

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

Please see the MongoDB Diagnostics FAQ keepalive section for instructions on setting these values at the system level.

Details on 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.

The driver currently does not eagerly create connections, regardless of min_pool_size setting. However, 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.

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

Usage with Forking Servers

When using the Mongo Ruby driver with a forking web server such as Unicorn, worker processes 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.

It is recommended to not create any Mongo::Client instances prior to the fork. If the parent process needs to perform operations on the MongoDB database, reset the client in an after_fork handler which is defined in unicorn.rb:

after_fork do |server, worker|
  $client.close
  $client.reconnect
end

The above code assumes your Mongo::Client instance is stored in the $client global variable. It also keeps the MongoDB connection in the parent process around, and this connection will continue to consume resources such as a connection slot. If the parent process performs one time operation(s) on MongoDB and does not need its MongoDB connection once workers are forked, the following code will close the connection in the parent:

before_fork do |server, worker|
  $client.close
end

after_fork do |server, worker|
  $client.reconnect
end

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: 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.

Details on Retryable Writes

The driver implements two mechanisms for retrying writes: modern and legacy. The modern mechanism is used when the driver connects to a MongoDB 3.6+ replica set or a sharded cluster, and the retry_writes client option is not set to false. This mechanism retries writes once on network errors (timeout, connection reset, etc.) as well as transient errors resulting from servers being unavailable due to initialization, shutdown, replica set elections and similar events (the corresponding errors are not master, node is recovering, etc.). Prior to retrying the write the driver attempts to select a new primary, since the server that was previously used is likely to no longer be usable.

The legacy mechanism is used when the driver connects to MongoDB 3.4 or earlier clusters, or to MongoDB 3.6 or later standalone servers, or when retry_writes client option is set to false. In this mode the driver will retry write operations once due to transient errors resulting from servers being unavailable due to initialization, shutdown, replica set elections and similar events, but will not retry writes on network errors like timeouts.

Note that writes are always retried on transient server status-related errors like “not master” and “node is recovering”, regardless of what retry_writes option is set to.

The following write methods used in day-to-day operations on collections will be automatically retried:

  • 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)

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 )

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:

  • The driver has a setting for minimum connection pool size. This setting results in the driver creating the specified number of connection objects but each connection object creates sockets and actually connects to the server on demand. Setting a minimum connection pool size will keep up to that many network connections to a server alive once they are established. This behavior may change in a future version of the driver (RUBY-1605).