diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
 Changelog for tmp-postgres
 
+1.33.0.0
+  #240 cacheAction should create the parent directories
+
 1.32.0.1
   #234 Extend core with a initdb cache primitive
   #232 Fix multithread initdb creation bug
diff --git a/src/Database/Postgres/Temp/Internal.hs b/src/Database/Postgres/Temp/Internal.hs
--- a/src/Database/Postgres/Temp/Internal.hs
+++ b/src/Database/Postgres/Temp/Internal.hs
@@ -24,6 +24,7 @@
 import           Text.PrettyPrint.ANSI.Leijen hiding ((<$>))
 import           System.Directory
 import           System.Directory.Internal.Prelude
+import           System.FilePath
 
 -- | Handle for holding temporary resources, the @postgres@ process handle
 --   and @postgres@ connection information. The 'DB' also includes the
@@ -681,7 +682,7 @@
 remigrate as long as the migration does not change. See 'withSnapshot' for
 a ephemeral version of taking snapshots.
 
-@since 1.32.0.0
+@since 1.33.0.0
 -}
 cacheAction
   :: FilePath
@@ -694,8 +695,10 @@
 cacheAction cachePath action config = do
   fixCachePath <- fixPath cachePath
   let result = config <> fromFilePathConfig fixCachePath
+      parentPath = joinPath $ init $ splitPath fixCachePath
 
-  -- TODO document the change in behavior
+  createDirectoryIfMissing True parentPath
+
   preexisting <- try (createDirectory fixCachePath) >>= \case
     Left e | isAlreadyExistsError e -> pure True
     Left e -> throwIO e
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -594,7 +594,7 @@
             snapshotConfigAndAssert
             testSuccessfulConfig
 
-  it "doesn't create the cache if it exists" $ do
+  it "doesnt create the cache if it exists" $ do
     let action db = withConn db $ \conn -> do
           _ <- PG.execute_ conn "BEGIN; CREATE TABLE foo ( id int );"
           void $ PG.execute_ conn "INSERT INTO foo (id) VALUES (1); END;"
@@ -657,6 +657,29 @@
 
       cacheAction theFinalCachePath action defaultConfig >>= \case
         Left err -> fail $ "First call should succeed but failed with " <> show err
+        Right _ -> pure ()
+
+  it "doesnt deadlock if the parent directory is missing" $ do
+    withTempDirectory "/tmp" "tmp-postgres-cache-action" $ \cachePath -> do
+      let theFinalCachePath = cachePath <> "/parent/child"
+      cacheAction theFinalCachePath (const $ pure ()) defaultConfig >>=  \case
+        Left err -> fail $ "First call should succeed but failed with " <> show err
+        Right _ -> pure ()
+
+  it "doesnt deadlock if the parent directory is missing multithreaded version" $ do
+    withTempDirectory "/tmp" "tmp-postgres-cache-action" $ \cachePath -> do
+      let theFinalCachePath = cachePath <> "/parent/child"
+          threadBody = cacheAction theFinalCachePath (const $ pure ()) defaultConfig
+
+      thread1 <- Async.async threadBody
+      thread2 <- Async.async threadBody
+
+      Async.wait thread1 >>= \case
+        Left err -> fail $ "First call should succeed but failed with " <> show err
+        Right _ -> pure ()
+
+      Async.wait thread2 >>= \case
+        Left err -> fail $ "Second call should succeed but failed with " <> show err
         Right _ -> pure ()
 
 spec :: Spec
diff --git a/tmp-postgres.cabal b/tmp-postgres.cabal
--- a/tmp-postgres.cabal
+++ b/tmp-postgres.cabal
@@ -1,5 +1,5 @@
 name:                tmp-postgres
-version:             1.32.0.1
+version:             1.33.0.0
 synopsis: Start and stop a temporary postgres
 description: Start and stop a temporary postgres. See README.md
 homepage:            https://github.com/jfischoff/tmp-postgres#readme
@@ -47,6 +47,7 @@
                , cryptohash-sha1
                , deepseq
                , directory
+               , filepath
                , generic-monoid
                , port-utils
                , postgres-options >= 0.2.0.0
