diff --git a/core/base/inc/TObject.h b/core/base/inc/TObject.h
index 58c09609f6989ff7cad62cccf5d8126d5e3277ed..f3646aa4f4c5bc5953aa338eeef533b6f265c45c 100644
--- a/core/base/inc/TObject.h
+++ b/core/base/inc/TObject.h
@@ -86,7 +86,16 @@ public:
    enum {
       kSingleKey     = BIT(0),        ///< write collection with single key
       kOverwrite     = BIT(1),        ///< overwrite existing object with same name
-      kWriteDelete   = BIT(2)         ///< write object, then delete previous key with same name
+      kWriteDelete   = BIT(2),        ///< write object, then delete previous key with same name
+
+      ///< Used to request that the class specific implementation of `TObject::Write` 
+      ///< just prepare the objects to be ready to be written but do not actually write
+      ///< them into the TBuffer. This is just for example by TBufferMerger to request
+      ///< that the TTree inside the file calls `TTree::FlushBaskets` (outside of the merging lock)
+      ///< and TBufferMerger will later ask for the write (inside the merging lock).
+      ///< To take advantage of this feature the class needs to overload `TObject::Write`
+      ///< and use this enum value accordingly.  (See `TTree::Write` and `TObject::Write`)
+      kOnlyPrepStep  = BIT(3)         
    };
 
    TObject();
diff --git a/core/base/src/TObject.cxx b/core/base/src/TObject.cxx
index 8d5cf8ba115865afcd7611d0f1a80b53fc9b5440..e9e54301d11098f373f5e5aa3a25fe195a2d207d 100644
--- a/core/base/src/TObject.cxx
+++ b/core/base/src/TObject.cxx
@@ -771,6 +771,9 @@ void TObject::UseCurrentStyle()
 
 Int_t TObject::Write(const char *name, Int_t option, Int_t bufsize) const
 {
+   if (R__unlikely(option & kOnlyPrepStep))
+      return 0;
+
    TString opt = "";
    if (option & kSingleKey)   opt += "SingleKey";
    if (option & kOverwrite)   opt += "OverWrite";
diff --git a/io/io/src/TBufferMergerFile.cxx b/io/io/src/TBufferMergerFile.cxx
index 249882bfc67c2c9c654f7cd4eb4bfaf4fe8fcdcc..634fa8a50645bdff1dc74d1a3ac3b38517361feb 100644
--- a/io/io/src/TBufferMergerFile.cxx
+++ b/io/io/src/TBufferMergerFile.cxx
@@ -29,6 +29,10 @@ TBufferMergerFile::~TBufferMergerFile()
 
 Int_t TBufferMergerFile::Write(const char *name, Int_t opt, Int_t bufsize)
 {
+   // Make sure the compression of the basket is done in the unlocked thread and
+   // not in the locked section.
+   TMemFile::Write(name, opt | TObject::kOnlyPrepStep, bufsize);
+
    // Instead of Writing the TTree, doing a memcpy, Pushing to the queue
    // then Reading and then deleting, let's see if we can just merge using
    // the live TTree.
diff --git a/io/io/src/TDirectoryFile.cxx b/io/io/src/TDirectoryFile.cxx
index 15ae3e635c16f6e03b20d82f8f6080fdbd51f3f5..b4dc18fff3ef82f550b9fa0b93141b60372830fd 100644
--- a/io/io/src/TDirectoryFile.cxx
+++ b/io/io/src/TDirectoryFile.cxx
@@ -1785,7 +1785,8 @@ Int_t TDirectoryFile::Write(const char *, Int_t opt, Int_t bufsize)
    while ((obj=next())) {
       nbytes += obj->Write(0,opt,bufsize);
    }
-   SaveSelf(kTRUE);   // force save itself
+   if (R__likely(!(opt & kOnlyPrepStep)))
+      SaveSelf(kTRUE);   // force save itself
 
    return nbytes;
 }
diff --git a/tree/tree/src/TTree.cxx b/tree/tree/src/TTree.cxx
index 31240e9651789af7efe8a4710d7defac75dad5f8..99837711e203b9c07dbc0315703d87970b203bc8 100644
--- a/tree/tree/src/TTree.cxx
+++ b/tree/tree/src/TTree.cxx
@@ -9576,6 +9576,8 @@ void TTree::UseCurrentStyle()
 Int_t TTree::Write(const char *name, Int_t option, Int_t bufsize) const
 {
    FlushBasketsImpl();
+   if (R__unlikely(option & kOnlyPrepStep))
+      return 0;
    return TObject::Write(name, option, bufsize);
 }