diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,11 @@
+## 1.2.4
+
+* Add a 100ms delay in the WebSocket upgrade process. This matches the
+  behavior of the reference engine.io implementation (in NodeJS), and
+  avoids a race condition on slower machines. Without this, it was
+  possible for the client to experience a up-to-45s delay before
+  upgrading.
+
 ## 1.2.3
 
 * Revert double-encoding introduced in 1.0.1. This now requires that you
diff --git a/engine-io.cabal b/engine-io.cabal
--- a/engine-io.cabal
+++ b/engine-io.cabal
@@ -1,5 +1,5 @@
 name: engine-io
-version: 1.2.3
+version: 1.2.4
 synopsis: A Haskell implementation of Engine.IO
 homepage: http://github.com/ocharles/engine.io
 license: BSD3
diff --git a/src/Network/EngineIO.hs b/src/Network/EngineIO.hs
--- a/src/Network/EngineIO.hs
+++ b/src/Network/EngineIO.hs
@@ -50,9 +50,10 @@
 import Prelude hiding (any)
 
 import Control.Applicative
+import Control.Concurrent (threadDelay)
 import Control.Concurrent.MVar (MVar, newMVar, withMVar)
 import Control.Exception (SomeException(SomeException), try)
-import Control.Monad (MonadPlus, forever, guard, mzero, replicateM)
+import Control.Monad (MonadPlus, forever, guard, mzero, replicateM, when)
 import Control.Monad.Trans.Iter (cutoff, delay, retract)
 import Control.Monad.IO.Class (MonadIO, liftIO)
 import Control.Monad.Loops (unfoldM)
@@ -550,12 +551,25 @@
 
       (wsIn, wsOut) <- liftIO $ STM.atomically $ do
         currentTransport <- STM.readTVar (socketTransport socket)
-        STM.writeTChan (transOut currentTransport) (Packet Noop (TextPacket Text.empty))
         return (transIn currentTransport, transOut currentTransport)
 
+      -- We wait 100ms to match the reference engine.io Javascript.
+      -- See automattic/engine.io socket.js revision d11e17c8.
+      check <-
+        liftIO
+          (Async.async
+            (do threadDelay 100000
+                STM.atomically
+                  (do t <- STM.readTVar (socketTransport socket)
+                      when (transType t == Polling)
+                           (STM.writeTChan (transOut t)
+                                           (Packet Noop (TextPacket Text.empty))))))
+
       Packet Upgrade body <- lift (receivePacket conn)
       guard (body == TextPacket Text.empty || body == BinaryPacket BS.empty)
 
+      liftIO (Async.cancel check)
+
       return (Transport wsIn wsOut Websocket)
 
     for_ mWsTransport $ \wsTransport@Transport { transIn = wsIn, transOut = wsOut } -> do
@@ -730,6 +744,7 @@
 of 'ServerAPI' as:
 
 * <http://hackage.haskell.org/package/engine-io-snap engine-io-snap> for Snap.
+* <http://hackage.haskell.org/package/engine-io-yesod engine-io-yesod> for Yesod.
 
 If you write your own implementation of 'ServerAPI', please share it on Hackage
 and I will link to it from here.
