diff --git a/src/Data/TimeMap/Multi.hs b/src/Data/TimeMap/Multi.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/TimeMap/Multi.hs
@@ -0,0 +1,77 @@
+module Data.TimeMap.Multi where
+
+import Data.TimeSet (TimeSet)
+import qualified Data.TimeSet as TimeSet
+import Data.Hashable (Hashable (..))
+import Data.Time (UTCTime, NominalDiffTime)
+import Control.Concurrent.STM (STM)
+import qualified Data.HashSet             as HS
+
+
+newtype TimeMultiMap k a = TimeMultiMap {getTimeMultiMap :: TimeSet (k,a)}
+
+
+newTimeMultiMap :: STM (TimeMultiMap k a)
+newTimeMultiMap = TimeMultiMap <$> TimeSet.newTimeSet
+
+
+insert :: (Hashable k, Hashable a, Eq k, Eq a) => k -> a -> TimeMultiMap k a -> IO ()
+insert k a (TimeMultiMap xs) = TimeSet.insert (k,a) xs
+
+
+insertWithTime :: (Hashable k, Hashable a, Eq k, Eq a) => UTCTime -> k -> a -> TimeMultiMap k a -> STM ()
+insertWithTime t k a (TimeMultiMap xs) = TimeSet.insertWithTime t (k,a) xs
+
+
+elem :: (Hashable k, Hashable a, Eq k, Eq a) => k -> a -> TimeMultiMap k a -> STM Bool
+elem k a (TimeMultiMap xs) = TimeSet.elem (k,a) xs
+
+
+keys :: (Hashable k, Hashable a, Eq k, Eq a) => TimeMultiMap k a -> STM [k]
+keys (TimeMultiMap xs) = (fmap fst . HS.toList) <$> TimeSet.elems xs
+
+
+elems :: (Hashable k, Hashable a, Eq k, Eq a) => TimeMultiMap k a -> STM [a]
+elems (TimeMultiMap xs) = (fmap snd . HS.toList) <$> TimeSet.elems xs
+
+
+size :: TimeMultiMap k a -> STM Int
+size (TimeMultiMap xs) = TimeSet.size xs
+
+
+null :: TimeMultiMap k a -> STM Bool
+null (TimeMultiMap xs) = TimeSet.null xs
+
+
+timeOf :: (Hashable k, Hashable a, Eq k, Eq a) => k -> a -> TimeMultiMap k a -> STM (Maybe UTCTime)
+timeOf k a (TimeMultiMap xs) = TimeSet.timeOf (k,a) xs
+
+
+ageOf :: (Hashable k, Hashable a, Eq k, Eq a) => k -> a -> TimeMultiMap k a -> IO (Maybe NominalDiffTime)
+ageOf k a (TimeMultiMap xs) = TimeSet.ageOf (k,a) xs
+
+
+delete :: (Hashable k, Hashable a, Eq k, Eq a) => k -> a -> TimeMultiMap k a -> STM ()
+delete k a (TimeMultiMap xs) = TimeSet.delete (k,a) xs
+
+
+deleteAll :: (Hashable k, Hashable a, Eq k, Eq a) => k -> TimeMultiMap k a -> STM ()
+deleteAll k t = do
+  as <- elems t
+  mapM_ (\a -> delete k a t) as
+
+
+touch :: (Hashable k, Hashable a, Eq k, Eq a) => k -> a -> TimeMultiMap k a -> IO ()
+touch k a (TimeMultiMap xs) = TimeSet.touch (k,a) xs
+
+
+filter :: (Hashable k, Hashable a, Eq k, Eq a) => (k -> a -> Bool) -> TimeMultiMap k a -> STM ()
+filter f (TimeMultiMap xs) = TimeSet.filter (\(k,a) -> f k a) xs
+
+
+filterSince :: (Hashable k, Hashable a, Eq k, Eq a) => UTCTime -> TimeMultiMap k a -> STM ()
+filterSince t (TimeMultiMap xs) = TimeSet.filterSince t xs
+
+
+filterFromNow :: (Hashable k, Hashable a, Eq k, Eq a) => NominalDiffTime -> TimeMultiMap k a -> IO ()
+filterFromNow t (TimeMultiMap xs) = TimeSet.filterFromNow t xs
diff --git a/src/Data/TimeSet.hs b/src/Data/TimeSet.hs
--- a/src/Data/TimeSet.hs
+++ b/src/Data/TimeSet.hs
@@ -3,7 +3,7 @@
 import Data.TimeMap (TimeMap, newTimeMap)
 import qualified Data.TimeMap as TimeMap
 import Data.Hashable (Hashable (..))
-import Data.Time (UTCTime, NominalDiffTime, addUTCTime, diffUTCTime, getCurrentTime)
+import Data.Time (UTCTime, NominalDiffTime)
 import qualified Data.HashSet             as HS
 import Control.Concurrent.STM (STM)
 
diff --git a/timemap.cabal b/timemap.cabal
--- a/timemap.cabal
+++ b/timemap.cabal
@@ -1,5 +1,5 @@
 Name:                   timemap
-Version:                0.0.5
+Version:                0.0.6
 Author:                 Athan Clark <athan.clark@gmail.com>
 Maintainer:             Athan Clark <athan.clark@gmail.com>
 License:                BSD3
@@ -19,6 +19,7 @@
   HS-Source-Dirs:       src
   GHC-Options:          -Wall
   Exposed-Modules:      Data.TimeMap
+                        Data.TimeMap.Multi
                         Data.TimeSet
   Other-Modules:        Data.TimeMap.Internal
   Build-Depends:        base >= 4.8 && < 5
