diff --git a/prometheus-client.cabal b/prometheus-client.cabal
--- a/prometheus-client.cabal
+++ b/prometheus-client.cabal
@@ -1,5 +1,5 @@
 name:                prometheus-client
-version:             0.1.0.1
+version:             0.1.1
 synopsis:            Haskell client library for http://prometheus.io.
 description:         Haskell client library for http://prometheus.io.
 homepage:            https://github.com/fimad/prometheus-haskell
diff --git a/src/Prometheus.hs b/src/Prometheus.hs
--- a/src/Prometheus.hs
+++ b/src/Prometheus.hs
@@ -28,17 +28,26 @@
 
 -- ** Counter
 --
--- | A counter models a monotonically increasing integer value. It is the
--- simplest type of metric provided by this library.
+-- | A counter models a monotonically increasing value. It is the simplest
+-- type of metric provided by this library.
 --
+-- A Counter is typically used to count requests served, tasks completed,
+-- errors occurred, etc.
+--
 -- >>> myCounter <- counter (Info "my_counter" "An example counter")
 -- >>> replicateM_ 47 (incCounter myCounter)
 -- >>> getCounter myCounter
--- 47
+-- 47.0
+-- >>> void $ addCounter 10 myCounter
+-- >>> getCounter myCounter
+-- 57.0
 
 ,   Counter
 ,   counter
 ,   incCounter
+,   addCounter
+,   unsafeAddCounter
+,   addDurationToCounter
 ,   getCounter
 
 -- ** Gauge
@@ -94,13 +103,13 @@
 -- >>> withLabel ("GET", "404") incCounter myVector
 -- >>> withLabel ("POST", "200") incCounter myVector
 -- >>> getVectorWith getCounter myVector
--- [(("GET","200"),2),(("GET","404"),1),(("POST","200"),1)]
+-- [(("GET","200"),2.0),(("GET","404"),1.0),(("POST","200"),1.0)]
 -- >>> exportMetricsAsText >>= Data.ByteString.putStr
 -- # HELP http_requests
 -- # TYPE http_requests counter
--- http_requests{method="GET",code="200"} 2
--- http_requests{method="GET",code="404"} 1
--- http_requests{method="POST",code="200"} 1
+-- http_requests{method="GET",code="200"} 2.0
+-- http_requests{method="GET",code="404"} 1.0
+-- http_requests{method="POST",code="200"} 1.0
 
 ,   Vector
 ,   vector
@@ -188,10 +197,10 @@
 -- >>> let add x y = incCounter numAdds >> return (x + y)
 -- >>> let (3, updateMetrics) = runMonitor $ (add 1 1) >>= (add 1)
 -- >>> getCounter numAdds
--- 0
+-- 0.0
 -- >>> updateMetrics
 -- >>> getCounter numAdds
--- 2
+-- 2.0
 
 ,   MonadMonitor (..)
 ,   Monitor
diff --git a/src/Prometheus/Export/Text.hs b/src/Prometheus/Export/Text.hs
--- a/src/Prometheus/Export/Text.hs
+++ b/src/Prometheus/Export/Text.hs
@@ -28,7 +28,7 @@
 -- >>> exportMetricsAsText >>= Data.ByteString.putStr
 -- # HELP my_counter Example counter
 -- # TYPE my_counter counter
--- my_counter 1
+-- my_counter 1.0
 exportMetricsAsText :: IO BS.ByteString
 exportMetricsAsText = do
     samples <- collectMetrics
diff --git a/src/Prometheus/Metric/Counter.hs b/src/Prometheus/Metric/Counter.hs
--- a/src/Prometheus/Metric/Counter.hs
+++ b/src/Prometheus/Metric/Counter.hs
@@ -2,6 +2,9 @@
     Counter
 ,   counter
 ,   incCounter
+,   addCounter
+,   unsafeAddCounter
+,   addDurationToCounter
 ,   getCounter
 ) where
 
@@ -9,32 +12,66 @@
 import Prometheus.Metric
 import Prometheus.MonadMonitor
 
-import qualified Data.Atomics.Counter as Atomics
+import Control.Monad (unless)
+import Data.Time.Clock (diffUTCTime, getCurrentTime)
+import qualified Data.Atomics as Atomics
 import qualified Data.ByteString.UTF8 as BS
+import qualified Data.IORef as IORef
 
 
-newtype Counter = MkCounter Atomics.AtomicCounter
+newtype Counter = MkCounter (IORef.IORef Double)
 
 -- | Creates a new counter metric with a given name and help string.
 counter :: Info -> IO (Metric Counter)
 counter info = do
-    atomicCounter <- Atomics.newCounter 0
+    ioref <- IORef.newIORef 0
     return Metric {
-            handle = MkCounter atomicCounter
-        ,   collect = collectCounter info atomicCounter
+            handle = MkCounter ioref
+        ,   collect = collectCounter info ioref
         }
 
+withCounter :: MonadMonitor m
+          => Metric Counter
+          -> (Double -> Double)
+          -> m ()
+withCounter Metric {handle = MkCounter ioref} f =
+    doIO $ Atomics.atomicModifyIORefCAS_ ioref f
+
 -- | Increments the value of a counter metric by 1.
 incCounter :: MonadMonitor m => Metric Counter -> m ()
-incCounter (Metric {handle = MkCounter c}) =
-    doIO $ Atomics.incrCounter_ 1 c
+incCounter c = withCounter c (+ 1)
 
+-- | Add the given value to the counter, if it is zero or more.
+addCounter :: MonadMonitor m => Double -> Metric Counter -> m Bool
+addCounter x c
+  | x < 0 = return False
+  | otherwise = do
+      withCounter c add
+      return True
+  where add i = i `seq` x `seq` i + x
+
+-- | Add the given value to the counter. Panic if it is less than zero.
+unsafeAddCounter :: MonadMonitor m => Double -> Metric Counter -> m ()
+unsafeAddCounter x c = do
+  added <- addCounter x c
+  unless added $
+    error $ "Tried to add negative value to counter: " ++ show x
+
+-- | Add the duration of an IO action (in seconds) to a counter.
+addDurationToCounter :: IO a -> Metric Counter -> IO a
+addDurationToCounter io metric = do
+    start  <- getCurrentTime
+    result <- io
+    end    <- getCurrentTime
+    addCounter (fromRational $ toRational $ end `diffUTCTime` start) metric
+    return result
+
 -- | Retrieves the current value of a counter metric.
-getCounter :: Metric Counter -> IO Int
-getCounter (Metric {handle = MkCounter c}) = Atomics.readCounter c
+getCounter :: Metric Counter -> IO Double
+getCounter Metric {handle = MkCounter ioref} = IORef.readIORef ioref
 
-collectCounter :: Info -> Atomics.AtomicCounter -> IO [SampleGroup]
+collectCounter :: Info -> IORef.IORef Double -> IO [SampleGroup]
 collectCounter info c = do
-    value <- Atomics.readCounter c
+    value <- IORef.readIORef c
     let sample = Sample (metricName info) [] (BS.fromString $ show value)
     return [SampleGroup info CounterType [sample]]
