diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,16 @@
 [1]: http://semver.org/spec/v2.0.0.html
 [2]: https://github.com/roman/Haskell-teardown/libraries/teardown/CHANGELOG.md
 
+## v0.4.1.0
+
+* Ensure that all `IO ()` sub-routines on `runTeardown` get executed inside a
+  `MaskedUninterruptible` masking state
+* Deprecate the `[(Text, IO ())]` instance of `IResource` in favor of creating a
+  teardown record per de-allocated resource.
+* Replace `criterion` in favor of `gauge`
+* Bump `rio` to v0.1.1.0
+* Improve upon documentation
+
 ## v0.4.0.0
 
 **BREAKING CHANGES**
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@
 ## Development
 
 [![Build Status](https://travis-ci.org/roman/Haskell-teardown.svg?branch=master)](https://travis-ci.org/roman/Haskell-teardown)
-[![Github](https://img.shields.io/github/commits-since/roman/haskell-teardown/v0.1.0.1.svg)](https://img.shields.io/github/commits-since/roman/haskell-teardown/v0.1.0.1.svg)
+[![Github](https://img.shields.io/github/commits-since/roman/haskell-teardown/v0.4.0.0.svg)](https://img.shields.io/github/commits-since/roman/haskell-teardown/v0.4.0.0.svg)
 [![Hackage Dependencies](https://img.shields.io/hackage-deps/v/teardown.svg)](http://packdeps.haskellers.com/feed?needle=teardown)
 
 Follow the [developer guidelines](https://romanandreg.gitbooks.io/teardown/content/CONTRIBUTING.html)
diff --git a/benchmark/Main.hs b/benchmark/Main.hs
--- a/benchmark/Main.hs
+++ b/benchmark/Main.hs
@@ -1,11 +1,16 @@
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE OverloadedStrings #-}
 module Main where
 
 import RIO
 
-import Criterion
-import Criterion.Main
+#if MIN_VERSION_gauge(0,2,0)
+import Gauge
+#else
+import Gauge
+import Gauge.Main (defaultMain)
+#endif
 
 import Control.Teardown (newTeardown, runTeardown_)
 
@@ -20,4 +25,9 @@
           bench "with teardown" (whnfIO $ runTeardown_ unitTeardown)
         )
       ]
+  , env
+      (sequence (replicate 1000 (newTeardown "benchmark" (return () :: IO ())))
+       >>= newTeardown "parent")
+      (\composedTeardown ->
+          bench "teardown list" (whnfIO $ runTeardown_ composedTeardown))
   ]
diff --git a/src/Control/Teardown/Internal/Core.hs b/src/Control/Teardown/Internal/Core.hs
--- a/src/Control/Teardown/Internal/Core.hs
+++ b/src/Control/Teardown/Internal/Core.hs
@@ -1,4 +1,6 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 module Control.Teardown.Internal.Core
@@ -10,6 +12,7 @@
 
   , runTeardown
   , runTeardown_
+  , newTeardown
   )
 where
 
@@ -17,6 +20,10 @@
 
 import RIO.Time (NominalDiffTime, diffUTCTime, getCurrentTime)
 
+#if MIN_VERSION_base(4,11,0)
+import qualified GHC.TypeLits as Ty
+#endif
+
 import Control.Teardown.Internal.Types
 
 --------------------------------------------------------------------------------
@@ -42,7 +49,7 @@
 
   EmptyResult{}  -> False
 
--- | Creates a new "Teardown" sub-routine from a cleanup "IO" action, the
+-- | Creates a new "Teardown" record from a cleanup "IO" action, the
 -- side-effects from this action are guaranteed to be executed only once, and
 -- also it is guaranteed to be thread-safe in the scenario of multiple threads
 -- executing the same teardown procedure.
@@ -80,11 +87,6 @@
 
   return $ BranchResult desc elapsed teardownFailed teardownResults
 
--- | Creates a "Teardown" sub-routine that is composed of inner sub-routines
---  that are allocated at runtime. This is useful if allocations are being
---  created and being hold on a Mutable variable of some sort (e.g. "IORef",
---  "TVar", etc) so that on cleanup this Mutable variable is read and the
---  results of the teardown operation are returned.
 newDynTeardown :: Description -> IO [TeardownResult] -> Teardown
 newDynTeardown desc action = Teardown $ do
   teardownResults <- action
@@ -99,6 +101,7 @@
 --  expects a teardown return but there is no allocation being made
 emptyTeardown :: Description -> Teardown
 emptyTeardown desc = Teardown (return $ emptyTeardownResult desc)
+{-# INLINE emptyTeardown #-}
 
 --------------------------------------------------------------------------------
 
@@ -120,13 +123,14 @@
       let result = map (foldTeardownResult leafStep branchStep acc) results
       in  branchStep result desc
 
--- | Returns number of sub-routines executed at teardown
+-- | Returns number of released resources from a "runTeardown" execution
 toredownCount :: TeardownResult -> Int
 toredownCount =
   foldTeardownResult (\acc _ _ -> acc + 1) (\results _ -> sum results) 0
+{-# INLINE toredownCount #-}
 
 -- | Returns number of sub-routines that threw an exception on execution of
--- teardown
+-- "runTeardown"
 failedToredownCount :: TeardownResult -> Int
 failedToredownCount = foldTeardownResult
   (\acc _ mErr -> acc + maybe 0 (const 1) mErr)
@@ -137,26 +141,45 @@
 
 instance HasTeardown Teardown where
   getTeardown = id
+  {-# INLINE getTeardown #-}
 
--- | Creates a Teardown record from a simple `IO ()` sub-routine
+-- | Creates a new "Teardown" record from a cleanup "IO ()" sub-routine; the
+-- Teardown API guarantees:
+--
+-- * The execution of given "IO ()" sub-routine happens exactly once
+-- * The execution is thread-safe when multiple threads try to call "runTeardown"
+--
+-- IMPORTANT: The @IO ()@ sub-routine _must not_ block or take a long time; this
+-- sub-routine cannot be stopped by an async exception
 instance IResource (IO ()) where
   newTeardown =
     newTeardownIO
+  {-# INLINE newTeardown #-}
 
--- | Creates a Teardown record from a simple list of cleanup sub-routines
--- (creating a Teardown record for each), ideal when one single component has
--- many resources allocated and need to be cleaned out all at once.
+-- | Deprecated instance that creates a Teardown record from a list of cleanup
+-- sub-routines (creating a Teardown record for each).
 --
+-- WARNING: This function assumes you are creating many sub-resources at once;
+-- this approach has a major risk of leaking resources, and that is why is
+-- deprecated; execute newTeardown for every resource you allocate.
+--
 -- NOTE: The @IO ()@ sub-routines given are going to be executed in reverse
 -- order at teardown time.
 --
+-- Since 0.4.1.0
+#if MIN_VERSION_base(4,11,0)
+instance Ty.TypeError ('Ty.Text "DEPRECATED: Execute a 'newTeardown' call per allocated resource")
+  => IResource [(Text, IO ())] where
+  newTeardown desc actionList =
+    concatTeardown desc <$> mapM (uncurry newTeardown) actionList
+#else
 instance IResource [(Text, IO ())] where
   newTeardown desc actionList =
     concatTeardown desc <$> mapM (uncurry newTeardown) actionList
+#endif
 
--- | Wraps a "Teardown" record; the new record will have one extra level of
--- description.
---
+-- | Wraps an existing "Teardown" record; the wrapper "Teardown" record represents
+-- a "parent resource" on the "TeardownResult"
 instance IResource Teardown where
   newTeardown desc =
     return . concatTeardown desc . return
@@ -168,6 +191,7 @@
 instance IResource [Teardown] where
   newTeardown desc =
     return . concatTeardown desc
+  {-# INLINE newTeardown #-}
 
 -- | Wraps an IO action that returns a list of "Teardown" record; the new record
 -- will have one extra level of description. Same behaviour as the @[(Text, IO
@@ -177,24 +201,28 @@
 instance IResource (IO [Teardown]) where
   newTeardown desc getTeardownList =
     concatTeardown desc <$> getTeardownList
+  {-# INLINE newTeardown #-}
 
--- | Creates a "Teardown" sub-routine that is composed of inner sub-routines
---  that are allocated at runtime. This is useful if allocations are being
---  created and being hold on a Mutable variable of some sort (e.g. "IORef",
---  "TVar", etc) so that on teardown time this Mutable variable is read and
---  executed and the results are returned.
+-- | Creates a "Teardown" record from executing a sub-routine that releases
+--  short-lived "Teardown" records. This is useful when short-lived "Teardown"
+--  are accumulated on a collection inside a mutable variable (e.g. @IORef@,
+--  @TVar@, etc) and we want to release them
 instance IResource (IO [TeardownResult]) where
   newTeardown desc =
     return . newDynTeardown desc
+  {-# INLINE newTeardown #-}
 
 --------------------------------------------------------------------------------
 
--- | Executes all composed "Teardown" sub-routines safely, and returns a Tree
--- data structure wich can be used to gather facts from the cleanup process.
+-- | Executes all composed "Teardown" sub-routines safely. This version returns
+-- a Tree data structure wich can be used to gather facts from the resource
+-- cleanup
 runTeardown :: HasTeardown t => t -> IO TeardownResult
 runTeardown t0 =
-  let (Teardown teardownAction) = getTeardown t0 in teardownAction
+  let (Teardown teardownAction) = getTeardown t0 in uninterruptibleMask_ teardownAction
+{-# INLINE runTeardown #-}
 
--- | Executes all composed "Teardown" sub-routines safely.
+-- | Executes all composed "Teardown" sub-routines safely
 runTeardown_ :: HasTeardown t => t -> IO ()
 runTeardown_ = void . runTeardown
+{-# INLINE runTeardown_ #-}
diff --git a/src/Control/Teardown/Internal/Printer.hs b/src/Control/Teardown/Internal/Printer.hs
--- a/src/Control/Teardown/Internal/Printer.hs
+++ b/src/Control/Teardown/Internal/Printer.hs
@@ -2,12 +2,14 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Control.Teardown.Internal.Printer where
 
-import RIO
+import Data.Monoid ((<>))
+import RIO         hiding ((<>))
 
 import           Data.Typeable (typeOf)
 import qualified RIO.Text      as Text
 
 import Text.PrettyPrint.ANSI.Leijen hiding ((<>))
+
 
 import Control.Teardown.Internal.Types
 
diff --git a/teardown.cabal b/teardown.cabal
--- a/teardown.cabal
+++ b/teardown.cabal
@@ -1,5 +1,5 @@
 name: teardown
-version: 0.4.0.0
+version: 0.4.1.0
 cabal-version: >=1.10
 build-type: Simple
 license: MIT
@@ -9,16 +9,15 @@
 stability: alpha (experimental)
 homepage: https://github.com/roman/Haskell-teardown#readme
 bug-reports: https://github.com/roman/Haskell-teardown/issues
-synopsis: Build composable components for your application with clear teardown semantics
+synopsis: Build safe and composable teardown sub-routines for resources
 description:
     The teardown library allows you to reliably execute cleanup sub-routines for
-    allocated resources when a program is initialized; it:
+    allocated resources. When a program is initialized, it:
     .
-    * Ensures that teardown sub-routines are executed /exactly/ once, even on the
-    scenario where cleanup is invoked multiple times
+    * Ensures that teardown sub-routines are executed /exactly/ once
     .
-    * Ensures that if errors occur on the execution of one teardown, the error
-    does not propagate to other sub-routines; effectively keeping them isolated.
+    * Ensures that if errors occur on the execution of a Teardown sub-routine, the
+    error does not propagate to others; bulkheading failure on cleanup.
     .
     * Requires every sub-routine to be documented at creation time; thus helping
     tracing your application structure.
@@ -76,7 +75,7 @@
     main-is: Main.hs
     build-depends:
         base >=4.8 && <5,
-        criterion >=1.1,
+        gauge >=0.1.3,
         rio >=0.0.0.0,
         teardown -any,
         typed-process >=0.1.0.0,
diff --git a/test/tasty/TeardownTest.hs b/test/tasty/TeardownTest.hs
--- a/test/tasty/TeardownTest.hs
+++ b/test/tasty/TeardownTest.hs
@@ -4,9 +4,10 @@
 
 import RIO
 
-import           Control.Monad    (replicateM)
-import qualified Control.Teardown as SUT
-import           Test.Tasty       (TestTree, testGroup)
+import           Control.Exception (MaskingState (..), getMaskingState)
+import           Control.Monad     (replicateM)
+import qualified Control.Teardown  as SUT
+import           Test.Tasty        (TestTree, testGroup)
 import           Test.Tasty.HUnit
 
 
@@ -87,38 +88,12 @@
         assertEqual "failed teardown action must be correct"
                     5
                     (SUT.failedToredownCount toredownResult)
-  , testCase "teardown with list of description and actions executes correctly"
-    $ do
-        callCountRef   <- newIORef (0 :: Int)
-        teardownAction <- SUT.newTeardown
-          "bigger-system"
-          [ ("1" :: Text, modifyIORef callCountRef (+ 1) :: IO ())
-          , ("2"        , modifyIORef callCountRef (+ 1))
-          , ("3"        , modifyIORef callCountRef (+ 1))
-          , ("4"        , modifyIORef callCountRef (+ 1))
-          , ("5"        , modifyIORef callCountRef (+ 1))
-          , ("6"        , error "nope")
-          , ("7"        , error "nope")
-          , ("8"        , error "nope")
-          , ("9"        , error "nope")
-          ]
-
-
-        -- Execute multiple times to assert idempotency
-        toredownResult <- SUT.runTeardown teardownAction
-        replicateM_ 9 (SUT.runTeardown teardownAction)
-
-        assertEqual "teardown action count must be correct"
-                    9
-                    (SUT.toredownCount toredownResult)
-
-        assertEqual "failed teardown must be correct"
-                    4
-                    (SUT.failedToredownCount toredownResult)
-
-        callCount <- readIORef callCountRef
-        assertEqual
-          "side-effects were executed despite errors on other teardown operations"
-          5
-          callCount
+  , testCase "Teardown sub-routine executes on an uninterruptedMask" $ do
+    resultVar <- newEmptyMVar
+    teardown  <- SUT.newTeardown "test" (getMaskingState >>= putMVar resultVar)
+    SUT.runTeardown_ teardown
+    masking <- takeMVar resultVar
+    assertEqual "Expecting Teardown masked state is Uninterruptible"
+                MaskedUninterruptible
+                masking
   ]
