diff --git a/hasql.cabal b/hasql.cabal
--- a/hasql.cabal
+++ b/hasql.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: hasql
-version: 1.10.2
+version: 1.10.2.1
 category: Hasql, Database, PostgreSQL
 synopsis: Fast PostgreSQL driver with a flexible mapping API
 description:
diff --git a/src/library-tests/Sharing/ByUnit/Connection/UseSpec.hs b/src/library-tests/Sharing/ByUnit/Connection/UseSpec.hs
--- a/src/library-tests/Sharing/ByUnit/Connection/UseSpec.hs
+++ b/src/library-tests/Sharing/ByUnit/Connection/UseSpec.hs
@@ -4,6 +4,7 @@
 import Hasql.Connection qualified as Connection
 import Hasql.Decoders qualified as Decoders
 import Hasql.Encoders qualified as Encoders
+import Hasql.Pipeline qualified as Pipeline
 import Hasql.Session qualified as Session
 import Hasql.Statement qualified as Statement
 import Helpers.Dsls.Execution qualified as Execution
@@ -42,6 +43,35 @@
             return s
 
         result `shouldBe` Right (3 :: Int64)
+
+  describe "Pipeline Mode" do
+    it "Leaves the connection usable after timeout in pipeline" \config -> do
+      Scripts.onPreparableConnection config \connection -> do
+        let selectStatement =
+              Statement.preparable
+                "select $1::int"
+                (Encoders.param (Encoders.nonNullable Encoders.int4))
+                (Decoders.singleRow (Decoders.column (Decoders.nonNullable Decoders.int4)))
+
+        -- Timeout during a pipeline operation
+        result <-
+          timeout 50_000 do
+            Connection.use connection
+              $ Session.pipeline
+              $ (,)
+              <$> Pipeline.statement 42 selectStatement
+              <*> Execution.pipelineByParams (Statements.Sleep 0.1)
+
+        result `shouldBe` Nothing
+
+        -- Try to use pipeline again after timeout cleanup
+        -- This should work but fails with "connection not idle" without the fix
+        result2 <-
+          Connection.use connection
+            $ Session.pipeline
+            $ Pipeline.statement 99 selectStatement
+
+        result2 `shouldBe` Right 99
 
   describe "Timing out" do
     describe "On a statement" do
diff --git a/src/library/Hasql/Comms/Session.hs b/src/library/Hasql/Comms/Session.hs
--- a/src/library/Hasql/Comms/Session.hs
+++ b/src/library/Hasql/Comms/Session.hs
@@ -76,6 +76,13 @@
 leavePipeline = do
   pipelineStatus <- getPipelineStatus
   when (pipelineStatus == Pq.PipelineOn) do
+    -- In pipeline mode, we need to ensure the pipeline is synchronized before exiting.
+    -- Send a pipeline sync marker to flush any pending operations.
+    syncSuccess <- sendPipelineSync
+    when syncSuccess drainResults
+    -- After sync, send a flush to ensure all queued commands are sent to the server.
+    flushSuccess <- sendFlushRequest
+    when flushSuccess drainResults
     -- Try to exit pipeline mode.
     -- This might fail if there are pending results that need to be consumed.
     success <- exitPipelineMode
@@ -124,6 +131,14 @@
 exitPipelineMode :: Session Bool
 exitPipelineMode = Session \connection -> do
   Right <$> Pq.exitPipelineMode connection
+
+sendPipelineSync :: Session Bool
+sendPipelineSync = Session \connection -> do
+  Right <$> Pq.pipelineSync connection
+
+sendFlushRequest :: Session Bool
+sendFlushRequest = Session \connection -> do
+  Right <$> Pq.sendFlushRequest connection
 
 -- Drain all pending results from the connection.
 drainResults :: Session ()
