diff --git a/Network/Wai/Handler/Warp.hs b/Network/Wai/Handler/Warp.hs
--- a/Network/Wai/Handler/Warp.hs
+++ b/Network/Wai/Handler/Warp.hs
@@ -38,6 +38,7 @@
     -- * Connection
   , Connection (..)
   , runSettingsConnection
+  , runSettingsConnectionMaker
     -- * Datatypes
   , Port
   , InvalidRequest (..)
diff --git a/Network/Wai/Handler/Warp/Run.hs b/Network/Wai/Handler/Warp/Run.hs
--- a/Network/Wai/Handler/Warp/Run.hs
+++ b/Network/Wai/Handler/Warp/Run.hs
@@ -129,7 +129,20 @@
         return (socketConnection conn, sa)
 
 runSettingsConnection :: Settings -> IO (Connection, SockAddr) -> Application -> IO ()
-runSettingsConnection set getConn app = do
+runSettingsConnection set getConn app = runSettingsConnectionMaker set getConnMaker app
+  where
+    getConnMaker = do
+      (conn, sa) <- getConn
+      return (return conn, sa)
+
+-- | Allows you to provide a function which will return a @Connection@. In
+-- cases where creating the @Connection@ can be expensive, this allows the
+-- expensive computations to be performed in a separate thread instead of the
+-- main server loop.
+--
+-- Since 1.3.5
+runSettingsConnectionMaker :: Settings -> IO (IO Connection, SockAddr) -> Application -> IO ()
+runSettingsConnectionMaker set getConn app = do
     tm <- maybe (T.initialize $ settingsTimeout set * 1000000) return
         $ settingsManager set
 #if SENDFILEFD
@@ -140,9 +153,10 @@
 #endif
     mask $ \restore -> forever $ do
         allowInterrupt
-        (conn, addr) <- getConnLoop
+        (mkConn, addr) <- getConnLoop
         void . forkIO $ do
             th <- T.registerKillThread tm
+            conn <- mkConn
 #if SENDFILEFD
             let cleaner = Cleaner th fc
 #else
diff --git a/warp.cabal b/warp.cabal
--- a/warp.cabal
+++ b/warp.cabal
@@ -1,5 +1,5 @@
 Name:                warp
-Version:             1.3.4.4
+Version:             1.3.5
 Synopsis:            A fast, light-weight web server for WAI applications.
 License:             MIT
 License-file:        LICENSE
