Docs Menu

Docs HomeDevelop ApplicationsMongoDB Manual

Retryable Writes

On this page

  • Prerequisites
  • Retryable Writes and Multi-Document Transactions
  • Enabling Retryable Writes
  • Retryable Write Operations
  • Behavior

Retryable writes allow MongoDB drivers to automatically retry certain write operations a single time if they encounter network errors, or if they cannot find a healthy primary in the replica set or sharded cluster. [1]

Retryable writes have the following requirements:

Supported Deployment Topologies
Retryable writes require a replica set or sharded cluster, and do not support standalone instances.
Supported Storage Engine
Retryable writes require a storage engine supporting document-level locking, such as the WiredTiger or in-memory storage engines.
3.6+ MongoDB Drivers

Clients require MongoDB drivers updated for MongoDB 3.6 or greater:

Java 3.6+

Python 3.6+

C 1.9+

Go 1.8+

C# 2.5+

Node 3.0+

Ruby 2.5+

Rust 2.1+

Swift 1.2+

Perl 2.0+

PHPC 1.4+

Scala 2.2+

C++ 3.6.6+

MongoDB Version
The MongoDB version of every node in the cluster must be 3.6 or greater, and the featureCompatibilityVersion of each node in the cluster must be 3.6 or greater. See setFeatureCompatibilityVersion for more information on the featureCompatibilityVersion flag.
Write Acknowledgment
Write operations issued with a Write Concern of 0 are not retryable.

New in version 4.0.

The transaction commit and abort operations are retryable write operations. If the commit operation or the abort operation encounters an error, MongoDB drivers retry the operation a single time regardless of whether retryWrites is set to false.

The write operations inside the transaction are not individually retryable, regardless of value of retryWrites.

For more information on transactions, see Transactions.

MongoDB Drivers
Drivers compatible with MongoDB 4.2 and higher enable Retryable Writes by default. Earlier drivers require the retryWrites=true option. The retryWrites=true option can be omitted in applications that use drivers compatible with MongoDB 4.2 and higher.

To disable retryable writes, applications that use drivers compatible with MongoDB 4.2 and higher must include retryWrites=false in the connection string.
mongosh

Retryable writes are enabled by default in mongosh. To disable retryable writes, use the --retryWrites=false command line option:

mongosh --retryWrites=false
mongo

Retryable writes are disabled by default in the legacy mongo shell. To enable retryable writes, use the --retryWrites=true command line option:

mongo --retryWrites=true

The following write operations are retryable when issued with acknowledged write concern; e.g., Write Concern cannot be {w: 0}.

Note

The write operations inside the transactions are not individually retryable.

Methods
Descriptions
Insert operations.
Single-document update operations. [1]
Single document delete operations.
findAndModify operations. All findAndModify operations are single document operations.

db.collection.bulkWrite() with the following write operations:

Bulk write operations that only consist of the single-document write operations. A retryable bulk operation can include any combination of the specified write operations but cannot include any multi-document write operations, such as updateMany.
Bulk write operations that only consist of the single-document write operations. A retryable bulk operation can include any combination of the specified write operations but cannot include any multi-document write operations, such as update which specifies true for the multi option.

Note

Updates to Shard Key Values

Starting in MongoDB 4.2, you can update a document's shard key value (unless the shard key field is the immutable _id field) by issuing single-document update/findAndModify operations either as a retryable write or in a transaction. For details, see Change a Document's Shard Key Value.

[1](1, 2) MongoDB 4.2 will retry certain single-document upserts (update with upsert: true and multi: false) that encounter a duplicate key exception. See Duplicate Key Errors on Upsert for conditions.Prior to MongoDB 4.2, MongoDB would not retry upsert operations that encountered a duplicate key error.

MongoDB retryable writes make only one retry attempt. This helps address transient network errors and replica set elections, but not persistent network errors.

If the driver cannot find a healthy primary in the destination replica set or sharded cluster shard, the drivers wait serverSelectionTimeoutMS milliseconds to determine the new primary before retrying. Retryable writes do not address instances where the failover period exceeds serverSelectionTimeoutMS.

Warning

If the client application becomes temporarily unresponsive for more than the localLogicalSessionTimeoutMinutes after issuing a write operation, there is a chance that when the client applications starts responding (without a restart), the write operation may be retried and applied again.

MongoDB 4.2 will retry single-document upsert operations (i.e upsert : true and multi : false) that fail due to a duplicate key error only if the operation meets all of the following conditions:

  • The target collection has a unique index that caused the duplicate key error.

  • The update match condition is either:

    • A single equality predicate

      { "fieldA" : "valueA" },

      or

    • a logical AND of equality predicates

      { "fieldA" : "valueA", "fieldB" : "valueB" }

  • The set of fields in the unique index key pattern matches the set of fields in the update query predicate.

  • The update operation does not modify any of the fields in the query predicate.

The following table contains examples of upsert operations that the server can or cannot retry on a duplicate key error:

Unique Index Key Pattern
Update Operation
Retryable
{ _id : 1 }
db.collName.updateOne(
{ _id : ObjectId("1aa1c1efb123f14aaa167aaa") },
{ $set : { fieldA : 25 } },
{ upsert : true }
)
Yes
{ fieldA : 1 }
db.collName.updateOne(
{ fieldA : { $in : [ 25 ] } },
{ $set : { fieldB : "someValue" } },
{ upsert : true }
)
Yes
{
fieldA : 1,
fieldB : 1
}
db.collName.updateOne(
{ fieldA : 25, fieldB : "someValue" },
{ $set : { fieldC : false } },
{ upsert : true }
)
Yes
{ fieldA : 1 }
db.collName.updateOne(
{ fieldA : { $lte : 25 } },
{ $set : { fieldC : true } },
{ upsert : true }
)

No

The query predicate on fieldA is not an equality

{ fieldA : 1 }
db.collName.updateOne(
{ fieldA : { $in : [ 25 ] } },
{ $set : { fieldA : 20 } },
{ upsert : true }
)

No

The update operation modifies fields specified in the query predicate.

{ _id : 1 }
db.collName.updateOne(
{ fieldA : { $in : [ 25 ] } },
{ $set : { fieldA : 20 } },
{ upsert : true }
)

No

The set of query predicate fields (fieldA) does not match the set of index key fields (_id).

{ fieldA : 1 }
db.collName.updateOne(
{ fieldA : 25, fieldC : true },
{ $set : { fieldD : false } },
{ upsert : true }
)

No

The set of query predicate fields (fieldA, fieldC) does not match the set of index key fields (fieldA).

Prior to MongoDB 4.2, MongoDB retryable writes did not support retrying upserts which failed due to duplicate key errors.

New in version 3.6.3.

The serverStatus command, and its mongosh shell helper db.serverStatus() includes statistics on retryable writes in the transactions section.

The official MongoDB 4.2-series drivers enable retryable writes by default. Applications which write to the local database will encounter write errors upon upgrading to 4.2-series drivers unless retryable writes are explicitly disabled.

To disable retryable writes, specify retryWrites=false in the connection string for the MongoDB cluster.

←  Bulk Write OperationsRetryable Reads →