diff --git a/Network/HTTP2/TLS/Client.hs b/Network/HTTP2/TLS/Client.hs
--- a/Network/HTTP2/TLS/Client.hs
+++ b/Network/HTTP2/TLS/Client.hs
@@ -41,6 +41,7 @@
     settingsOpenClientSocket,
     settingsUseEarlyData,
     settingsOnServerFinished,
+    settingsTimeout,
 
     -- ** Rate limits
     settingsPingRateLimit,
@@ -59,6 +60,7 @@
 import qualified Network.Run.TCP as TCP
 import Network.Socket
 import Network.TLS hiding (HostName)
+import System.Timeout (timeout)
 import System.X509 (getSystemCertificateStore)
 
 import Network.HTTP2.TLS.Client.Settings
@@ -67,6 +69,9 @@
 import qualified Network.HTTP2.TLS.Server.Settings as Server
 import Network.HTTP2.TLS.Supported
 
+data H2TlsTimeout = H2TlsTimeout deriving (Eq, Show)
+instance E.Exception H2TlsTimeout
+
 ----------------------------------------------------------------
 -- Default API
 
@@ -139,8 +144,16 @@
 runWithConfig
     :: ClientConfig -> Settings -> HostName -> PortNumber -> Client a -> IO a
 runWithConfig cliconf settings serverName port client =
-    runTLSWithConfig cliconf settings serverName port "h2" $ \ctx mysa peersa ->
-        run' cliconf' (sendTLS ctx) (recvTLS ctx) mysa peersa client
+    runTLSWithConfig cliconf settings serverName port "h2" $ \ctx mysa peersa -> do
+        let tout = settingsTimeout settings
+            recv
+                | tout > 0 = do
+                    mx <- timeout (tout * 1000000) $ recvTLS ctx
+                    case mx of
+                        Nothing -> E.throwIO H2TlsTimeout
+                        Just x -> return x
+                | otherwise = recvTLS ctx
+        run' cliconf' (sendTLS ctx) recv mysa peersa client
   where
     cliconf' :: ClientConfig
     cliconf' = cliconf{H2Client.scheme = "https"}
@@ -153,7 +166,15 @@
         mysa <- getSocketName sock
         peersa <- getPeerName sock
         recv <- mkRecvTCP Server.defaultSettings sock
-        run' cliconf' (sendTCP sock) recv mysa peersa client
+        let tout = settingsTimeout
+            recv'
+                | tout > 0 = do
+                    mx <- timeout (tout * 1000000) recv
+                    case mx of
+                        Nothing -> E.throwIO H2TlsTimeout
+                        Just x -> return x
+                | otherwise = recv
+        run' cliconf' (sendTCP sock) recv' mysa peersa client
   where
     cliconf' :: ClientConfig
     cliconf' = cliconf{H2Client.scheme = "http"}
diff --git a/Network/HTTP2/TLS/Client/Settings.hs b/Network/HTTP2/TLS/Client/Settings.hs
--- a/Network/HTTP2/TLS/Client/Settings.hs
+++ b/Network/HTTP2/TLS/Client/Settings.hs
@@ -123,6 +123,11 @@
     --
     -- >>> settingsRstRateLimit
     -- 4
+    , settingsTimeout :: Int
+    -- ^ Timeout in seconds. Non-positive values mean no timeout. (H2 and H2c)
+    --
+    -- >>> settingsTimeout defaultSettings
+    -- 0
     }
 
 -- | Default settings.
@@ -150,4 +155,5 @@
         , settingsEmptyFrameRateLimit = 4
         , settingsSettingsRateLimit = 4
         , settingsRstRateLimit = 4
+        , settingsTimeout = 0
         }
diff --git a/http2-tls.cabal b/http2-tls.cabal
--- a/http2-tls.cabal
+++ b/http2-tls.cabal
@@ -1,6 +1,6 @@
 cabal-version: >=1.10
 name:          http2-tls
-version:       0.4.7
+version:       0.4.8
 license:       BSD3
 license-file:  LICENSE
 maintainer:    Kazu Yamamoto <kazu@iij.ad.jp>
