diff --git a/lightstep-haskell.cabal b/lightstep-haskell.cabal
--- a/lightstep-haskell.cabal
+++ b/lightstep-haskell.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.4
 
 name:           lightstep-haskell
-version:        0.1.6
+version:        0.1.7
 synopsis:       LightStep OpenTracing client library
 description:    LightStep OpenTracing client library. Uses GRPC transport via proto-lens.
 category:       Tools
diff --git a/src/LightStep/HighLevel/IO.hs b/src/LightStep/HighLevel/IO.hs
--- a/src/LightStep/HighLevel/IO.hs
+++ b/src/LightStep/HighLevel/IO.hs
@@ -20,6 +20,7 @@
 import System.IO.Unsafe
 import qualified Data.HashMap.Strict as HM
 import qualified Data.Text as T
+import System.Timeout
 
 {-# noinline globalSharedMutableSpanStacks #-}
 globalSharedMutableSpanStacks :: MVar (HM.HashMap ThreadId [Span])
@@ -137,13 +138,6 @@
 waitUntilDone :: Int -> MVar () -> IO ()
 waitUntilDone timeoutSeconds doneVar = do
   d_ "waitUntilDone begin"
-  race_
-    ( do
-        threadDelay $ 1_000_000 * timeoutSeconds
-        d_ "waitUntilDone: timeout"
-    )
-    ( do
-        takeMVar doneVar
-        d_ "waitUntilDone: done"
-    )
-  d_ "waitUntilDone end"
+  timeout (1_000_000 * timeoutSeconds) $ do
+    takeMVar doneVar
+  d_ "waitUntilDone: done"
diff --git a/src/LightStep/LowLevel.hs b/src/LightStep/LowLevel.hs
--- a/src/LightStep/LowLevel.hs
+++ b/src/LightStep/LowLevel.hs
@@ -7,8 +7,10 @@
 where
 
 import Chronos
+import System.Timeout
 import Control.Exception.Safe
 import Control.Lens hiding (op)
+import Control.Monad.IO.Class
 import Data.ProtoLens.Message (defMessage)
 import qualified Data.Text as T
 import LightStep.Internal.Debug
@@ -32,15 +34,16 @@
 
 reportSpans :: LightStepClient -> [Span] -> ExceptT ClientError IO ()
 reportSpans (LightStepClient grpc token rep) sps = do
-  ret <-
-    rawUnary
-      (RPC :: RPC CollectorService "report")
-      grpc
-      ( defMessage
-          & auth .~ (defMessage & accessToken .~ token)
-          & spans .~ sps
-          & reporter .~ rep
-      )
+  let req = liftIO . timeout 3_000_000 . runExceptT $
+          rawUnary
+            (RPC :: RPC CollectorService "report")
+            grpc
+            ( defMessage
+                & auth .~ (defMessage & accessToken .~ token)
+                & spans .~ sps
+                & reporter .~ rep
+            )
+  ret <- req
       `withException` (\err -> d_ $ "reportSpans failed: " <> show (err :: SomeException))
   d_ $ show ret
   -- FIXME: handle errors
