Read Preference

Read preference describes how MongoDB clients route read operations to the members of a replica set.

Read operations to a replica set. Default read preference routes the read to the primary. Read preference of ``nearest`` routes the read to the nearest member.

By default, an application directs its read operations to the primary member in a replica set (i.e. read preference mode “primary”). But, clients can specify a read preference to send read operations to secondaries.

Read preference consists of the read preference mode, and optionally, a tag set and maxStalenessSeconds.

Important

Exercise care when specifying read preferences: Modes other than primary may return stale data because with asynchronous replication, data in the secondary may not reflect the most recent write operations. [1]

Note

The read preference does not affect the visibility of data; i.e. clients can see the results of writes before they are acknowledged or have propagated to a majority of replica set members:

Use Cases

Indications

The following are common use cases for using non-primary read preference modes:

  • Running systems operations that do not affect the front-end application.

    Note

    Read preferences aren’t relevant to direct connections to a single mongod instance. However, in order to perform read operations on a direct connection to a secondary member of a replica set, you must set a read preference, such as secondary.

  • Providing local reads for geographically distributed applications.

    If you have application servers in multiple data centers, you may consider having a geographically distributed replica set and using a non primary or nearest read preference. This allows the client to read from the lowest-latency members, rather than always reading from the primary.

  • Maintaining availability during a failover.

    Use primaryPreferred if you want an application to read from the primary under normal circumstances, but to allow stale reads from secondaries when the primary is unavailable. This provides a “read-only mode” for your application during a failover.

Counter-Indications

In general, do not use secondary and secondaryPreferred to provide extra capacity for reads, because:

  • All members of a replica have roughly equivalent write traffic; as a result, secondaries will service reads at roughly the same rate as the primary.

  • Replication is asynchronous and there is some amount of delay between a successful write operation and its replication to secondaries. Reading from a secondary can return stale data; reading from different secondaries may result in non-monotonic reads.

    Changed in version 3.6: Starting in MongoDB 3.6, clients can use Client Sessions and Causal Consistency Guarantees to ensure monotonic reads.

  • Distributing read operations to secondaries can compromise availability if any members of the set become unavailable because the remaining members of the set will need to be able to handle all application requests.

Sharding increases read and write capacity by distributing read and write operations across a group of machines, and is often a better strategy for adding capacity.

See Server Selection Algorithm for more information about the internal application of read preferences.

Read Preference Modes

Important

All read preference modes except primary may return stale data because secondaries replicate operations from the primary with some delay. [1] Ensure that your application can tolerate stale data if you choose to use a non-primary mode.

MongoDB drivers support five read preference modes.

Read Preference Mode Description
primary Default mode. All operations read from the current replica set primary.
primaryPreferred In most situations, operations read from the primary but if it is unavailable, operations read from secondary members.
secondary All operations read from the secondary members of the replica set.
secondaryPreferred In most situations, operations read from secondary members but if no secondary members are available, operations read from the primary.
nearest Operations read from member of the replica set with the least network latency, irrespective of the member’s type.

Tag Set

If a replica set member or members are associated with tags, you can specify a tag set (array of tag specification documents) in the read preference to target those members.

To configure a member with tags, set members[n].tags to a document that contains the tag name and value pairs. The value of the tags must be a string.

{ "<tag1>": "<string1>", "<tag2>": "<string2>",... }

Then, you can include a tag set in the read preference to target tagged members. A tag set is an array of tag specification documents, where each tag specification document contains one or more tag/value pairs.

[ { "<tag1>": "<string1>", "<tag2>": "<string2>",... }, ... ]

To find replica set members, MongoDB tries each document in succession until a match is found. See Order of Tag Matching for details.

For example, if a secondary member has the following members[n].tags:

{ "region": "South", "datacenter": "A" }

Then, the following tags sets can direct read operations to the aforementioned secondary (or other members with the same tags):

[ { "region": "South", "datacenter": "A" }, { } ]     // Find members with both tag values. If none are found, read from any eligible member.
[ { "region": "South" }, { "datacenter": "A" }, { } ] // Find members with the specified region tag. Only if not found, then find members with the specified datacenter tag. If none are found, read from any eligible member.
[ { "datacenter": "A" }, { "region": "South" }, { } ] // Find members with the specified datacenter tag. Only if not found, then find members with the specified region tag. If none are found, read from any eligible member.
[ { "region": "South" }, { } ]                        // Find members with the specified region tag value. If none are found, read from any eligible member.
[ { "datacenter": "A" }, { } ]                        // Find members with the specified datacenter tag value. If none are found, read from any eligible member.
[ { } ]                                               // Find any eligible member.

Order of Tag Matching

If the tag set lists multiple documents, MongoDB tries each document in succession until a match is found. Once a match is found, that tag specification document is used to find all eligible matching members, and the remaining tag specification documents are ignored. If no members match any of the tag specification documents, the read operation returns with an error.

Tip

To avoid an error if no members match any of the tag specifications, you can add an empty document { } as the last element of the tag set to read from any eligible member.

For example, consider the following tag set with three tag specification documents:

[ { "region": "South", "datacenter": "A" },  { "rack": "rack-1" }, { } ]

First, MongoDB tries to find members tagged with both "region": "South" and "datacenter": "A".

{ "region": "South", "datacenter": "A" }
  • If a member is found, the remaining tag specification documents are not considered. Instead, MongoDB uses this tag specification document to find all eligible members.

  • Else, MongoDB tries to find members with the tags specified in the second document

    { "rack": "rack-1" }
    
    • If a member is found tagged, the remaining tag specification document is not considered. Instead, MongoDB uses this tag specification document to find all eligible members.

    • Else, the third document is considered.

      { }
      

      The empty document matches any eligible member.