diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Changelog
 
+## [0.15.0.0] - 2023-04-08
+
+* `DefBeforeAllWithNode`: so that `beforeAllWith` can be defined in terms of it and have better parallelism properties.
+* `DefSetupNode`: so that `beforeAll_` can be defined in terms of it and have better parallelism properties.
+
 ## [0.14.0.0] - 2023-04-05
 
 * Profiling mode, for figuring out why your test suite is slow.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1,2 +1,3 @@
 NorfairKing
 igrep
+mrcjkb
diff --git a/src/Test/Syd/Def/Around.hs b/src/Test/Syd/Def/Around.hs
--- a/src/Test/Syd/Def/Around.hs
+++ b/src/Test/Syd/Def/Around.hs
@@ -207,8 +207,10 @@
               DefDescribeNode t sdf -> DefDescribeNode t $ modifyForest sdf
               DefPendingNode t mr -> DefPendingNode t mr
               DefSpecifyNode t td e -> DefSpecifyNode t (modifyVal <$> td) e
-              DefWrapNode f sdf -> DefWrapNode f $ modifyForest sdf
+              DefSetupNode f sdf -> DefSetupNode f $ modifyForest sdf
               DefBeforeAllNode f sdf -> DefBeforeAllNode f $ modifyForest sdf
+              DefBeforeAllWithNode f sdf -> DefBeforeAllWithNode f $ modifyForest sdf
+              DefWrapNode f sdf -> DefWrapNode f $ modifyForest sdf
               DefAroundAllNode f sdf -> DefAroundAllNode f $ modifyForest sdf
               DefAroundAllWithNode f sdf -> DefAroundAllWithNode f $ modifyForest sdf
               DefAfterAllNode f sdf -> DefAfterAllNode f $ modifyForest sdf
diff --git a/src/Test/Syd/Def/AroundAll.hs b/src/Test/Syd/Def/AroundAll.hs
--- a/src/Test/Syd/Def/AroundAll.hs
+++ b/src/Test/Syd/Def/AroundAll.hs
@@ -16,6 +16,14 @@
 import Test.Syd.HList
 import Test.Syd.SpecDef
 
+-- | Run a custom action before all spec items in a group without setting up any outer resources.
+beforeAll_ ::
+  -- | The function to run (once), beforehand.
+  IO () ->
+  TestDefM outers inner result ->
+  TestDefM outers inner result
+beforeAll_ action = wrapForest $ \forest -> DefSetupNode action forest
+
 -- | Run a custom action before all spec items in a group, to set up an outer resource 'a'.
 beforeAll ::
   -- | The function to run (once), beforehand, to produce the outer resource.
@@ -24,24 +32,22 @@
   TestDefM otherOuters inner result
 beforeAll action = wrapForest $ \forest -> DefBeforeAllNode action forest
 
--- | Run a custom action before all spec items in a group without setting up any outer resources.
-beforeAll_ ::
-  -- | The function to run (once), beforehand.
-  IO () ->
-  TestDefM outers inner result ->
-  TestDefM outers inner result
-beforeAll_ action = aroundAll_ (action >>)
-
 -- | Run a custom action before all spec items in a group, to set up an outer resource 'b' by using the outer resource 'a'.
 beforeAllWith ::
   -- | The function to run (once), beforehand, to produce a new outer resource while using a previous outer resource
   (previousOuter -> IO newOuter) ->
   TestDefM (newOuter ': previousOuter ': otherOuters) inner result ->
   TestDefM (previousOuter ': otherOuters) inner result
-beforeAllWith action = aroundAllWith $ \func b -> do
-  a <- action b
-  func a
+beforeAllWith action = wrapForest $ \forest -> DefBeforeAllWithNode action forest
 
+-- | Run a custom action after all spec items without using any outer resources.
+afterAll_ ::
+  -- | The function to run (once), afterwards.
+  IO () ->
+  TestDefM outers inner result ->
+  TestDefM outers inner result
+afterAll_ action = afterAll' $ \_ -> action
+
 -- | Run a custom action after all spec items, using the outer resource 'a'.
 afterAll ::
   -- | The function to run (once), afterwards, using the outer resource.
@@ -58,24 +64,6 @@
   TestDefM outers inner result
 afterAll' func = wrapForest $ \forest -> DefAfterAllNode func forest
 
--- | Run a custom action after all spec items without using any outer resources.
-afterAll_ ::
-  -- | The function to run (once), afterwards.
-  IO () ->
-  TestDefM outers inner result ->
-  TestDefM outers inner result
-afterAll_ action = afterAll' $ \_ -> action
-
--- | Run a custom action before and/or after all spec items in group, to provide access to a resource 'a'.
---
--- See the @FOOTGUN@ note in the docs for 'around_'.
-aroundAll ::
-  -- | The function that provides the outer resource (once), around the tests.
-  ((outer -> IO ()) -> IO ()) ->
-  TestDefM (outer ': otherOuters) inner result ->
-  TestDefM otherOuters inner result
-aroundAll func = wrapForest $ \forest -> DefAroundAllNode func forest
-
 -- | Run a custom action before and/or after all spec items in a group without accessing any resources.
 --
 -- == __FOOTGUN__
@@ -115,6 +103,16 @@
   TestDefM outers inner result ->
   TestDefM outers inner result
 aroundAll_ func = wrapForest $ \forest -> DefWrapNode func forest
+
+-- | Run a custom action before and/or after all spec items in group, to provide access to a resource 'a'.
+--
+-- See the @FOOTGUN@ note in the docs for 'around_'.
+aroundAll ::
+  -- | The function that provides the outer resource (once), around the tests.
+  ((outer -> IO ()) -> IO ()) ->
+  TestDefM (outer ': otherOuters) inner result ->
+  TestDefM otherOuters inner result
+aroundAll func = wrapForest $ \forest -> DefAroundAllNode func forest
 
 -- | Run a custom action before and/or after all spec items in a group to provide access to a resource 'a' while using a resource 'b'
 --
diff --git a/src/Test/Syd/Output.hs b/src/Test/Syd/Output.hs
--- a/src/Test/Syd/Output.hs
+++ b/src/Test/Syd/Output.hs
@@ -584,8 +584,10 @@
       DefSpecifyNode t _ _ -> T.length t + level * paddingSize
       DefPendingNode t _ -> T.length t + level * paddingSize
       DefDescribeNode _ sdf -> goF (succ level) sdf
-      DefWrapNode _ sdf -> goF level sdf
+      DefSetupNode _ sdf -> goF level sdf
       DefBeforeAllNode _ sdf -> goF level sdf
+      DefBeforeAllWithNode _ sdf -> goF level sdf
+      DefWrapNode _ sdf -> goF level sdf
       DefAroundAllNode _ sdf -> goF level sdf
       DefAroundAllWithNode _ sdf -> goF level sdf
       DefAfterAllNode _ sdf -> goF level sdf
diff --git a/src/Test/Syd/Runner/Asynchronous.hs b/src/Test/Syd/Runner/Asynchronous.hs
--- a/src/Test/Syd/Runner/Asynchronous.hs
+++ b/src/Test/Syd/Runner/Asynchronous.hs
@@ -227,22 +227,36 @@
                   -- done before and after.
                   -- It's not enough to just not have two tests running at the
                   -- same time, because they also need to be executed in order.
-                  when (eParallelism == Sequential) waitForWorkersDone
-                  enqueueJob jobQueue job
-                  when (eParallelism == Sequential) waitForWorkersDone
+                  case eParallelism of
+                    Sequential -> do
+                      waitForWorkersDone
+                      job 0
+                    Parallel -> do
+                      enqueueJob jobQueue job
           DefPendingNode _ _ -> pure ()
           DefDescribeNode _ sdf -> goForest sdf
+          DefSetupNode func sdf -> do
+            liftIO func
+            goForest sdf
+          DefBeforeAllNode func sdf -> do
+            b <- liftIO func
+            withReaderT
+              (\e -> e {eExternalResources = HCons b (eExternalResources e)})
+              (goForest sdf)
+          DefBeforeAllWithNode func sdf -> do
+            e <- ask
+            let HCons x _ = eExternalResources e
+            b <- liftIO $ func x
+            liftIO $
+              runReaderT
+                (goForest sdf)
+                (e {eExternalResources = HCons b (eExternalResources e)})
           DefWrapNode func sdf -> do
             e <- ask
             liftIO $
               func $ do
                 runReaderT (goForest sdf) e
                 waitForWorkersDone
-          DefBeforeAllNode func sdf -> do
-            b <- liftIO func
-            withReaderT
-              (\e -> e {eExternalResources = HCons b (eExternalResources e)})
-              (goForest sdf)
           DefAroundAllNode func sdf -> do
             e <- ask
             liftIO $
@@ -367,8 +381,10 @@
             Nothing -> do
               outputLineP $ outputDescribeLine t
               fmap (DescribeNode t) <$> addLevel (goForest sf)
-        DefWrapNode _ sdf -> fmap SubForestNode <$> goForest sdf
+        DefSetupNode _ sdf -> fmap SubForestNode <$> goForest sdf
         DefBeforeAllNode _ sdf -> fmap SubForestNode <$> goForest sdf
+        DefBeforeAllWithNode _ sdf -> fmap SubForestNode <$> goForest sdf
+        DefWrapNode _ sdf -> fmap SubForestNode <$> goForest sdf
         DefAroundAllNode _ sdf -> fmap SubForestNode <$> goForest sdf
         DefAroundAllWithNode _ sdf -> fmap SubForestNode <$> goForest sdf
         DefAfterAllNode _ sdf -> fmap SubForestNode <$> goForest sdf
@@ -426,8 +442,10 @@
         DefPendingNode t mr -> pure $ Just $ PendingNode t mr
         DefDescribeNode t sf -> do
           fmap (DescribeNode t) <$> goForest sf
-        DefWrapNode _ sdf -> fmap SubForestNode <$> goForest sdf
+        DefSetupNode _ sdf -> fmap SubForestNode <$> goForest sdf
         DefBeforeAllNode _ sdf -> fmap SubForestNode <$> goForest sdf
+        DefBeforeAllWithNode _ sdf -> fmap SubForestNode <$> goForest sdf
+        DefWrapNode _ sdf -> fmap SubForestNode <$> goForest sdf
         DefAroundAllNode _ sdf -> fmap SubForestNode <$> goForest sdf
         DefAroundAllWithNode _ sdf -> fmap SubForestNode <$> goForest sdf
         DefAfterAllNode _ sdf -> fmap SubForestNode <$> goForest sdf
diff --git a/src/Test/Syd/Runner/Synchronous/Interleaved.hs b/src/Test/Syd/Runner/Synchronous/Interleaved.hs
--- a/src/Test/Syd/Runner/Synchronous/Interleaved.hs
+++ b/src/Test/Syd/Runner/Synchronous/Interleaved.hs
@@ -99,9 +99,9 @@
         DefDescribeNode t sdf -> do
           outputLineR $ outputDescribeLine t
           fmap (DescribeNode t) <$> addLevel (goForest sdf)
-        DefWrapNode func sdf -> do
-          e <- ask
-          liftIO $ fmap SubForestNode <$> applySimpleWrapper'' func (runReaderT (goForest sdf) e)
+        DefSetupNode func sdf -> do
+          liftIO func
+          fmap SubForestNode <$> goForest sdf
         DefBeforeAllNode func sdf ->
           fmap SubForestNode
             <$> ( do
@@ -110,6 +110,20 @@
                       (\e -> e {eExternalResources = HCons b (eExternalResources e)})
                       (goForest sdf)
                 )
+        DefBeforeAllWithNode func sdf -> do
+          e <- ask
+          let HCons x _ = eExternalResources e
+          liftIO $
+            fmap SubForestNode
+              <$> ( do
+                      b <- liftIO $ func x
+                      runReaderT
+                        (goForest sdf)
+                        (e {eExternalResources = HCons b (eExternalResources e)})
+                  )
+        DefWrapNode func sdf -> do
+          e <- ask
+          liftIO $ fmap SubForestNode <$> applySimpleWrapper'' func (runReaderT (goForest sdf) e)
         DefAroundAllNode func sdf -> do
           e <- ask
           liftIO $
diff --git a/src/Test/Syd/Runner/Synchronous/Separate.hs b/src/Test/Syd/Runner/Synchronous/Separate.hs
--- a/src/Test/Syd/Runner/Synchronous/Separate.hs
+++ b/src/Test/Syd/Runner/Synchronous/Separate.hs
@@ -58,9 +58,9 @@
         pure $ SpecifyNode t <$> r
       DefPendingNode t mr -> pure $ Continue $ PendingNode t mr
       DefDescribeNode t sdf -> fmap (DescribeNode t) <$> goForest sdf
-      DefWrapNode func sdf -> do
-        e <- ask
-        liftIO $ fmap SubForestNode <$> applySimpleWrapper'' func (runReaderT (goForest sdf) e)
+      DefSetupNode func sdf -> do
+        liftIO func
+        fmap SubForestNode <$> goForest sdf
       DefBeforeAllNode func sdf -> do
         fmap SubForestNode
           <$> ( do
@@ -69,6 +69,20 @@
                     (\e -> e {eExternalResources = HCons b (eExternalResources e)})
                     (goForest sdf)
               )
+      DefBeforeAllWithNode func sdf -> do
+        e <- ask
+        let HCons x _ = eExternalResources e
+        liftIO $
+          fmap SubForestNode
+            <$> ( do
+                    b <- liftIO (func x)
+                    runReaderT
+                      (goForest sdf)
+                      (e {eExternalResources = HCons b (eExternalResources e)})
+                )
+      DefWrapNode func sdf -> do
+        e <- ask
+        liftIO $ fmap SubForestNode <$> applySimpleWrapper'' func (runReaderT (goForest sdf) e)
       DefAroundAllNode func sdf -> do
         e <- ask
         liftIO $
diff --git a/src/Test/Syd/SpecDef.hs b/src/Test/Syd/SpecDef.hs
--- a/src/Test/Syd/SpecDef.hs
+++ b/src/Test/Syd/SpecDef.hs
@@ -80,9 +80,9 @@
     Text ->
     SpecDefForest outers inner extra ->
     SpecDefTree outers inner extra
-  DefWrapNode ::
-    -- | The function that wraps running the tests.
-    (IO () -> IO ()) ->
+  DefSetupNode ::
+    -- | The function that runs before the test
+    IO () ->
     SpecDefForest outers inner extra ->
     SpecDefTree outers inner extra
   DefBeforeAllNode ::
@@ -90,6 +90,16 @@
     IO outer ->
     SpecDefForest (outer ': otherOuters) inner extra ->
     SpecDefTree otherOuters inner extra
+  DefBeforeAllWithNode ::
+    -- | The function to run (once), beforehand, to produce the outer resource.
+    (oldOuter -> IO newOuter) ->
+    SpecDefForest (newOuter ': oldOuter ': otherOuters) inner extra ->
+    SpecDefTree (oldOuter ': otherOuters) inner extra
+  DefWrapNode ::
+    -- | The function that wraps running the tests.
+    (IO () -> IO ()) ->
+    SpecDefForest outers inner extra ->
+    SpecDefTree outers inner extra
   DefAroundAllNode ::
     -- | The function that provides the outer resource (once), around the tests.
     ((outer -> IO ()) -> IO ()) ->
@@ -142,8 +152,10 @@
           DefDescribeNode t sdf -> DefDescribeNode t $ goF sdf
           DefPendingNode t mr -> DefPendingNode t mr
           DefSpecifyNode t td e -> DefSpecifyNode t td (f e)
-          DefWrapNode func sdf -> DefWrapNode func $ goF sdf
+          DefSetupNode func sdf -> DefSetupNode func $ goF sdf
           DefBeforeAllNode func sdf -> DefBeforeAllNode func $ goF sdf
+          DefBeforeAllWithNode func sdf -> DefBeforeAllWithNode func $ goF sdf
+          DefWrapNode func sdf -> DefWrapNode func $ goF sdf
           DefAroundAllNode func sdf -> DefAroundAllNode func $ goF sdf
           DefAroundAllWithNode func sdf -> DefAroundAllWithNode func $ goF sdf
           DefAfterAllNode func sdf -> DefAfterAllNode func $ goF sdf
@@ -162,8 +174,10 @@
           DefDescribeNode _ sdf -> goF sdf
           DefPendingNode _ _ -> mempty
           DefSpecifyNode _ _ e -> f e
-          DefWrapNode _ sdf -> goF sdf
+          DefSetupNode _ sdf -> goF sdf
           DefBeforeAllNode _ sdf -> goF sdf
+          DefBeforeAllWithNode _ sdf -> goF sdf
+          DefWrapNode _ sdf -> goF sdf
           DefAroundAllNode _ sdf -> goF sdf
           DefAroundAllWithNode _ sdf -> goF sdf
           DefAfterAllNode _ sdf -> goF sdf
@@ -182,8 +196,10 @@
           DefDescribeNode t sdf -> DefDescribeNode t <$> goF sdf
           DefPendingNode t mr -> pure $ DefPendingNode t mr
           DefSpecifyNode t td e -> DefSpecifyNode t td <$> f e
-          DefWrapNode func sdf -> DefWrapNode func <$> goF sdf
+          DefSetupNode func sdf -> DefSetupNode func <$> goF sdf
           DefBeforeAllNode func sdf -> DefBeforeAllNode func <$> goF sdf
+          DefBeforeAllWithNode func sdf -> DefBeforeAllWithNode func <$> goF sdf
+          DefWrapNode func sdf -> DefWrapNode func <$> goF sdf
           DefAroundAllNode func sdf -> DefAroundAllNode func <$> goF sdf
           DefAroundAllWithNode func sdf -> DefAroundAllWithNode func <$> goF sdf
           DefAfterAllNode func sdf -> DefAfterAllNode func <$> goF sdf
@@ -218,8 +234,10 @@
         guard $ filterGuard tl
         pure $ DefPendingNode t mr
       DefDescribeNode t sdf -> DefDescribeNode t <$> goForest (DList.snoc dl t) sdf
-      DefWrapNode func sdf -> DefWrapNode func <$> goForest dl sdf
+      DefSetupNode func sdf -> DefSetupNode func <$> goForest dl sdf
       DefBeforeAllNode func sdf -> DefBeforeAllNode func <$> goForest dl sdf
+      DefBeforeAllWithNode func sdf -> DefBeforeAllWithNode func <$> goForest dl sdf
+      DefWrapNode func sdf -> DefWrapNode func <$> goForest dl sdf
       DefAroundAllNode func sdf -> DefAroundAllNode func <$> goForest dl sdf
       DefAroundAllWithNode func sdf -> DefAroundAllWithNode func <$> goForest dl sdf
       DefAfterAllNode func sdf -> DefAfterAllNode func <$> goForest dl sdf
@@ -239,8 +257,10 @@
       DefSpecifyNode t td e -> pure $ DefSpecifyNode t td e
       DefPendingNode t mr -> pure $ DefPendingNode t mr
       DefDescribeNode t sdf -> DefDescribeNode t <$> goForest sdf
-      DefWrapNode func sdf -> DefWrapNode func <$> goForest sdf
+      DefSetupNode func sdf -> DefSetupNode func <$> goForest sdf
       DefBeforeAllNode func sdf -> DefBeforeAllNode func <$> goForest sdf
+      DefBeforeAllWithNode func sdf -> DefBeforeAllWithNode func <$> goForest sdf
+      DefWrapNode func sdf -> DefWrapNode func <$> goForest sdf
       DefAroundAllNode func sdf -> DefAroundAllNode func <$> goForest sdf
       DefAroundAllWithNode func sdf -> DefAroundAllWithNode func <$> goForest sdf
       DefAfterAllNode func sdf -> DefAfterAllNode func <$> goForest sdf
@@ -264,8 +284,10 @@
       DefSpecifyNode t _ _ -> DefPendingNode t mMessage
       DefPendingNode t mr -> DefPendingNode t mr
       DefDescribeNode t sdf -> DefDescribeNode t $ goForest sdf
-      DefWrapNode func sdf -> DefWrapNode func $ goForest sdf
+      DefSetupNode func sdf -> DefSetupNode func $ goForest sdf
       DefBeforeAllNode func sdf -> DefBeforeAllNode func $ goForest sdf
+      DefBeforeAllWithNode func sdf -> DefBeforeAllWithNode func $ goForest sdf
+      DefWrapNode func sdf -> DefWrapNode func $ goForest sdf
       DefAroundAllNode func sdf -> DefAroundAllNode func $ goForest sdf
       DefAroundAllWithNode func sdf -> DefAroundAllWithNode func $ goForest sdf
       DefAfterAllNode func sdf -> DefAfterAllNode func $ goForest sdf
diff --git a/sydtest.cabal b/sydtest.cabal
--- a/sydtest.cabal
+++ b/sydtest.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           sydtest
-version:        0.14.0.0
+version:        0.15.0.0
 synopsis:       A modern testing framework for Haskell with good defaults and advanced testing features.
 description:    A modern testing framework for Haskell with good defaults and advanced testing features. Sydtest aims to make the common easy and the hard possible. See https://github.com/NorfairKing/sydtest#readme for more information.
 category:       Testing
