diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+1.37.1
+
+* [Fix performance regression for `with` expressions](https://github.com/dhall-lang/dhall-haskell/pull/2112)
+
 1.37.0
 
 * [Supports version 20.0.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v20.0.0)
diff --git a/dhall.cabal b/dhall.cabal
--- a/dhall.cabal
+++ b/dhall.cabal
@@ -1,5 +1,5 @@
 Name: dhall
-Version: 1.37.0
+Version: 1.37.1
 Cabal-Version: >=1.10
 Build-Type: Simple
 Tested-With: GHC == 8.4.3, GHC == 8.6.1
diff --git a/src/Dhall/TypeCheck.hs b/src/Dhall/TypeCheck.hs
--- a/src/Dhall/TypeCheck.hs
+++ b/src/Dhall/TypeCheck.hs
@@ -1252,27 +1252,32 @@
 
             return (VConst Type)
 
-        With e ks v -> do
-            tE' <- loop ctx e
+        With e₀ ks₀ v₀ -> do
+            tE₀' <- loop ctx e₀
 
-            kTs' <- case tE' of
-                VRecord kTs' -> return kTs'
-                _            -> die (NotWithARecord e (quote names tE'))
+            -- The purpose of this inner loop is to ensure that we only need to
+            -- typecheck the record once
+            let with tE' ks v = do
+                    kTs' <- case tE' of
+                        VRecord kTs' -> return kTs'
+                        _            -> die (NotWithARecord e₀ (quote names tE'))
 
-            case ks of
-                k :| [] -> do
-                    tV' <- loop ctx v
+                    case ks of
+                        k :| [] -> do
+                            tV' <- loop ctx v
 
-                    return (VRecord (Dhall.Map.insert k tV' kTs'))
-                k₀ :| k₁ : ks' -> do
-                    let e₁ =
-                            if Dhall.Map.member k₀ kTs'
-                                then Field e (Syntax.makeFieldSelection k₀)
-                                else RecordLit mempty
+                            return (VRecord (Dhall.Map.insert k tV' kTs'))
+                        k₀ :| k₁ : ks' -> do
+                            let _T =
+                                    case Dhall.Map.lookup k₀ kTs' of
+                                        Just _T' -> _T'
+                                        Nothing  -> VRecord mempty
 
-                    tV' <- loop ctx (With e₁ (k₁ :| ks') v)
+                            tV' <- with _T (k₁ :| ks') v
 
-                    return (VRecord (Dhall.Map.insert k₀ tV' kTs'))
+                            return (VRecord (Dhall.Map.insert k₀ tV' kTs'))
+
+            with tE₀' ks₀ v₀
 
         Note s e ->
             case loop ctx e of
