diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,4 @@
 # Changelog for log4hs
 
-## Unreleased changes
+## V0.3.0
+- Add `RotatingFileHandler` (without unit tests)
diff --git a/log4hs.cabal b/log4hs.cabal
--- a/log4hs.cabal
+++ b/log4hs.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 8d633b37fcc55dd17512ea7e3f2351a1e6b89b9fb459303951dd3039c1bb8bed
+-- hash: e7e350195d12d645cff1909da7ee473c97ec7d76c3116dc59cd50b3d7d294f14
 
 name:           log4hs
-version:        0.2.0.0
+version:        0.3.0.0
 synopsis:       A python logging style log library
 description:    Please see the http://hackage.haskell.org/package/log4hs
 category:       logging
@@ -36,6 +36,7 @@
       Logging.Types.Filter
       Logging.Types.Handlers
       Logging.Types.Handlers.FileHandler
+      Logging.Types.Handlers.RotatingFileHandler
       Logging.Types.Handlers.StreamHandler
       Logging.Types.Level
       Logging.Types.Logger
diff --git a/src/Logging/Aeson.hs b/src/Logging/Aeson.hs
--- a/src/Logging/Aeson.hs
+++ b/src/Logging/Aeson.hs
@@ -156,6 +156,22 @@
       return $ FileHandler level filterer formatter file encoding' stream
 
 
+instance FromJSON (IO RotatingFileHandler) where
+  parseJSON = withObject "RotatingFileHandler" $ \v -> do
+    level <- v .:? "level" .!= def
+    filterer <- v .:? "filterer" .!= []
+    formatter <- v .:? "formatter" .!= ""
+    file <- v .:? "file" .!= "log4hs.log"
+    encoding <- v .:? "encoding" .!= (show utf8)
+    maxBytes <- v .:? "maxBytes" .!= 102400000
+    backupCount <- v .:? "maxBytes" .!= 5
+    return $ do
+      stream <- newIORef undefined
+      encoding' <- mkTextEncoding encoding
+      return $ RotatingFileHandler level filterer formatter file encoding'
+                                   maxBytes backupCount stream
+
+
 instance FromJSON (IO SomeHandler) where
   parseJSON = withObject "Handler" $ \v -> (v .: "type") >>= (`parseHandler` v)
     where
@@ -166,6 +182,9 @@
       parseHandler "FileHandler" v = do
         hdlIo <- parseJSON (Object v)
         return $ toHandler <$> (hdlIo :: IO FileHandler)
+      parseHandler "RotatingFileHandler" v = do
+        hdlIo <- parseJSON (Object v)
+        return $ toHandler <$> (hdlIo :: IO RotatingFileHandler)
 
 
 instance FromJSON (M.Map String Format1 -> IO SomeHandler) where
diff --git a/src/Logging/Types/Handlers.hs b/src/Logging/Types/Handlers.hs
--- a/src/Logging/Types/Handlers.hs
+++ b/src/Logging/Types/Handlers.hs
@@ -1,7 +1,9 @@
 module Logging.Types.Handlers
   ( module Logging.Types.Handlers.StreamHandler
   , module Logging.Types.Handlers.FileHandler
+  , module Logging.Types.Handlers.RotatingFileHandler
   ) where
 
 import           Logging.Types.Handlers.FileHandler
+import           Logging.Types.Handlers.RotatingFileHandler
 import           Logging.Types.Handlers.StreamHandler
diff --git a/src/Logging/Types/Handlers/RotatingFileHandler.hs b/src/Logging/Types/Handlers/RotatingFileHandler.hs
new file mode 100644
--- /dev/null
+++ b/src/Logging/Types/Handlers/RotatingFileHandler.hs
@@ -0,0 +1,68 @@
+{-# LANGUAGE DeriveGeneric         #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE RecordWildCards       #-}
+
+module Logging.Types.Handlers.RotatingFileHandler
+  ( RotatingFileHandler(..)
+  ) where
+
+import           Control.Monad
+import           Data.IORef
+import           GHC.Generics
+import           System.IO
+import           Text.Format
+
+import           Logging.Types.Class
+import           Logging.Types.Filter
+import           Logging.Types.Level
+import           Logging.Utils
+import           System.IO.Extra
+
+
+-- | A handler type which writes logging records, appropriately formatted,
+-- to a file, it will rotate when file is too large.
+--
+-- UNTESTED
+--
+-- Since 0.3.0
+--
+data RotatingFileHandler = RotatingFileHandler { level       :: Level
+                                               , filterer    :: Filterer
+                                               , formatter   :: Format1
+                                               , file        :: FilePath
+                                               , encoding    :: TextEncoding
+                                               , maxBytes    :: Int
+                                               , backupCount :: Int
+                                               , stream      :: IORef Handle
+                                               } deriving (Generic, Eq)
+
+instance Handler RotatingFileHandler where
+  open RotatingFileHandler{..} =
+    atomicWriteIORef stream =<< openLogFile file encoding
+
+  emit RotatingFileHandler{..} rcd = do
+      let msg = format1 formatter rcd
+      rollover $ length msg
+      stream' <- readIORef stream
+      hPutStrLn stream' msg
+      hFlush stream'
+    where
+      rollover :: Int -> IO ()
+      rollover mlen = do
+        stream' <- readIORef stream
+        pos <- hTell =<< readIORef stream
+        when (fromEnum pos + mlen >= maxBytes && backupCount > 0)  $ do
+          hClose stream'
+          rotateNext $ backupCount - 1
+          rotateFile file $ modifyBaseName file (++ ".1")
+
+      addSuffix :: String -> Int -> String
+      addSuffix src suffix = src ++ "." ++ (show suffix)
+
+      rotateNext :: Int -> IO ()
+      rotateNext n = when (n > 0) $ do
+        let src = modifyBaseName file $ flip addSuffix n
+            dest = modifyBaseName file $ flip addSuffix $ n + 1
+        rotateFile src dest
+
+  close RotatingFileHandler{..} = hClose =<< readIORef stream
