diff --git a/buffer.cabal b/buffer.cabal
--- a/buffer.cabal
+++ b/buffer.cabal
@@ -1,7 +1,7 @@
 name:
   buffer
 version:
-  0.5.0.1
+  0.5.3
 category:
   Data
 synopsis:
diff --git a/library/Buffer.hs b/library/Buffer.hs
--- a/library/Buffer.hs
+++ b/library/Buffer.hs
@@ -42,7 +42,7 @@
   * End offset
   * Max amount
   -}
-  State !(ForeignPtr Word8) !Int !Int !Int
+  State {-# UNPACK #-} !(ForeignPtr Word8) {-# UNPACK #-} !Int {-# UNPACK #-} !Int {-# UNPACK #-} !Int
 
 {-|
 Create a new buffer of the specified initial capacity.
@@ -69,40 +69,41 @@
 {-# INLINABLE push #-}
 push :: Buffer -> Int -> (Ptr Word8 -> IO (Int, result)) -> IO result
 push (Buffer stateIORef) space ptrIO =
+  {-# SCC "push" #-} 
   do
     State fptr start end capacity <- readIORef stateIORef
     let
-      remainingSpace = capacity - end
-      capacityDelta = space - remainingSpace
-      occupiedSpace = end - start
+      !remainingSpace = capacity - end
+      !capacityDelta = space - remainingSpace
+      !occupiedSpace = end - start
       in 
         if capacityDelta <= 0 -- Doesn't need more space?
           then 
             do
-              (actualSpace, output) <- withForeignPtr fptr $ \ptr -> ptrIO (plusPtr ptr end)
-              writeIORef stateIORef (State fptr start (end + actualSpace) capacity)
+              (!actualSpace, !output) <- withForeignPtr fptr $ \ptr -> ptrIO (plusPtr ptr end)
+              writeIORef stateIORef $! State fptr start (end + actualSpace) capacity
               return output
           else 
             if capacityDelta > start -- Needs growing?
               then
                 -- Grow
                 do
-                  let newCapacity = occupiedSpace + space
+                  let !newCapacity = occupiedSpace + space
                   newFPtr <- mallocForeignPtrBytes newCapacity
-                  (actualSpace, output) <- withForeignPtr newFPtr $ \newPtr -> do
+                  (!actualSpace, !output) <- withForeignPtr newFPtr $ \newPtr -> do
                     withForeignPtr fptr $ \ptr -> do
                       memcpy newPtr (plusPtr ptr start) (fromIntegral occupiedSpace)
                     ptrIO (plusPtr newPtr occupiedSpace)
-                  let newOccupiedSpace = occupiedSpace + actualSpace
-                  writeIORef stateIORef (State newFPtr 0 newOccupiedSpace newCapacity)
+                  let !newOccupiedSpace = occupiedSpace + actualSpace
+                  writeIORef stateIORef $! State newFPtr 0 newOccupiedSpace newCapacity
                   return output
               else 
                 -- Align
                 do
-                  (actualSpace, output) <- withForeignPtr fptr $ \ptr -> do
+                  (!actualSpace, !output) <- withForeignPtr fptr $ \ptr -> do
                     memmove ptr (plusPtr ptr start) (fromIntegral occupiedSpace)
                     ptrIO (plusPtr ptr occupiedSpace)
-                  writeIORef stateIORef (State fptr 0 (occupiedSpace + actualSpace) capacity)
+                  writeIORef stateIORef $! State fptr 0 (occupiedSpace + actualSpace) capacity
                   return output
 
 {-|
@@ -116,14 +117,15 @@
 {-# INLINE pull #-}
 pull :: Buffer -> Int -> (Ptr Word8 -> IO result) -> (Int -> IO result) -> IO result
 pull (Buffer stateIORef) pulledAmount ptrIO refill =
+  {-# SCC "pull" #-} 
   do
     State fptr start end capacity <- readIORef stateIORef
-    let newStart = start + pulledAmount
+    let !newStart = start + pulledAmount
     if newStart > end
-      then refill (newStart - end)
-      else withForeignPtr fptr $ \ptr -> do
-        pulled <- ptrIO (plusPtr ptr start)
-        writeIORef stateIORef (State fptr newStart end capacity)
+      then refill $! newStart - end
+      else do
+        !pulled <- withForeignPtr fptr $ \ptr -> ptrIO (plusPtr ptr start)
+        writeIORef stateIORef $! State fptr newStart end capacity
         return pulled
 
 {-|
@@ -181,9 +183,10 @@
 {-# INLINE getSpace #-}
 getSpace :: Buffer -> IO Int
 getSpace (Buffer stateIORef) =
+  {-# SCC "getSpace" #-} 
   do
     State fptr start end capacity <- readIORef stateIORef
-    return (end - start)
+    return $! end - start
 
 {-|
 Create a bytestring representation without modifying the buffer.
@@ -194,4 +197,4 @@
   do
     State fptr start end capacity <- readIORef stateIORef
     let size = end - start
-    withForeignPtr fptr $ \ptr -> C.create size $ \destPtr -> C.memcpy destPtr ptr size
+    withForeignPtr fptr $ \ptr -> C.create size $ \destPtr -> C.memcpy destPtr (plusPtr ptr start) size
