diff --git a/library/PrimitiveExtras/Cereal/Get.hs b/library/PrimitiveExtras/Cereal/Get.hs
new file mode 100644
--- /dev/null
+++ b/library/PrimitiveExtras/Cereal/Get.hs
@@ -0,0 +1,20 @@
+module PrimitiveExtras.Cereal.Get
+where
+
+import PrimitiveExtras.Prelude
+import PrimitiveExtras.Types
+import Data.Serialize.Get
+import PrimitiveExtras.Monad
+
+
+primArray :: Prim element => Get element -> Get (PrimArray element)
+primArray element =
+  do
+    size <- fromIntegral <$> getInt64le
+    replicateMPrimArray size element
+
+primMultiArray :: Prim element => Get element -> Get (PrimMultiArray element)
+primMultiArray element =
+  do
+    size <- fromIntegral <$> getInt64le
+    replicateMMultiPrimArray size (primArray element)
diff --git a/library/PrimitiveExtras/Cereal/Put.hs b/library/PrimitiveExtras/Cereal/Put.hs
new file mode 100644
--- /dev/null
+++ b/library/PrimitiveExtras/Cereal/Put.hs
@@ -0,0 +1,22 @@
+module PrimitiveExtras.Cereal.Put
+where
+
+import PrimitiveExtras.Prelude
+import PrimitiveExtras.Types
+import Data.Serialize.Put
+import qualified PrimitiveExtras.Monad as Monad
+
+
+primArray :: Prim element => Putter element -> Putter (PrimArray element)
+primArray element primArrayValue =
+  size <> elements
+  where
+    size = putInt64le (fromIntegral (sizeofPrimArray primArrayValue))
+    elements = traversePrimArray_ element primArrayValue
+
+primMultiArray :: Prim element => Putter element -> Putter (PrimMultiArray element)
+primMultiArray element (PrimMultiArray outerArrayValue) =
+  size <> innerArrays
+  where
+    size = putInt64le (fromIntegral (sizeofUnliftedArray outerArrayValue))
+    innerArrays = Monad.traverseUnliftedArray_ (primArray element) outerArrayValue
diff --git a/library/PrimitiveExtras/Monad.hs b/library/PrimitiveExtras/Monad.hs
--- a/library/PrimitiveExtras/Monad.hs
+++ b/library/PrimitiveExtras/Monad.hs
@@ -14,6 +14,20 @@
     indexCounts <- runFold (lmap fst (A.indexCounts outerArraySize))
     runFold (A.primMultiArray (indexCounts :: PrimArray Word32))
 
+replicateMMultiPrimArray :: (Monad m, Prim a) => Int -> m (PrimArray a) -> m (PrimMultiArray a)
+replicateMMultiPrimArray size elementM =
+  do
+    !mutable <- return (unsafeDupablePerformIO (unsafeNewUnliftedArray size))
+    let 
+      iterate index =
+        if index < size
+          then do
+            element <- elementM
+            let !() = unsafeDupablePerformIO (writeUnliftedArray mutable index element)
+            iterate (succ index)
+          else return (PrimMultiArray (unsafePerformIO (unsafeFreezeUnliftedArray mutable)))
+      in iterate 0
+
 {-| Please notice that this function is highly untested -}
 replicateMPrimArray :: (Monad m, Prim element) => Int -> m element -> m (PrimArray element)
 replicateMPrimArray size elementM =
@@ -28,3 +42,15 @@
             iterate (succ index)
           else return (unsafePerformIO (unsafeFreezePrimArray mutable))
       in iterate 0
+
+traverseUnliftedArray_ :: (Monad m, PrimUnlifted a) => (a -> m ()) -> UnliftedArray a -> m ()
+traverseUnliftedArray_ action array =
+  let
+    size = sizeofUnliftedArray array
+    iterate index = if index < size
+      then do
+        element <- indexUnliftedArrayM array index
+        action element
+        iterate (succ index)
+      else return ()
+    in iterate 0
diff --git a/primitive-extras.cabal b/primitive-extras.cabal
--- a/primitive-extras.cabal
+++ b/primitive-extras.cabal
@@ -1,7 +1,7 @@
 name:
   primitive-extras
 version:
-  0.1.9
+  0.1.10
 category:
   Primitive
 synopsis:
@@ -46,12 +46,15 @@
     PrimitiveExtras.UnfoldM
     PrimitiveExtras.Fold
     PrimitiveExtras.Pure
+    PrimitiveExtras.Cereal.Get
+    PrimitiveExtras.Cereal.Put
   other-modules:
     PrimitiveExtras.UnliftedArray
     PrimitiveExtras.Prelude
     PrimitiveExtras.Types
   build-depends:
     base >=4.7 && <5,
+    cereal >=0.5.5 && <0.6,
     deferred-folds >=0.6 && <0.7,
     foldl >=1 && <2,
     primitive >=0.6.4 && <0.7,
