diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.1.1 [2021-09-09]
+- Improved type checking performance on Diff and Merge ([Thanks ak3n!](https://github.com/target/row-types/pull/77))
+
+
 ## 1.0.1.0 [2021-05-06]
 - Fixed a critical bug in certain values in `Dictionaries` that could cause segfaults.
 - Reimplemented and simplified `Subset`.
@@ -58,7 +62,7 @@
 ## 0.2.3.0 [2018-07-02]
 - Update the `Show` instance for `Rec` to render valid code.
 - Add `toNative` and `fromNative` functions for records to easily convert between Haskell records and row-types records.
-- Make type families in `Data.Row.Internal` polykinded (thanks James Yu!)
+- Make type families in `Data.Row.Internal` polykinded ([Thanks James Yu!](https://github.com/target/row-types/pull/20))
 
 ## 0.2.1.0 [2018-03-20]
 - Bug Fix: The type of `update` for both `Rec` and `Var` now enforce the newly inserted type is correct.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 Row-Types
 =======
 
-[![Build Status](https://api.travis-ci.org/target/row-types.svg?branch=master)](https://travis-ci.org/target/row-types/branches)
+[![Build Status](https://github.com/target/row-types/actions/workflows/.github/workflows/ci.yml/badge.svg)](https://github.com/target/row-types/)
 [![Hackage](https://img.shields.io/hackage/v/row-types.svg)](https://hackage.haskell.org/package/row-types)
 
 Row-types is a library of open records and variants for Haskell using closed
diff --git a/row-types.cabal b/row-types.cabal
--- a/row-types.cabal
+++ b/row-types.cabal
@@ -1,5 +1,5 @@
 Name:                row-types
-Version:             1.0.1.0
+Version:             1.0.1.1
 License:             MIT
 License-file:        LICENSE
 Author:              Daniel Winograd-Cort, Matthew Farkas-Dyck
@@ -7,7 +7,7 @@
 homepage:            https://github.com/target/row-types
 Build-Type:          Simple
 Cabal-Version:       >=1.10
-Tested-With:         GHC == 8.6.5, GHC == 8.8.3, GHC == 8.10.2
+Tested-With:         GHC == 8.6.5, GHC == 8.8.3, GHC == 8.10.3
 Category:            Data, Data Structures
 Synopsis:	           Open Records and Variants
 Description:
@@ -81,6 +81,8 @@
   hs-source-dirs: tests, examples
   ghc-options: -W +RTS -M1G -RTS
   other-modules: Examples,
+                 DiffPerformance,
+                 MergePerformance,
                  UnionPerformance
   build-depends: base >= 2 && < 6
                , generic-lens >= 1.1.0.0
diff --git a/src/Data/Row/Dictionaries.hs b/src/Data/Row/Dictionaries.hs
--- a/src/Data/Row/Dictionaries.hs
+++ b/src/Data/Row/Dictionaries.hs
@@ -211,3 +211,13 @@
 -- | Subset is transitive
 subsetTrans :: forall r1 r2 r3. (Subset r1 r2, Subset r2 r3) :- (Subset r1 r3)
 subsetTrans = Sub $ UNSAFE.unsafeCoerce $ Dict @Unconstrained
+
+-- | Map distributes over Difference
+mapDifference :: forall f r r'. Dict (Map f r .\\ Map f r' ≈ Map f (r .\\ r'))
+mapDifference = UNSAFE.unsafeCoerce $ Dict @Unconstrained
+
+-- | ApSingle distributes over Difference
+apSingleDifference :: forall r r' x. Dict (ApSingle r x .\\ ApSingle r' x ≈ ApSingle (r .\\ r') x)
+apSingleDifference = UNSAFE.unsafeCoerce $ Dict @Unconstrained
+
+-- differenceForall :: forall r r' c. Forall r c :- Forall (r .\\ r') c
diff --git a/src/Data/Row/Internal.hs b/src/Data/Row/Internal.hs
--- a/src/Data/Row/Internal.hs
+++ b/src/Data/Row/Internal.hs
@@ -461,10 +461,14 @@
     TypeError (TL.Text "The label " :<>: ShowType h :<>: TL.Text " has conflicting assignments."
           :$$: TL.Text "Its type is both " :<>: ShowType a :<>: TL.Text " and " :<>: ShowType b :<>: TL.Text ".")
   Merge (hl :-> al ': tl) (hr :-> ar ': tr) =
-      Ifte (hl <=.? hr)
-      (hl :-> al ': Merge tl (hr :-> ar ': tr))
-      (hr :-> ar ': Merge (hl :-> al ': tl) tr)
+      -- Using Ifte here makes GHC blow up on nested unions with many overlapping keys.
+      MergeCont (CmpSymbol hl hr) hl al tl hr ar tr
 
+type family MergeCont (cmp :: Ordering) (hl :: Symbol) (al :: k) (tl :: [LT k])
+                                        (hr :: Symbol) (ar :: k) (tr :: [LT k]) where
+    MergeCont 'LT hl al tl hr ar tr = (hl :-> al ': Merge tl (hr :-> ar ': tr))
+    MergeCont _ hl al tl hr ar tr = (hr :-> ar ': Merge (hl :-> al ': tl) tr)
+
 type family MinJoinR (l :: [LT k]) (r :: [LT k]) where
   MinJoinR '[] r = r
   MinJoinR l '[] = l
@@ -501,11 +505,15 @@
 type family Diff (l :: [LT k]) (r :: [LT k]) where
   Diff '[] r = '[]
   Diff l '[] = l
-  Diff (l :-> al ': tl) (l :-> al ': tr) = Diff tl tr
-  Diff (hl :-> al ': tl) (hr :-> ar ': tr) =
-    Ifte (hl <=.? hr)
-    (hl :-> al ': Diff tl (hr :-> ar ': tr))
-    (Diff (hl :-> al ': tl) tr)
+  Diff (l ':-> al ': tl) (l ':-> al ': tr) = Diff tl tr
+  Diff (hl ':-> al ': tl) (hr ':-> ar ': tr) =
+    -- Using Ifte here makes GHC blow up on nested unions with many overlapping keys.
+    DiffCont (CmpSymbol hl hr) hl al tl hr ar tr
+
+type family DiffCont (cmp :: Ordering) (hl :: Symbol) (al :: k) (tl :: [LT k])
+                                       (hr :: Symbol) (ar :: k) (tr :: [LT k]) where
+    DiffCont 'LT hl al tl hr ar tr = (hl ':-> al ': Diff tl (hr ':-> ar ': tr))
+    DiffCont _ hl al tl hr ar tr = (Diff (hl ':-> al ': tl) tr)
 
 type family ShowRowType (r :: [LT k]) :: ErrorMessage where
   ShowRowType '[] = TL.Text "Empty"
diff --git a/tests/DiffPerformance.hs b/tests/DiffPerformance.hs
new file mode 100644
--- /dev/null
+++ b/tests/DiffPerformance.hs
@@ -0,0 +1,15 @@
+module DiffPerformance where
+
+import Data.Row
+
+type Key l = l .== ()
+type Common = Key "z" .\/ Key "x" .\/ Key "y" .\/ Key "m" .\/ Key "n" .\/ Key "q" .\/ Key "v"
+type Ext l  = Common .\/ Key l
+
+type A = Ext "a" .\/ Ext "b" .\/ Ext "c" .\/ Ext "d" .\/ Ext "e" .\/ Ext "f" .\/ Ext "g" .\/ Ext "h" .\/ Ext "i"
+
+type AWithoutCommon = Key "a" .\/ Key "b" .\/ Key "c" .\/ Key "d" .\/ Key "e" .\/ Key "f" .\/ Key "g" .\/ Key "h" .\/ Key "i"
+
+test :: Rec (A .\\ Common) -> Rec AWithoutCommon
+test = id
+
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -2,6 +2,8 @@
 module Main where
 
 import Examples ()
+import DiffPerformance ()
+import MergePerformance ()
 import UnionPerformance ()
 
 main = putStrLn "Test passes if Examples.lhs type-checks."
diff --git a/tests/MergePerformance.hs b/tests/MergePerformance.hs
new file mode 100644
--- /dev/null
+++ b/tests/MergePerformance.hs
@@ -0,0 +1,13 @@
+module MergePerformance where
+
+import Data.Row
+
+type Key l = l .== ()
+type Common = Key "z" .\/ Key "x" .\/ Key "y" .\/ Key "m" .\/ Key "n" .\/ Key "q" .\/ Key "v"
+type Ext l  = Common .\/ Key l
+
+type A = Ext "a" .\/ Ext "b" .\/ Ext "c" .\/ Ext "d" .\/ Ext "e" .\/ Ext "f" .\/ Ext "g" .\/ Ext "h" .\/ Ext "i"
+
+test :: Rec (Common .+ A) -> Rec (Common .+ A)
+test = id
+
