diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2021 Simon Hengel <sol@typeful.net>
+Copyright (c) 2011-2022 Simon Hengel <sol@typeful.net>
 Copyright (c) 2011-2012 Trystan Spangler <trystan.s@comcast.net>
 Copyright (c) 2011-2011 Greg Weber <greg@gregweber.info>
 
diff --git a/hspec-core.cabal b/hspec-core.cabal
--- a/hspec-core.cabal
+++ b/hspec-core.cabal
@@ -5,10 +5,10 @@
 -- see: https://github.com/sol/hpack
 
 name:             hspec-core
-version:          2.9.6
+version:          2.9.7
 license:          MIT
 license-file:     LICENSE
-copyright:        (c) 2011-2021 Simon Hengel,
+copyright:        (c) 2011-2022 Simon Hengel,
                   (c) 2011-2012 Trystan Spangler,
                   (c) 2011 Greg Weber
 maintainer:       Simon Hengel <sol@typeful.net>
diff --git a/src/Test/Hspec/Core/Formatters/Internal.hs b/src/Test/Hspec/Core/Formatters/Internal.hs
--- a/src/Test/Hspec/Core/Formatters/Internal.hs
+++ b/src/Test/Hspec/Core/Formatters/Internal.hs
@@ -41,7 +41,6 @@
 
 #ifdef TEST
 , runFormatM
-, overwriteWith
 , splitLines
 #endif
 ) where
@@ -51,7 +50,7 @@
 
 import qualified System.IO as IO
 import           System.IO (Handle, stdout)
-import           Control.Exception (bracket_)
+import           Control.Exception (bracket_, bracket)
 import           System.Console.ANSI
 import           Control.Monad.Trans.State hiding (state, gets, modify)
 import           Control.Monad.IO.Class
@@ -94,7 +93,6 @@
   Progress path progress -> formatterProgress path progress
   ItemStarted path -> formatterItemStarted path
   ItemDone path item -> do
-    clearTransientOutput
     case itemResult item of
       Success {} -> increaseSuccessCount
       Pending {} -> increasePendingCount
@@ -147,7 +145,6 @@
 , stateFailMessages    :: [FailureRecord]
 , stateCpuStartTime    :: Maybe Integer
 , stateStartTime       :: Seconds
-, stateTransientOutput :: String
 , stateConfig          :: FormatConfig
 , stateColor           :: Maybe SGR
 }
@@ -168,12 +165,16 @@
   deriving (Functor, Applicative, Monad, MonadIO)
 
 runFormatM :: FormatConfig -> FormatM a -> IO a
-runFormatM config (FormatM action) = do
+runFormatM config (FormatM action) = withLineBuffering $ do
   time <- getMonotonicTime
   cpuTime <- if (formatConfigPrintCpuTime config) then Just <$> CPUTime.getCPUTime else pure Nothing
-  st <- newIORef (FormatterState 0 0 [] cpuTime time "" config Nothing)
+  st <- newIORef (FormatterState 0 0 [] cpuTime time config Nothing)
   evalStateT action st
 
+withLineBuffering :: IO a -> IO a
+withLineBuffering action = bracket (IO.hGetBuffering stdout) (IO.hSetBuffering stdout) $ \ _ -> do
+  IO.hSetBuffering stdout IO.LineBuffering >> action
+
 -- | Increase the counter for successful examples
 increaseSuccessCount :: FormatM ()
 increaseSuccessCount = modify $ \s -> s {stateSuccessCount = succ $ stateSuccessCount s}
@@ -203,29 +204,14 @@
 getExpectedTotalCount :: FormatM Int
 getExpectedTotalCount = getConfig formatConfigExpectedTotalCount
 
-overwriteWith :: String -> String -> String
-overwriteWith old new
-  | n == 0 = new
-  | otherwise = '\r' : new ++ replicate (n - length new) ' '
-  where
-    n = length old
-
 writeTransient :: String -> FormatM ()
 writeTransient new = do
   reportProgress <- getConfig formatConfigReportProgress
   when (reportProgress) $ do
-    old <- gets stateTransientOutput
-    write $ old `overwriteWith` new
-    modify $ \ state -> state {stateTransientOutput = new}
     h <- getHandle
+    write $ new
     liftIO $ IO.hFlush h
-
-clearTransientOutput :: FormatM ()
-clearTransientOutput = do
-  n <- length <$> gets stateTransientOutput
-  unless (n == 0) $ do
-    write ("\r" ++ replicate n ' ' ++ "\r")
-    modify $ \ state -> state {stateTransientOutput = ""}
+    write $ "\r" ++ replicate (length new) ' ' ++ "\r"
 
 -- | Append some output to the report.
 write :: String -> FormatM ()
diff --git a/test/Test/Hspec/Core/Formatters/InternalSpec.hs b/test/Test/Hspec/Core/Formatters/InternalSpec.hs
--- a/test/Test/Hspec/Core/Formatters/InternalSpec.hs
+++ b/test/Test/Hspec/Core/Formatters/InternalSpec.hs
@@ -33,23 +33,6 @@
         withSuccessColor $ write "foo\nbar\nbaz\n"
       `shouldReturn` unlines [green "foo", green "bar", green "baz"]
 
-  describe "overwriteWith" $ do
-    context "when old is null" $ do
-      it "returns new" $ do
-        ("" `overwriteWith` "foo") `shouldBe` "foo"
-
-    context "when old and new have the same length" $ do
-      it "overwrites old" $ do
-        ("foo" `overwriteWith` "bar") `shouldBe` "\rbar"
-
-    context "when old is shorter than new" $ do
-      it "overwrites old" $ do
-        ("ba" `overwriteWith` "foo") `shouldBe` "\rfoo"
-
-    context "when old is longer than new" $ do
-      it "overwrites old" $ do
-        ("foobar" `overwriteWith` "foo") `shouldBe` "\rfoo   "
-
   describe "splitLines" $ do
     it "splits a string into chunks" $ do
       splitLines "foo\nbar\nbaz" `shouldBe` ["foo", "\n", "bar", "\n", "baz"]
diff --git a/version.yaml b/version.yaml
--- a/version.yaml
+++ b/version.yaml
@@ -1,1 +1,1 @@
-&version 2.9.6
+&version 2.9.7
