diff --git a/keyvaluehash.cabal b/keyvaluehash.cabal
--- a/keyvaluehash.cabal
+++ b/keyvaluehash.cabal
@@ -1,5 +1,5 @@
 name:                keyvaluehash
-version:             0.1.0.0
+version:             0.2.0.0
 synopsis:            Pure Haskell key/value store implementation
 -- description:         
 license:             BSD3
diff --git a/src/Database/KeyValueHash.hs b/src/Database/KeyValueHash.hs
--- a/src/Database/KeyValueHash.hs
+++ b/src/Database/KeyValueHash.hs
@@ -3,7 +3,8 @@
   ( Key, Value
   , Size, mkSize, sizeLinear
   , HashFunction, stdHash, mkHashFunc
-  , Database, createDatabase, openDatabase
+  , Database, createDatabase, openDatabase, closeDatabase
+  , withCreateDatabase, withOpenDatabase
   , readKey, writeKey, deleteKey
   ) where
 
@@ -81,6 +82,8 @@
 
 data ValueHeader = ValueHeader
   { vhNextCollision :: ValuePtr
+    -- if value is re-written multiple times, we can do it in-place as long as it fits
+  , vhAllocSize :: Word32
   , vhKeySize :: Word32
   , vhValueSize :: Word32
   }
@@ -104,7 +107,7 @@
 keyRecordSize = binaryPutSize (0 :: KeyRecord)
 
 valueHeaderSize :: Word64
-valueHeaderSize = binaryPutSize $ ValueHeader 0 0 0
+valueHeaderSize = binaryPutSize $ ValueHeader 0 0 0 0
 
 makeFileName :: String -> FilePath -> HashFunction -> Size -> FilePath
 makeFileName prefix path func size =
@@ -145,6 +148,19 @@
   where
     mkHandle f = IO.openFile (f path func size) IO.ReadWriteMode
 
+closeDatabase :: Database -> IO ()
+closeDatabase db = do
+  IO.hClose $ dbKeysHandle db
+  IO.hClose $ dbValuesHandle db
+
+withCreateDatabase :: FilePath -> HashFunction -> Size -> (Database -> IO a) -> IO a
+withCreateDatabase path func size =
+  Exc.bracket (createDatabase path func size) closeDatabase
+
+withOpenDatabase :: FilePath -> HashFunction -> Size -> (Database -> IO a) -> IO a
+withOpenDatabase path func size =
+  Exc.bracket (openDatabase path func size) closeDatabase
+
 hashKey :: Database -> Key -> KeyPtr
 hashKey db key = hfHash (dbHashFunc db) key (dbSize db)
 
@@ -234,29 +250,44 @@
       readFileRange (dbValuesHandle db)
       (valueDataRange (vprVal valuePtrRef) valueHeader)
 
+pairLengths :: Key -> Value -> (Word32, Word32)
+pairLengths key value = (keyLen, valueLen)
+  where
+    keyLen = fromIntegral $ SBS.length key
+    valueLen = fromIntegral $ SBS.length value
+
 appendNewValue :: Database -> ValuePtr -> Key -> Value -> IO ValuePtr
-appendNewValue db nextCollision key val = do
+appendNewValue db nextCollision key value = do
   valuePtr <- fromIntegral <$> IO.hFileSize (dbValuesHandle db)
   let
     headerStr = encode ValueHeader
-      { vhKeySize = fromIntegral $ SBS.length key
-      , vhValueSize = fromIntegral $ SBS.length val
-      , vhNextCollision = nextCollision
+      { vhNextCollision = nextCollision
+      , vhAllocSize = keyLen + valueLen
+      , vhKeySize = keyLen
+      , vhValueSize = valueLen
       }
-  writeFileRange (dbValuesHandle db) valuePtr $ mconcat [headerStr, key, val]
+  writeFileRange (dbValuesHandle db) valuePtr $ mconcat [headerStr, key, value]
   return valuePtr
+  where
+    (keyLen, valueLen) = pairLengths key value
 
 writeKey :: Database -> Key -> Value -> IO ()
 writeKey db key value = do
   mResult <- findKey db key
   case mResult of
     Just (valuePtrRef, valueHeader) ->
-      -- The old value now becomes unreachable
-      setValue valuePtrRef $ vhNextCollision valueHeader
+      if vhAllocSize valueHeader >= keyLen + valueLen then
+        -- re-use existing storage:
+        let headerStr = encode valueHeader { vhKeySize = keyLen, vhValueSize = valueLen }
+        in writeFileRange (dbValuesHandle db) (vprVal valuePtrRef) $ mconcat [headerStr, key, value]
+      else
+        -- The old value now becomes unreachable
+        setValue valuePtrRef $ vhNextCollision valueHeader
     Nothing -> do
       hashAnchor <- hashValuePtrRef db key
       setValue hashAnchor $ vprVal hashAnchor
   where
+    (keyLen, valueLen) = pairLengths key value
     setValue ref nextCollision =
       vprSet ref =<< appendNewValue db nextCollision key value
 
