diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.8.2.0
+
+* Improve performance of `Reader` and `DslBuilderEff`
+
 # 0.8.1.0
 
 * Add `trans3D`, `oneWayCoercibleNewtypeHandle`
diff --git a/bluefin-internal.cabal b/bluefin-internal.cabal
--- a/bluefin-internal.cabal
+++ b/bluefin-internal.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               bluefin-internal
-version:            0.8.1.0
+version:            0.8.2.0
 license:            MIT
 license-file:       LICENSE
 author:             Tom Ellis
diff --git a/src/Bluefin/Internal.hs b/src/Bluefin/Internal.hs
--- a/src/Bluefin/Internal.hs
+++ b/src/Bluefin/Internal.hs
@@ -38,9 +38,9 @@
 import Control.Monad.Trans.Control (MonadBaseControl, StM, liftBaseWith, restoreM)
 import Control.Monad.Trans.Reader (ReaderT)
 import Control.Monad.Trans.Reader qualified as Reader
-import Data.Coerce (coerce)
+import Data.Coerce (Coercible, coerce)
 import Data.Foldable (for_)
-import Data.IORef (IORef, modifyIORef, newIORef, readIORef, writeIORef)
+import Data.IORef (IORef, modifyIORef', newIORef, readIORef, writeIORef)
 import Data.Kind (Type)
 import Data.Proxy (Proxy (Proxy))
 import Data.Type.Coercion (Coercion (Coercion))
@@ -49,7 +49,6 @@
 import System.IO.Unsafe (unsafePerformIO)
 import Unsafe.Coerce (unsafeCoerce)
 import Prelude hiding (drop, head, read, return)
-import Data.Coerce (Coercible)
 
 -- | Each inhabitant of @Effects@ is a set of effect tags, used for
 -- effect tracking to ensure that effects don't escape the scope of
@@ -581,6 +580,15 @@
 
 -- }
 
+-- | For defining 'OneWayCoercible' instances for newtypes. Example:
+--
+-- @
+-- newtype Random g e = Random (State g e)
+--   deriving (Handle) via OneWayCoercibleHandle (Random g)
+--
+-- instance (e \<: es) => OneWayCoercible (Random g e) (Random g es) where
+--   oneWayCoercibleImpl = oneWayCoercibleNewtypeHandle @(State g)
+-- @
 oneWayCoercibleNewtypeHandle ::
   forall h1 h2 e es.
   (e :> es) =>
@@ -588,6 +596,7 @@
     OneWayCoercible (h1 e) (h1 es),
     Coercible (h1 es) (h2 es)
   ) =>
+  -- | ͘
   OneWayCoercibleD (h2 e) (h2 es)
 oneWayCoercibleNewtypeHandle =
   trans3D
@@ -1624,7 +1633,6 @@
 tell (Writer y) = yield y
 
 type Reader :: Type -> Effects -> Type
-
 newtype Reader r e = MkReader (Vault.Key r)
   deriving (Handle) via OneWayCoercibleHandle (Reader r)
 
@@ -1641,7 +1649,7 @@
 runReader r f = do
   k <- UnsafeMkEff $ \vault -> do
     k <- Vault.newKey
-    modifyIORef vault (\v -> Vault.insert k r v)
+    modifyIORef' vault (\v -> Vault.insert k r v)
     pure k
   makeOp (f (MkReader k))
 
diff --git a/src/Bluefin/Internal/DslBuilderEff.hs b/src/Bluefin/Internal/DslBuilderEff.hs
--- a/src/Bluefin/Internal/DslBuilderEff.hs
+++ b/src/Bluefin/Internal/DslBuilderEff.hs
@@ -10,6 +10,8 @@
     oneWayCoercible,
     oneWayCoercibleImpl,
   )
+import GHC.Base (oneShot)
+import GHC.IO (IO (IO))
 
 newtype DslBuilderEff h es r
   = MkDslBuilderEff {unMkDslBuilderEff :: forall e. h e -> Eff (e :& es) r}
@@ -28,11 +30,16 @@
   Eff es r
 runDslBuilderEff h f = makeOp (unMkDslBuilderEff f h)
 
+-- oneShot is essential for good performance. I don't fully understand
+-- why.
 dslBuilderEff ::
   (forall e. h e -> Eff (e :& es) r) ->
   -- | ͘
   DslBuilderEff h es r
-dslBuilderEff = MkDslBuilderEff
+dslBuilderEff f = MkDslBuilderEff $ \h -> case f h of
+  UnsafeMkEff g -> UnsafeMkEff $ oneShot $ \env -> case g env of
+    -- Expose IO's state transformer so it too can be marked one-shot
+    IO io -> IO (oneShot io)
 
 instance
   (e <: es) =>
