diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -2,6 +2,16 @@
 
 `mem-info` uses [PVP Versioning][1].
 
+## 0.4.2.0 -- 2026-02-11
+
+- Add the function `selfId` to System.MemInfo to allow the current process
+  to access its own process information
+
+- Adds `printUsages` and `defaultRoot` as exports to System.MemInfo
+
+- Add an example executable `mem_pids` that uses System.MemInfo functions as
+  library functions
+
 ## 0.4.1.2 -- 2026-01-14
 
 - Relax the upper bound on the containers dependency
@@ -21,7 +31,7 @@
   Used to specify an alternate process root than the default, _/proc_. This
   allows reporting of process status for other machines whose proc information
   has been mounted or synced to a local filesystem
-  
+
 - Breaking changes:
 
   - [ProcNamer][2] takes an additional argument that specifies the proc filesystem root
diff --git a/exe/MemPids.hs b/exe/MemPids.hs
new file mode 100644
--- /dev/null
+++ b/exe/MemPids.hs
@@ -0,0 +1,46 @@
+{- |
+Module      : MemPids
+Copyright   : (c) 2022 Tim Emiola
+Maintainer  : Tim Emiola <adetokunbo@emio.la>
+SPDX-License-Identifier: BSD3
+
+An example program that prints the usage of a specified processes.
+-}
+module Main (main) where
+
+import Data.List.NonEmpty (NonEmpty ((:|)))
+import System.Environment (getArgs)
+import System.MemInfo (
+  defaultRoot,
+  mkReportBud,
+  printUsage,
+  printUsages,
+  readForOnePid,
+  readMemUsage,
+  selfId',
+ )
+import Text.Read (readEither)
+
+
+main :: IO ()
+main = do
+  let readPrintPid p = readForOnePid p >>= ifOkDo printUsage
+      readProcID = either (const $ Left "bad pid") Right . readEither
+      toProcessID = ifOkDo pure . readProcID
+  args <- getArgs
+  case args of
+    [] -> selfId' >>= readPrintPid
+    [x] -> toProcessID x >>= readPrintPid
+    xs -> do
+      let toEither = maybe (Left "odd: could not make a bud") Right
+          mkReportBud' root pids = mkReportBud root pids >>= pure . toEither
+      n : ns <- mapM toProcessID xs
+      mkReportBud' defaultRoot (n :| ns) >>= ifOkDo readMemUsage >>= ifOkDo printUsages
+
+
+ifOkDo :: (Show a) => (b -> IO c) -> Either a b -> IO c
+ifOkDo =
+  let core = "Usage: mem_pids [args]"
+      fail' x | show x == "" = fail core
+      fail' x = fail $ core ++ ": error: " ++ show x
+   in either fail'
diff --git a/mem-info.cabal b/mem-info.cabal
--- a/mem-info.cabal
+++ b/mem-info.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               mem-info
-version:            0.4.1.2
+version:            0.4.2.0
 synopsis:           Print the core memory usage of programs
 description:
   A utility to accurately report the core memory usage of programs.
@@ -101,6 +101,19 @@
 -- printmem is the printmem command
 executable printmem
   main-is:          PrintMem.hs
+  hs-source-dirs:   exe
+  default-language: Haskell2010
+  build-depends:
+    , base         >=4.14 && <5
+    , mem-info
+
+  ghc-options:      -threaded -rtsopts -with-rtsopts=-N
+  ghc-options:
+    -Wall -Wincomplete-uni-patterns -Wpartial-fields -fwarn-tabs
+
+-- mem_pids is an example that reports the usage of one or many pids
+executable mem_pids
+  main-is:          MemPids.hs
   hs-source-dirs:   exe
   default-language: Haskell2010
   build-depends:
diff --git a/src/System/MemInfo.hs b/src/System/MemInfo.hs
--- a/src/System/MemInfo.hs
+++ b/src/System/MemInfo.hs
@@ -49,15 +49,22 @@
   -- * Print /MemUsage/
   printUsage',
   printUsage,
+  printUsages,
 
+  -- * The current process ID
+  selfId,
+  selfId',
+
   -- * Convenient re-exports
   mkReportBud,
+  defaultRoot,
   ProcessID,
   AsCmdName (..),
 ) where
 
+import Control.Exception (Exception)
 import Control.Monad.IO.Class (MonadIO, liftIO)
-import Control.Monad.Reader (MonadReader (ask), runReaderT)
+import Control.Monad.Reader (MonadReader (ask), asks, runReaderT)
 import Data.Bifunctor (Bifunctor (..))
 import Data.Functor ((<&>))
 import Data.List (sortBy)
@@ -168,6 +175,14 @@
 printUsage = flip printUsage' True
 
 
+-- | Like @'printUsage' for several @processIDs@
+printUsages ::
+  (AsCmdName a) =>
+  Map a MemUsage ->
+  IO ()
+printUsages = mapM_ printUsage . Map.toAscList
+
+
 onlyPrintTotal :: (AsCmdName k) => ReportBud -> Bool -> Bool -> [(k, MemUsage)] -> IO ()
 onlyPrintTotal bud showSwap onlyTotal totals = do
   let (private, swap) = overallTotals $ map snd totals
@@ -453,15 +468,20 @@
   | NeedsRoot
   | OddKernel
   | NoRecords
+  | BadSelfId
   deriving (Eq, Show)
 
 
+instance Exception NotRun
+
+
 fmtNotRun :: NotRun -> Text
 fmtNotRun NeedsRoot = "run as root when no pids are specified using -p"
 fmtNotRun (PidLost x) = fmtLostPid x
 fmtNotRun OddKernel = "unrecognized kernel version"
 fmtNotRun (MissingPids pids) = "no records available for: " +| listF (toInteger <$> pids) |+ ""
 fmtNotRun NoRecords = "could not find any process records"
+fmtNotRun BadSelfId = "self value was not a valid process ID"
 
 
 {- | Represents reasons a specified @pid@ may not have memory
@@ -517,6 +537,21 @@
       fromBadStatus NoParent = NoStatusParent pid
   statusPath <- pidPath "status" pid
   first fromBadStatus . parseStatusInfo <$> liftIO (readUtf8Text statusPath)
+
+
+-- | the processId of the current running process
+selfId :: (MonadReader ProcRoot m, MonadIO m) => m ProcessID
+selfId = do
+  let mkSelfPath root = "" +| root |+ "/self"
+  selfText <- asks mkSelfPath >>= liftIO . getSymbolicLinkTarget
+  case readMaybe selfText of
+    Just procId -> pure procId
+    Nothing -> liftIO $ throwIO BadSelfId
+
+
+-- | Like 'selfId' using the default ProcRoot
+selfId' :: IO ProcessID
+selfId' = runReaderT selfId defaultRoot
 
 
 parseCmdline :: Text -> Maybe (NonEmpty Text)
