diff --git a/library/Potoki/Core/Fetch.hs b/library/Potoki/Core/Fetch.hs
--- a/library/Potoki/Core/Fetch.hs
+++ b/library/Potoki/Core/Fetch.hs
@@ -119,7 +119,7 @@
       (!headVal) : (!tailVal) -> do
         writeIORef unsentListRef tailVal
         return $ Just headVal
-      _              -> do
+      _ -> do
         writeIORef unsentListRef []
         return Nothing
 
@@ -129,7 +129,7 @@
   Fetch $ do
     bothFetch <- bothFetchIO
     case bothFetch of
-      Nothing                -> return Nothing
+      Nothing -> return Nothing
       Just (!firstVal, !secondVal) -> do
         writeIORef cacheRef secondVal
         return $ Just firstVal
@@ -140,7 +140,7 @@
   Fetch $ do
     firstFetch <- firstFetchIO
     case firstFetch of
-      Nothing            -> return Nothing
+      Nothing -> return Nothing
       Just !firstFetched -> do
         secondCached <- readIORef cacheRef
         return $ Just (firstFetched, secondCached)
@@ -151,7 +151,7 @@
   Fetch $ do
     eitherFetch <- eitherFetchIO
     case eitherFetch of
-      Nothing    -> return Nothing
+      Nothing -> return Nothing
       Just input -> case input of
         Right rightInput -> return $ Just rightInput
         Left  leftInput  -> left2IO leftInput $> Nothing
diff --git a/library/Potoki/Core/TextBuilder.hs b/library/Potoki/Core/TextBuilder.hs
new file mode 100644
--- /dev/null
+++ b/library/Potoki/Core/TextBuilder.hs
@@ -0,0 +1,20 @@
+module Potoki.Core.TextBuilder
+where
+
+import Potoki.Core.Prelude
+import Text.Builder
+
+
+count :: Int -> Builder
+count = thousandSeparatedUnsignedDecimal ','
+
+streamProgressMessage :: Int -> Int -> Builder
+streamProgressMessage progress total =
+  "Processed " <> count progress <> " elements (" <>
+  count total <> " in total)"
+
+indexationSummary :: Int -> Int -> Builder
+indexationSummary userAmount uriAmount =
+  "Got the following amounts of nodes:\n" <>
+  "\tUsers: " <> count userAmount <> "\n" <>
+  "\tUris: " <> count uriAmount
diff --git a/library/Potoki/Core/Transform.hs b/library/Potoki/Core/Transform.hs
--- a/library/Potoki/Core/Transform.hs
+++ b/library/Potoki/Core/Transform.hs
@@ -19,6 +19,8 @@
   distinct,
   executeIO,
   mapInIO,
+  reportProgress,
+  handleProgressAndCountOnInterval,
   -- * ByteString
   builderChunks,
   extractLines,
diff --git a/library/Potoki/Core/Transform/Basic.hs b/library/Potoki/Core/Transform/Basic.hs
--- a/library/Potoki/Core/Transform/Basic.hs
+++ b/library/Potoki/Core/Transform/Basic.hs
@@ -9,6 +9,8 @@
 import qualified Acquire.Acquire as M
 import qualified Data.Vector.Generic.Mutable as MutableGenericVector
 import qualified Data.Vector.Generic as GenericVector
+import qualified Text.Builder as TextBuilder
+import qualified Potoki.Core.TextBuilder as TextBuilder
 
 
 {-# INLINE mapFilter #-}
@@ -308,4 +310,15 @@
             fetchIO
           else
             return Nothing
-      
+
+reportProgress :: (Text -> IO ()) -> Transform a a
+reportProgress log = handleProgressAndCountOnInterval 1 $ \ progress count ->
+  log $ TextBuilder.run $ TextBuilder.streamProgressMessage progress count
+
+handleProgressAndCountOnInterval :: NominalDiffTime -> (Int -> Int -> IO ()) -> Transform a a
+handleProgressAndCountOnInterval interval handle = ioTransform $ do
+  lastCountRef <- newIORef 0
+  return $ handleCountOnInterval interval $ \ count -> do
+    lastCount <- readIORef lastCountRef
+    writeIORef lastCountRef count
+    handle (count - lastCount) count
diff --git a/library/Potoki/Core/Transform/Instances.hs b/library/Potoki/Core/Transform/Instances.hs
--- a/library/Potoki/Core/Transform/Instances.hs
+++ b/library/Potoki/Core/Transform/Instances.hs
@@ -23,16 +23,16 @@
       fetchedLeftMaybeRef <- liftIO $ newIORef Nothing
       Fetch rightFetchIO <- rightTransformAcquire (A.rightHandlingLeft (writeIORef fetchedLeftMaybeRef . Just) inFetch)
       return $ Fetch $ do
-          rightFetch <- rightFetchIO
-          case rightFetch of
-            Nothing    -> do
-              fetchedLeftMaybe <- readIORef fetchedLeftMaybeRef
-              case fetchedLeftMaybe of
-                Nothing          -> return Nothing
-                Just fetchedLeft -> do
-                  writeIORef fetchedLeftMaybeRef Nothing
-                  return $ Just (Left fetchedLeft)
-            Just element -> return $ Just (Right element)
+        rightFetch <- rightFetchIO
+        case rightFetch of
+          Nothing -> do
+            fetchedLeftMaybe <- readIORef fetchedLeftMaybeRef
+            case fetchedLeftMaybe of
+              Nothing -> return Nothing
+              Just fetchedLeft -> do
+                writeIORef fetchedLeftMaybeRef Nothing
+                return $ Just (Left fetchedLeft)
+          Just element -> return $ Just (Right element)
 
 instance Strong Transform where
   first' (Transform firstTransformAcquire) =
diff --git a/potoki-core.cabal b/potoki-core.cabal
--- a/potoki-core.cabal
+++ b/potoki-core.cabal
@@ -1,5 +1,5 @@
 name: potoki-core
-version: 2.3.1
+version: 2.3.2
 synopsis: Low-level components of "potoki"
 description:
   Provides everything required for building custom instances of
@@ -33,6 +33,7 @@
     Potoki.Core.IO
     Potoki.Core.Transform
   other-modules:
+    Potoki.Core.TextBuilder
     Potoki.Core.Types
     Potoki.Core.Prelude
     Potoki.Core.Transform.Attoparsec
@@ -59,6 +60,7 @@
     scanner >=0.3 && <0.4,
     stm >=2.4 && <3,
     text >=1 && <2,
+    text-builder >=0.6.3 && <0.7,
     time >=1.5 && <2,
     transformers >=0.5 && <0.6,
     unordered-containers >=0.2 && <0.3,
