diff --git a/hasql-cursor-transaction.cabal b/hasql-cursor-transaction.cabal
--- a/hasql-cursor-transaction.cabal
+++ b/hasql-cursor-transaction.cabal
@@ -1,7 +1,7 @@
 name:
   hasql-cursor-transaction
 version:
-  0.5.0.1
+  0.6
 category:
   Hasql, Database, PostgreSQL, Streaming
 synopsis:
@@ -38,7 +38,7 @@
     library
   ghc-options:
   default-extensions:
-    Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFunctor, DeriveGeneric, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples
+    Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples
   default-language:
     Haskell2010
   other-modules:
diff --git a/library/Hasql/CursorTransaction.hs b/library/Hasql/CursorTransaction.hs
--- a/library/Hasql/CursorTransaction.hs
+++ b/library/Hasql/CursorTransaction.hs
@@ -6,7 +6,7 @@
   B.BatchSize,
   B.EncodedParams,
   -- * Cursor Transactions
-  A.withCursor,
+  A.declareCursor,
   A.fetchBatch,
   A.transaction,
   -- * Batch Sizes
diff --git a/library/Hasql/CursorTransaction/Private/CursorTransaction.hs b/library/Hasql/CursorTransaction/Private/CursorTransaction.hs
--- a/library/Hasql/CursorTransaction/Private/CursorTransaction.hs
+++ b/library/Hasql/CursorTransaction/Private/CursorTransaction.hs
@@ -13,7 +13,7 @@
 -- |
 -- Context for fetching from multiple cursors in an intertwined fashion.
 newtype CursorTransaction s result =
-  CursorTransaction (StateT Int A.Transaction result)
+  CursorTransaction (StateT (Int, A.Transaction ()) A.Transaction result)
   deriving (Functor, Applicative, Monad)
 
 -- |
@@ -21,35 +21,26 @@
 newtype Cursor s =
   Cursor ByteString
 
-declareCursor :: ByteString -> D.Params params -> params -> CursorTransaction s (Cursor s)
-declareCursor template encoder params =
+-- |
+-- Given a template and encoded params produces a cursor,
+-- while automating its resource management.
+declareCursor :: ByteString -> G.EncodedParams -> CursorTransaction s (Cursor s)
+declareCursor template (G.EncodedParams (Supplied encoder params)) =
   CursorTransaction $
   do
-    name <- fmap name (state ((,) <$> id <*> succ))
+    name <- state $ do
+      (inc, finaliser) <- id
+      name <- return (incToName inc)
+      newFinaliser <- return (finaliser *> C.closeCursor name)
+      return (name, (succ inc, newFinaliser))
     lift (C.declareCursor name template encoder params)
     return (Cursor name)
   where
-    name inc =
+    incToName inc =
       E.toByteString $
       E.byteString "Hasql_CursorTransaction_" <> E.asciiIntegral inc
 
-closeCursor :: Cursor s -> CursorTransaction s ()
-closeCursor (Cursor name) =
-  transaction (C.closeCursor name)
-
 -- |
--- Given a template, encoded params and a Cursor-handling continuation,
--- executes it,
--- while automatically declaring and closing the cursor behind the scenes.
-withCursor :: ByteString -> G.EncodedParams -> (forall s. Cursor s -> CursorTransaction s result) -> CursorTransaction s result
-withCursor template (G.EncodedParams (Supplied encoder params)) continuation =
-  do
-    cursor <- declareCursor template encoder params
-    result <- continuation cursor
-    closeCursor cursor
-    return result
-
--- |
 -- Fetch from a cursor a batch of the given size and decode it using the specified result decoder.
 fetchBatch :: Cursor s -> G.BatchSize -> F.Result result -> CursorTransaction s result
 fetchBatch (Cursor name) batchSize decoder =
@@ -64,4 +55,7 @@
 
 run :: (forall s. CursorTransaction s result) -> A.Transaction result
 run (CursorTransaction stack) =
-  evalStateT stack 1
+  do
+    (result, (_, finaliser)) <- runStateT stack (1, pure ())
+    finaliser
+    return result
