diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h
index 7750ce8f1e5..899b02a1d43 100644
--- a/src/mongo/db/operation_context.h
+++ b/src/mongo/db/operation_context.h
@@ -310,6 +310,16 @@ public:
         return _writesAreReplicated;
     }
 
+    // TODO(Jack) In a real implementation this won't be on the opCtx, should be threaded through
+    // the transaction API instead.
+    bool optedIntoExclusiveCommit() const {
+        return _optedIntoExclusiveCommit;
+    }
+
+    void setOptedIntoExclusiveCommit() {
+        _optedIntoExclusiveCommit = true;
+    }
+
     /**
      * Returns true if the operation is running lock-free.
      */
@@ -827,6 +837,9 @@ private:
     // destructs lock helpers out of order.
     int _lockFreeReadOpCount = 0;
 
+    // TODO(Jack) Just for the POC
+    bool _optedIntoExclusiveCommit = false;
+
     // If true, this OpCtx will get interrupted during replica set stepUp and stepDown, regardless
     // of what locks it's taken.
     AtomicWord<bool> _alwaysInterruptAtStepDownOrUp{false};
diff --git a/src/mongo/db/transaction/transaction_api.cpp b/src/mongo/db/transaction/transaction_api.cpp
index 30a8ce585c3..dad2d523424 100644
--- a/src/mongo/db/transaction/transaction_api.cpp
+++ b/src/mongo/db/transaction/transaction_api.cpp
@@ -448,6 +448,9 @@ ExecutorFuture<BSONObj> SEPTransactionClient::_runCommand(const DatabaseName& db
     auto opCtxFactory = CancelableOperationContextFactory(_hooks->getTokenForCommand(), _executor);
 
     auto cancellableOpCtx = opCtxFactory.makeOperationContext(&cc());
+    if (_hooks->optedIntoExclusiveCommit()) {
+        cancellableOpCtx->setOptedIntoExclusiveCommit();
+    }
 
     primeInternalClient(&cc());
 
@@ -1093,6 +1096,8 @@ void Transaction::_primeTransaction(OperationContext* opCtx) {
         _opDeadline = opCtx->getDeadline();
     }
 
+    _optedIntoExclusiveCommit = opCtx->optedIntoExclusiveCommit();
+
     LOGV2_DEBUG(5875901,
                 3,
                 "Started internal transaction",
diff --git a/src/mongo/db/transaction/transaction_api.h b/src/mongo/db/transaction/transaction_api.h
index 17a8c3b3b73..0988f423622 100644
--- a/src/mongo/db/transaction/transaction_api.h
+++ b/src/mongo/db/transaction/transaction_api.h
@@ -466,6 +466,10 @@ public:
      */
     CancellationToken getTokenForCommand() const;
 
+    bool optedIntoExclusiveCommit() const {
+        return _optedIntoExclusiveCommit;
+    }
+
     /**
      * Returns the latest operationTime returned by a command in this transaction.
      */
@@ -544,6 +548,7 @@ private:
     BSONObj _writeConcern;
     BSONObj _readConcern;
     APIParameters _apiParameters;
+    bool _optedIntoExclusiveCommit{false};
     ExecutionContext _execContext;
 
     // Protects the members below that are accessed by the TxnHooks, which are called by the user's
@@ -580,6 +585,10 @@ public:
         _internalTxn.processResponse(reply);
     }
 
+    bool optedIntoExclusiveCommit() const {
+        return _internalTxn.optedIntoExclusiveCommit();
+    }
+
     /**
      * Called to get the cancellation token to be used for a command in the TransactionClient.
      */
diff --git a/src/mongo/s/transaction_router.cpp b/src/mongo/s/transaction_router.cpp
index 8eeaca38cd1..9fcc01e486a 100644
--- a/src/mongo/s/transaction_router.cpp
+++ b/src/mongo/s/transaction_router.cpp
@@ -228,6 +228,74 @@ BSONObj sendCommitDirectlyToShards(OperationContext* opCtx, const std::vector<Sh
     return lastResult;
 }
 
+BSONObj sendExclusiveCommit(OperationContext* opCtx,
+                            const std::vector<ShardId>& abortShards,
+                            const ShardId& exclusiveShard) {
+    // Assemble requests.
+    std::vector<AsyncRequestsSender::Request> requests;
+
+    // Commit on just the exclusive shard, abort on all the others to free their resources.
+    CommitTransaction commitCmd;
+    commitCmd.setDbName(DatabaseName::kAdmin);
+    const auto commitCmdObj = commitCmd.toBSON(
+        BSON(WriteConcernOptions::kWriteConcernField << opCtx->getWriteConcern().toBSON()));
+    requests.emplace_back(exclusiveShard, std::move(commitCmdObj));
+
+    for (const auto& shardId : abortShards) {
+        // TODO(Jack) Should we use w:1 so this is faster? Or if we stop waiting for reponses, we
+        // don't care about the WC. Either way w:1 is probably better.
+        auto abortCmd = BSON("abortTransaction" << 1 << WriteConcernOptions::kWriteConcernField
+                                                << WriteConcernOptions::Acknowledged);
+        requests.emplace_back(shardId, std::move(abortCmd));
+    }
+
+    // Send the requests.
+    MultiStatementTransactionRequestsSender ars(
+        opCtx,
+        Grid::get(opCtx)->getExecutorPool()->getFixedExecutor(),
+        DatabaseName::kAdmin,
+        requests,
+        ReadPreferenceSetting{ReadPreference::PrimaryOnly},
+        Shard::RetryPolicy::kIdempotent);
+
+    BSONObj exclusiveShardResult;
+
+    // Receive the responses.
+    while (!ars.done()) {
+        auto response = ars.next();
+
+        if (response.shardId != exclusiveShard) {
+            // Ignore aborted shards' responses.
+            continue;
+        }
+
+        uassertStatusOK(response.swResponse);
+        exclusiveShardResult = response.swResponse.getValue().data;
+
+        const auto commandStatus = getStatusFromCommandResult(exclusiveShardResult);
+        if (!commandStatus.isOK()) {
+            return exclusiveShardResult;
+        }
+
+        const auto writeConcernStatus =
+            getWriteConcernStatusFromCommandResult(exclusiveShardResult);
+        if (!writeConcernStatus.isOK()) {
+            return exclusiveShardResult;
+        }
+
+        // We have the only response we care about, but wait until we receive all responses to know
+        // we sent abort to all shards.
+        ars.stopRetrying();
+
+        // TODO(Jack) Could we return without cancelling IO? Like at least verify we sent abort to
+        // each shard? Don't want to return so fast that we cancel an abort request and leave a
+        // transaction open. But we also don't need to keep retrying or wait for the abort shard
+        // responses.
+    }
+
+    return exclusiveShardResult;
+}
+
 // Helper to convert the CommitType enum into a human readable string for diagnostics.
 std::string commitTypeToString(TransactionRouter::CommitType state) {
     switch (state) {
@@ -1263,7 +1331,8 @@ BSONObj TransactionRouter::Router::_commitTransaction(
                     "sessionId"_attr = _sessionId().getId(),
                     "txnNumber"_attr = o().txnNumberAndRetryCounter.getTxnNumber(),
                     "numReadOnlyShards"_attr = readOnlyShards.size(),
-                    "writeShardId"_attr = writeShards.front());
+                    "writeShardId"_attr = writeShards.front(),
+                    "exclusive"_attr = opCtx->optedIntoExclusiveCommit());
         {
             stdx::lock_guard<Client> lk(*opCtx->getClient());
             o(lk).commitType = CommitType::kSingleWriteShard;
@@ -1286,6 +1355,14 @@ BSONObj TransactionRouter::Router::_commitTransaction(
             return _commitWithRecoveryToken(opCtx, syntheticRecoveryToken);
         }
 
+        // Some features don't care about the responses from the read shards, like updateOne without
+        // shard key. Must be opted into explicitly.
+        if (opCtx->optedIntoExclusiveCommit()) {
+            // NOTE Put after recovery check so we don't need additional test coverage for retrying
+            // after this commit type.
+            return sendExclusiveCommit(opCtx, readOnlyShards, writeShards[0]);
+        }
+
         auto readOnlyShardsResponse = sendCommitDirectlyToShards(opCtx, readOnlyShards);
 
         auto readOnlyCmdStatus = getStatusFromCommandResult(readOnlyShardsResponse);
diff --git a/src/mongo/s/write_ops/write_without_shard_key_util.cpp b/src/mongo/s/write_ops/write_without_shard_key_util.cpp
index c67351750bf..b9318484754 100644
--- a/src/mongo/s/write_ops/write_without_shard_key_util.cpp
+++ b/src/mongo/s/write_ops/write_without_shard_key_util.cpp
@@ -253,6 +253,11 @@ StatusWith<ClusterWriteWithoutShardKeyResponse> runTwoPhaseWriteProtocol(Operati
     auto& executor = Grid::get(opCtx)->getExecutorPool()->getFixedExecutor();
     auto inlineExecutor = std::make_shared<executor::InlineExecutor>();
 
+    // Two phase write transactions only care that the write shard can commit, so opt into
+    // "exclusive commit" which will abort on every shard except the one write shard. This lets the
+    // transaction commit with one round trip and one majority write on the critical path.
+    opCtx->setOptedIntoExclusiveCommit();
+
     auto txn = txn_api::SyncTransactionWithRetries(
         opCtx, executor, TransactionRouterResourceYielder::makeForLocalHandoff(), inlineExecutor);
 
