diff --git a/buffer-builder.cabal b/buffer-builder.cabal
--- a/buffer-builder.cabal
+++ b/buffer-builder.cabal
@@ -1,5 +1,5 @@
 name:                buffer-builder
-version:             0.2.2.2
+version:             0.2.3.0
 synopsis:            Library for efficiently building up buffers, one piece at a time
 description:
 
diff --git a/cbits/buffer.cpp b/cbits/buffer.cpp
--- a/cbits/buffer.cpp
+++ b/cbits/buffer.cpp
@@ -87,9 +87,6 @@
     }
 }
 
-// assumes malloc will not fail
-// TODO: replace assert with some other error mechanism
-
 extern "C" BufferWriter* bw_new(size_t initialCapacity) {
     if (!initialCapacity) {
         initialCapacity = 1;
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,7 +1,12 @@
+0.2.3.0
+
+* Add the ability to query the current buffer size
+* Add the ability to return a value from a BufferBuilder
+
 0.2.2.2
 
-* Add the ability to percent-encode directly into a Utf8Builder.
-* Add Utf8Builder.unsafeAppendBufferBuilder.
+* Add the ability to percent-encode directly into a Utf8Builder
+* Add Utf8Builder.unsafeAppendBufferBuilder
 
 0.2.2.0
 
diff --git a/src/Data/BufferBuilder.hs b/src/Data/BufferBuilder.hs
--- a/src/Data/BufferBuilder.hs
+++ b/src/Data/BufferBuilder.hs
@@ -10,11 +10,16 @@
     -- * The BufferBuilder Monad
       BufferBuilder
     , runBufferBuilder
+    , runBufferBuilder'
 
     -- * Optional configuration
     , Options(..)
     , runBufferBuilderWithOptions
+    , runBufferBuilderWithOptions'
 
+    -- * Query current state
+    , currentLength
+
     -- * Appending bytes and byte strings
     , appendByte
     , appendChar8
@@ -122,7 +127,7 @@
         a <- lhs h
         unBB (next a) h
 
-withHandle :: (Handle -> IO ()) -> BufferBuilder ()
+withHandle :: (Handle -> IO a) -> BufferBuilder a
 withHandle = BB
 {-# INLINE withHandle #-}
 
@@ -143,20 +148,28 @@
 
 -- | Run a sequence of 'BufferBuilder' actions and extract the resulting
 -- buffer as a 'BS.ByteString'.
-runBufferBuilder :: BufferBuilder () -> BS.ByteString
-runBufferBuilder = runBufferBuilderWithOptions defaultOptions
+runBufferBuilder :: BufferBuilder a -> BS.ByteString
+runBufferBuilder = snd . runBufferBuilder'
 
-runBufferBuilderWithOptions :: Options -> BufferBuilder () -> BS.ByteString
-runBufferBuilderWithOptions options = unsafeDupablePerformIO . runBufferBuilderIO options
+-- | Run a sequence of 'BufferBuilder' actions and extract the resulting
+-- buffer as a 'BS.ByteString'.  Also returns the BufferBuilder's result.
+runBufferBuilder' :: BufferBuilder a -> (a, BS.ByteString)
+runBufferBuilder' = runBufferBuilderWithOptions' defaultOptions
 
-runBufferBuilderIO :: Options-> BufferBuilder () -> IO BS.ByteString
+runBufferBuilderWithOptions :: Options -> BufferBuilder a -> BS.ByteString
+runBufferBuilderWithOptions options = snd . runBufferBuilderWithOptions' options
+
+runBufferBuilderWithOptions' :: Options -> BufferBuilder a -> (a, BS.ByteString)
+runBufferBuilderWithOptions' options = unsafeDupablePerformIO . runBufferBuilderIO options
+
+runBufferBuilderIO :: Options -> BufferBuilder a -> IO (a, BS.ByteString)
 runBufferBuilderIO !Options{..} !(BB bw) = do
     handle <- bw_new initialCapacity
     when (handle == nullPtr) $ do
         throw BufferOutOfMemoryError
     
     handleFP <- newForeignPtr bw_free handle
-    () <- bw handle
+    rv <- bw handle
 
     when trimFinalBuffer $ do
         bw_trim handle
@@ -173,7 +186,11 @@
     borrowed <- newForeignPtr finalizerFree src
     let bs = BS.fromForeignPtr borrowed 0 size
     touchForeignPtr handleFP
-    return bs
+    return (rv, bs)
+
+-- | Reads current length of BufferBuilder
+currentLength :: BufferBuilder Int
+currentLength = withHandle bw_get_size
 
 -- | Append a single byte to the output buffer.  To append multiple bytes in sequence and
 -- avoid redundant bounds checks, consider using 'appendBS', 'appendLiteral', or 'unsafeAppendLiteralN'.
diff --git a/test/BufferTest.hs b/test/BufferTest.hs
--- a/test/BufferTest.hs
+++ b/test/BufferTest.hs
@@ -47,6 +47,18 @@
             appendUrlEncoded safe
     assertEqual "matches" "%00%01%20%2f%5c%24%25" result
 
+case_query_size :: Assertion
+case_query_size = do
+    let ((f, s), result) = runBufferBuilder' $ do
+            appendBS "foo"
+            first <- currentLength
+            appendBS "bar"
+            second <- currentLength
+            return (first, second)
+    assertEqual "first size" 3 f
+    assertEqual "second size" 6 s
+    assertEqual "result" "foobar" result
+
 prop_match_intDec :: Int -> Bool
 prop_match_intDec i = runBufferBuilder (appendDecimalSignedInt i) == (BSC.pack $ show i)
 
