diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for essence-of-live-coding-gloss
 
-## 0.1.0.0 -- YYYY-mm-dd
+## 0.2.3
 
-* First version. Released on an unsuspecting world.
+* glossWrapC is now nonblocking.
+
+## Earlier versions
+
+See in essence-of-live-coding/CHANGELOG.md.
diff --git a/essence-of-live-coding-gloss.cabal b/essence-of-live-coding-gloss.cabal
--- a/essence-of-live-coding-gloss.cabal
+++ b/essence-of-live-coding-gloss.cabal
@@ -1,5 +1,5 @@
 name:                essence-of-live-coding-gloss
-version:             0.2.2
+version:             0.2.3
 synopsis: General purpose live coding framework - Gloss backend
 description:
   essence-of-live-coding is a general purpose and type safe live coding framework.
@@ -32,7 +32,7 @@
 source-repository this
   type:     git
   location: git@github.com:turion/essence-of-live-coding.git
-  tag:      v0.2.2
+  tag:      v0.2.3
 
 library
   exposed-modules:
@@ -43,7 +43,7 @@
       base >= 4.11 && < 5
     , syb >= 0.7
     , transformers >= 0.5
-    , essence-of-live-coding >= 0.2.2
+    , essence-of-live-coding >= 0.2.3
     , foreign-store >= 0.2
     , gloss >= 1.13
   hs-source-dirs:      src
diff --git a/src/LiveCoding/Gloss.hs b/src/LiveCoding/Gloss.hs
--- a/src/LiveCoding/Gloss.hs
+++ b/src/LiveCoding/Gloss.hs
@@ -92,25 +92,37 @@
 
 stepGloss :: Float -> GlossVars -> IO GlossVars
 stepGloss dTime vars@GlossVars { .. } = do
-  threadDelay $ round $ dTime * 1000
   putMVar glossDTimeVar dTime
   exitNow <- readIORef glossExitRef
   when exitNow exitSuccess
   return vars
 
--- | Given a cell in the gloss monad 'PictureM',
---   start the gloss backend and connect the cell to it.
---   This introduces 'Handle's, which need to be taken care of by calling 'runHandlingState'
---   or a similar function.
-glossWrapC :: GlossSettings -> Cell PictureM a b -> Cell (StateT (HandlingState IO) IO) a b
+{- | Given a cell in the gloss monad 'PictureM',
+start the gloss backend and connect the cell to it.
+
+This introduces 'Handle's containing the gloss background thread,
+which need to be taken care of by calling 'runHandlingState'
+or a similar function.
+
+The resulting cell never blocks,
+but returns 'Nothing' if there currently is no gloss tick.
+-}
+glossWrapC
+  :: GlossSettings
+  -> Cell PictureM a b
+  -> Cell (HandlingStateT IO) a (Maybe b)
 glossWrapC glossSettings cell = proc a -> do
   GlossHandle { .. } <- handling $ glossHandle glossSettings -< ()
   liftCell pump -< (glossVars, a)
   where
     pump = proc (GlossVars { .. }, a) -> do
-      _      <- arrM takeMVar                        -< glossDTimeVar
-      events <- arrM $ flip atomicModifyIORef ([], ) -< glossEventsRef
-      (picture, b) <- runPictureT cell               -< (events, a)
-      arrM (uncurry writeIORef)                      -< (glossPicRef, picture)
-      arrM threadDelay                               -< 10000 -- TODO Tweak for better performance
-      returnA                                        -< b
+      timeMaybe <- arrM tryTakeMVar                        -< glossDTimeVar
+      case timeMaybe of
+        Just _ -> do
+          events <- arrM $ flip atomicModifyIORef ([], ) -< glossEventsRef
+          (picture, b) <- runPictureT cell               -< (events, a)
+          arrM (uncurry writeIORef)                      -< (glossPicRef, picture)
+          returnA                                        -< Just b
+        Nothing -> do
+          arrM threadDelay       -< 100 -- Prevent too much CPU load
+          returnA                -< Nothing
