diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+# 0.7
+
+Simplified the implementation a lot by removing the notion of timeout.
+
+Breaking:
+- Removed the `Settings` type
+- Changed the signature of `acquire`
+
 # 0.6
 
 Moved away from "resource-pool" and fixed the handling of lost connections.
diff --git a/hasql-pool.cabal b/hasql-pool.cabal
--- a/hasql-pool.cabal
+++ b/hasql-pool.cabal
@@ -1,7 +1,7 @@
 name:
   hasql-pool
 version:
-  0.6.0.1
+  0.7
 category:
   Hasql, Database, PostgreSQL
 synopsis:
@@ -49,7 +49,7 @@
     Hasql.Pool.Prelude
   build-depends:
     base >=4.11 && <5,
-    hasql >=1.6.0.1 && <1.7,
+    hasql >=1.3 && <1.6,
     stm >=2.5 && <3,
     time >=1.5 && <2,
     transformers >=0.5 && <0.7
diff --git a/library/Hasql/Pool.hs b/library/Hasql/Pool.hs
--- a/library/Hasql/Pool.hs
+++ b/library/Hasql/Pool.hs
@@ -1,6 +1,5 @@
 module Hasql.Pool
   ( Pool,
-    Settings (..),
     acquire,
     release,
     UsageError (..),
@@ -16,186 +15,85 @@
 
 -- |
 -- A pool of connections to DB.
-data Pool
-  = Pool
-      Connection.Settings
-      -- ^ Connection settings.
-      (TQueue ActiveConnection)
-      -- ^ Queue of established connections.
-      (TVar Int)
-      -- ^ Slots available for establishing new connections.
-      (TVar Bool)
-      -- ^ Flag signaling whether pool's alive.
-
-data ActiveConnection = ActiveConnection
-  { activeConnectionLastUseTimestamp :: Int,
-    activeConnectionConnection :: Connection
+data Pool = Pool
+  { -- | Connection settings.
+    poolConnectionSettings :: Connection.Settings,
+    -- | Avail connections.
+    poolConnectionQueue :: TQueue Connection,
+    -- | Capacity.
+    poolCapacity :: TVar Int,
+    -- | Alive.
+    poolAlive :: TVar Bool
   }
 
-loopCollectingGarbage :: Int -> TQueue ActiveConnection -> TVar Int -> TVar Bool -> IO ()
-loopCollectingGarbage timeout establishedQueue slotsAvailVar aliveVar =
-  decide
-  where
-    decide =
-      do
-        ts <- getMillisecondsSinceEpoch
-        join $
-          atomically $ do
-            alive <- readTVar aliveVar
-            if alive
-              then
-                let tryToRelease =
-                      tryReadTQueue establishedQueue >>= \case
-                        -- The queue is empty. Just wait for changes in the state.
-                        Nothing ->
-                          retry
-                        Just entry@(ActiveConnection lastUseTs connection) ->
-                          let outdatingTs =
-                                lastUseTs + timeout
-                           in -- Check whether it's outdated.
-                              if outdatingTs < ts
-                                then -- Fetch the current value of available slots and
-                                -- release this one and other connections.
-                                do
-                                  slotsAvail <- readTVar slotsAvailVar
-                                  collectAndRelease slotsAvail [connection] outdatingTs
-                                else -- Return it to the front of the queue and
-                                -- wait until it's outdating time.
-                                do
-                                  unGetTQueue establishedQueue entry
-                                  return (sleep outdatingTs *> decide)
-                    collectAndRelease !slotsAvail !outdatedList outdatingTs =
-                      tryReadTQueue establishedQueue >>= \case
-                        Nothing ->
-                          finalizeAndRelease slotsAvail outdatedList outdatingTs
-                        Just entry@(ActiveConnection lastUseTs connection) ->
-                          let outdatingTs =
-                                lastUseTs + timeout
-                           in if outdatingTs < ts
-                                then do
-                                  unGetTQueue establishedQueue entry
-                                  finalizeAndRelease slotsAvail outdatedList outdatingTs
-                                else collectAndRelease (succ slotsAvail) (connection : outdatedList) outdatingTs
-                    finalizeAndRelease slotsAvail outdatedList outdatingTs =
-                      do
-                        writeTVar slotsAvailVar slotsAvail
-                        return (release outdatedList *> sleep outdatingTs *> decide)
-                 in tryToRelease
-              else do
-                list <- flushTQueue establishedQueue
-                return (release (fmap activeConnectionConnection list))
-    sleep untilTs =
-      do
-        ts <- getMillisecondsSinceEpoch
-        let diff =
-              untilTs - ts
-         in if diff > 0
-              then threadDelay (diff * 1000)
-              else return ()
-    release =
-      traverse_ Connection.release
-
--- |
--- Settings of the connection pool. Consist of:
---
--- * Pool-size.
---
--- * Timeout.
--- An amount of time in milliseconds for which the unused connections are kept open.
---
--- * Connection settings.
-type Settings =
-  (Int, Int, Connection.Settings)
-
--- |
--- Given the pool-size, timeout and connection settings
--- create a connection-pool.
-acquire :: Settings -> IO Pool
-acquire (size, timeout, connectionSettings) =
-  do
-    establishedQueue <- newTQueueIO
-    slotsAvailVar <- newTVarIO size
-    aliveVar <- newTVarIO (size > 0)
-    forkIO $ loopCollectingGarbage timeout establishedQueue slotsAvailVar aliveVar
-    return (Pool connectionSettings establishedQueue slotsAvailVar aliveVar)
+-- | Given the pool-size and connection settings create a connection-pool.
+acquire :: Int -> Connection.Settings -> IO Pool
+acquire poolSize connectionSettings = do
+  Pool connectionSettings
+    <$> newTQueueIO
+    <*> newTVarIO poolSize
+    <*> newTVarIO True
 
 -- |
--- Release the connection-pool.
+-- Release all the connections in the pool.
 release :: Pool -> IO ()
-release (Pool _ _ _ aliveVar) =
-  atomically (writeTVar aliveVar False)
+release Pool {..} = do
+  connections <- atomically $ do
+    writeTVar poolAlive False
+    flushTQueue poolConnectionQueue
+  forM_ connections Connection.release
 
 -- |
 -- A union over the connection establishment error and the session error.
 data UsageError
-  = -- | Error during an attempt to connect.
-    ConnectionUsageError Connection.ConnectionError
-  | -- | Error during session execution.
-    SessionUsageError Session.QueryError
-  | -- | Pool has been released and can no longer be used.
-    PoolIsReleasedUsageError
+  = ConnectionUsageError Connection.ConnectionError
+  | SessionUsageError Session.QueryError
+  | PoolIsReleasedUsageError
   deriving (Show, Eq)
 
--- | Use a connection from the pool to run a session and return the connection
--- to the pool, when finished. If the session fails
--- with 'Session.ClientError' the connection gets reestablished.
+-- |
+-- Use a connection from the pool to run a session and
+-- return the connection to the pool, when finished.
 use :: Pool -> Session.Session a -> IO (Either UsageError a)
-use (Pool connectionSettings establishedQueue slotsAvailVar aliveVar) session =
-  join $
-    atomically $ do
-      alive <- readTVar aliveVar
-      if alive
-        then
-          tryReadTQueue establishedQueue >>= \case
-            -- No established connection avail at the moment.
-            Nothing -> do
-              slotsAvail <- readTVar slotsAvailVar
-              -- Do we have any slots left for establishing new connections?
-              if slotsAvail > 0
-                then -- Reduce the available slots var and instruct to
-                -- establish and use a new connection.
-                do
-                  writeTVar slotsAvailVar $! pred slotsAvail
-                  return acquireConnectionThenUseThenPutItToQueue
-                else -- Wait until the state changes and retry.
-
-                  retry
-            Just (ActiveConnection _ connection) ->
-              return (useConnectionThenPutItToQueue connection)
-        else return (return (Left PoolIsReleasedUsageError))
+use Pool {..} sess =
+  join . atomically $ do
+    alive <- readTVar poolAlive
+    if alive
+      then
+        asum
+          [ readTQueue poolConnectionQueue <&> onConn,
+            do
+              capVal <- readTVar poolCapacity
+              if capVal > 0
+                then do
+                  writeTVar poolCapacity $! pred capVal
+                  return onNewConn
+                else retry
+          ]
+      else return . return . Left $ PoolIsReleasedUsageError
   where
-    acquireConnectionThenUseThenPutItToQueue =
-      do
-        res <- Connection.acquire connectionSettings
-        case res of
-          -- Failed to acquire, so release an availability slot,
-          -- returning the error details.
-          Left acquisitionError -> do
-            atomically $ modifyTVar' slotsAvailVar succ
-            return (Left (ConnectionUsageError acquisitionError))
-          Right connection ->
-            useConnectionThenPutItToQueue connection
-    useConnectionThenPutItToQueue connection =
-      do
-        res <- Session.run session connection
-        case res of
-          Left queryError -> do
-            -- Check whether the error is on client-side,
-            -- and in that case release the connection.
-            case queryError of
-              Session.QueryError _ _ (Session.ClientError _) ->
-                releaseConnection connection
-              _ ->
-                putConnectionToPool connection
-            return (Left (SessionUsageError queryError))
-          Right res -> do
-            putConnectionToPool connection
-            return (Right res)
-    putConnectionToPool connection =
-      do
-        ts <- getMillisecondsSinceEpoch
-        atomically $ writeTQueue establishedQueue (ActiveConnection ts connection)
-    releaseConnection connection =
-      do
-        atomically $ modifyTVar' slotsAvailVar succ
-        Connection.release connection
+    onNewConn = do
+      connRes <- Connection.acquire poolConnectionSettings
+      case connRes of
+        Left connErr -> do
+          atomically $ modifyTVar' poolCapacity succ
+          return $ Left $ ConnectionUsageError connErr
+        Right conn -> onConn conn
+    onConn conn = do
+      sessRes <- Session.run sess conn
+      case sessRes of
+        Left err -> case err of
+          Session.QueryError _ _ (Session.ClientError _) -> do
+            atomically $ modifyTVar' poolCapacity succ
+            return $ Left $ SessionUsageError err
+          _ -> do
+            returnConn
+            return $ Left $ SessionUsageError err
+        Right res -> do
+          returnConn
+          return $ Right res
+      where
+        returnConn = do
+          atomically $ do
+            alive <- readTVar poolAlive
+            when alive $ writeTQueue poolConnectionQueue conn
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -12,24 +12,24 @@
 main = hspec $ do
   describe "" $ do
     it "Releases a spot in the pool when there is a query error" $ do
-      pool <- acquire (1, 1, connectionSettings)
+      pool <- acquire 1 connectionSettings
       use pool badQuerySession `shouldNotReturn` (Right ())
       use pool selectOneSession `shouldReturn` (Right 1)
     it "Simulation of connection error works" $ do
-      pool <- acquire (3, 1, connectionSettings)
+      pool <- acquire 3 connectionSettings
       res <- use pool $ closeConnSession >> selectOneSession
       shouldSatisfy res $ \case
         Left (SessionUsageError (Session.QueryError _ _ (Session.ClientError _))) -> True
         _ -> False
     it "Connection errors cause eviction of connection" $ do
-      pool <- acquire (3, 1, connectionSettings)
+      pool <- acquire 3 connectionSettings
       res <- use pool $ closeConnSession >> selectOneSession
       res <- use pool $ closeConnSession >> selectOneSession
       res <- use pool $ closeConnSession >> selectOneSession
       res <- use pool $ selectOneSession
       shouldSatisfy res $ isRight
     it "Connection gets returned to the pool after normal use" $ do
-      pool <- acquire (3, 1, connectionSettings)
+      pool <- acquire 3 connectionSettings
       res <- use pool $ selectOneSession
       res <- use pool $ selectOneSession
       res <- use pool $ selectOneSession
@@ -37,7 +37,7 @@
       res <- use pool $ selectOneSession
       shouldSatisfy res $ isRight
     it "Connection gets returned to the pool after non-connection error" $ do
-      pool <- acquire (3, 1, connectionSettings)
+      pool <- acquire 3 connectionSettings
       res <- use pool $ badQuerySession
       res <- use pool $ badQuerySession
       res <- use pool $ badQuerySession
@@ -60,7 +60,7 @@
 badQuerySession =
   Session.statement () statement
   where
-    statement = Statement.Statement "zzz" Encoders.noParams Decoders.noResult True
+    statement = Statement.Statement "" Encoders.noParams Decoders.noResult True
 
 closeConnSession :: Session.Session ()
 closeConnSession = do
