diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,7 @@
+## 0.1.1.4 (2018-02-27)
+
+ * GHC 8.4 support ([#23](https://github.com/tibbe/ekg-core/pull/23)).
+
 ## 0.1.1.3 (2017-10-10)
 
  * Fix a space leak in `System.Metric.Label.set` ([#21](https://github.com/tibbe/ekg-core/pull/21)).
diff --git a/System/Metrics.hs b/System/Metrics.hs
--- a/System/Metrics.hs
+++ b/System/Metrics.hs
@@ -331,9 +331,15 @@
 -- easily be added to a metrics store by calling their register
 -- function.
 
+#if MIN_VERSION_base(4,10,0)
+-- | Convert nanoseconds to milliseconds.
+nsToMs :: Int64 -> Int64
+nsToMs s = round (realToFrac s / (1000000.0 :: Double))
+#else
 -- | Convert seconds to milliseconds.
-toMs :: Double -> Int64
-toMs s = round (s * 1000.0)
+sToMs :: Double -> Int64
+sToMs s = round (s * 1000.0)
+#endif
 
 -- | Register a number of metrics related to garbage collector
 -- behavior.
@@ -410,18 +416,42 @@
 registerGcMetrics :: Store -> IO ()
 registerGcMetrics store =
     registerGroup
+#if MIN_VERSION_base(4,10,0)
     (M.fromList
+     [ ("rts.gc.bytes_allocated"          , Counter . fromIntegral . Stats.allocated_bytes)
+     , ("rts.gc.num_gcs"                  , Counter . fromIntegral . Stats.gcs)
+     , ("rts.gc.num_bytes_usage_samples"  , Counter . fromIntegral . Stats.major_gcs)
+     , ("rts.gc.cumulative_bytes_used"    , Counter . fromIntegral . Stats.cumulative_live_bytes)
+     , ("rts.gc.bytes_copied"             , Counter . fromIntegral . Stats.copied_bytes)
+     , ("rts.gc.mutator_cpu_ms"           , Counter . nsToMs . Stats.mutator_cpu_ns)
+     , ("rts.gc.mutator_wall_ms"          , Counter . nsToMs . Stats.mutator_elapsed_ns)
+     , ("rts.gc.gc_cpu_ms"                , Counter . nsToMs . Stats.gc_cpu_ns)
+     , ("rts.gc.gc_wall_ms"               , Counter . nsToMs . Stats.gc_elapsed_ns)
+     , ("rts.gc.cpu_ms"                   , Counter . nsToMs . Stats.cpu_ns)
+     , ("rts.gc.wall_ms"                  , Counter . nsToMs . Stats.elapsed_ns)
+     , ("rts.gc.max_bytes_used"           , Gauge . fromIntegral . Stats.max_live_bytes)
+     , ("rts.gc.current_bytes_used"       , Gauge . fromIntegral . Stats.gcdetails_live_bytes . Stats.gc)
+     , ("rts.gc.current_bytes_slop"       , Gauge . fromIntegral . Stats.gcdetails_slop_bytes . Stats.gc)
+     , ("rts.gc.max_bytes_slop"           , Gauge . fromIntegral . Stats.max_slop_bytes)
+     , ("rts.gc.peak_megabytes_allocated" , Gauge . fromIntegral . (`quot` (1024*1024)) . Stats.max_mem_in_use_bytes)
+     , ("rts.gc.par_tot_bytes_copied"     , Gauge . fromIntegral . Stats.par_copied_bytes)
+     , ("rts.gc.par_avg_bytes_copied"     , Gauge . fromIntegral . Stats.par_copied_bytes)
+     , ("rts.gc.par_max_bytes_copied"     , Gauge . fromIntegral . Stats.cumulative_par_max_copied_bytes)
+     ])
+    getRTSStats
+#else
+    (M.fromList
      [ ("rts.gc.bytes_allocated"          , Counter . Stats.bytesAllocated)
      , ("rts.gc.num_gcs"                  , Counter . Stats.numGcs)
      , ("rts.gc.num_bytes_usage_samples"  , Counter . Stats.numByteUsageSamples)
      , ("rts.gc.cumulative_bytes_used"    , Counter . Stats.cumulativeBytesUsed)
      , ("rts.gc.bytes_copied"             , Counter . Stats.bytesCopied)
-     , ("rts.gc.mutator_cpu_ms"           , Counter . toMs . Stats.mutatorCpuSeconds)
-     , ("rts.gc.mutator_wall_ms"          , Counter . toMs . Stats.mutatorWallSeconds)
-     , ("rts.gc.gc_cpu_ms"                , Counter . toMs . Stats.gcCpuSeconds)
-     , ("rts.gc.gc_wall_ms"               , Counter . toMs . Stats.gcWallSeconds)
-     , ("rts.gc.cpu_ms"                   , Counter . toMs . Stats.cpuSeconds)
-     , ("rts.gc.wall_ms"                  , Counter . toMs . Stats.wallSeconds)
+     , ("rts.gc.mutator_cpu_ms"           , Counter . sToMs . Stats.mutatorCpuSeconds)
+     , ("rts.gc.mutator_wall_ms"          , Counter . sToMs . Stats.mutatorWallSeconds)
+     , ("rts.gc.gc_cpu_ms"                , Counter . sToMs . Stats.gcCpuSeconds)
+     , ("rts.gc.gc_wall_ms"               , Counter . sToMs . Stats.gcWallSeconds)
+     , ("rts.gc.cpu_ms"                   , Counter . sToMs . Stats.cpuSeconds)
+     , ("rts.gc.wall_ms"                  , Counter . sToMs . Stats.wallSeconds)
      , ("rts.gc.max_bytes_used"           , Gauge . Stats.maxBytesUsed)
      , ("rts.gc.current_bytes_used"       , Gauge . Stats.currentBytesUsed)
      , ("rts.gc.current_bytes_slop"       , Gauge . Stats.currentBytesSlop)
@@ -432,11 +462,68 @@
      , ("rts.gc.par_max_bytes_copied"     , Gauge . Stats.parMaxBytesCopied)
      ])
     getGcStats
+#endif
     store
 
+#if MIN_VERSION_base(4,10,0)
+-- | Get RTS statistics.
+getRTSStats :: IO Stats.RTSStats
+getRTSStats = do
+    enabled <- Stats.getRTSStatsEnabled
+    if enabled
+        then Stats.getRTSStats
+        else return emptyRTSStats
+
+-- | Empty RTS statistics, as if the application hasn't started yet.
+emptyRTSStats :: Stats.RTSStats
+emptyRTSStats = Stats.RTSStats
+    { gcs                                  = 0
+    , major_gcs                            = 0
+    , allocated_bytes                      = 0
+    , max_live_bytes                       = 0
+    , max_large_objects_bytes              = 0
+    , max_compact_bytes                    = 0
+    , max_slop_bytes                       = 0
+    , max_mem_in_use_bytes                 = 0
+    , cumulative_live_bytes                = 0
+    , copied_bytes                         = 0
+    , par_copied_bytes                     = 0
+    , cumulative_par_max_copied_bytes      = 0
+# if MIN_VERSION_base(4,11,0)
+    , cumulative_par_balanced_copied_bytes = 0
+# endif
+    , mutator_cpu_ns                       = 0
+    , mutator_elapsed_ns                   = 0
+    , gc_cpu_ns                            = 0
+    , gc_elapsed_ns                        = 0
+    , cpu_ns                               = 0
+    , elapsed_ns                           = 0
+    , gc                                   = emptyGCDetails
+    }
+
+emptyGCDetails :: Stats.GCDetails
+emptyGCDetails = Stats.GCDetails
+    { gcdetails_gen                       = 0
+    , gcdetails_threads                   = 0
+    , gcdetails_allocated_bytes           = 0
+    , gcdetails_live_bytes                = 0
+    , gcdetails_large_objects_bytes       = 0
+    , gcdetails_compact_bytes             = 0
+    , gcdetails_slop_bytes                = 0
+    , gcdetails_mem_in_use_bytes          = 0
+    , gcdetails_copied_bytes              = 0
+    , gcdetails_par_max_copied_bytes      = 0
+# if MIN_VERSION_base(4,11,0)
+    , gcdetails_par_balanced_copied_bytes = 0
+# endif
+    , gcdetails_sync_elapsed_ns           = 0
+    , gcdetails_cpu_ns                    = 0
+    , gcdetails_elapsed_ns                = 0
+    }
+#else
 -- | Get GC statistics.
 getGcStats :: IO Stats.GCStats
-#if MIN_VERSION_base(4,6,0)
+# if MIN_VERSION_base(4,6,0)
 getGcStats = do
     enabled <- Stats.getGCStatsEnabled
     if enabled
@@ -445,7 +532,6 @@
 
 -- | Empty GC statistics, as if the application hasn't started yet.
 emptyGCStats :: Stats.GCStats
-# if MIN_VERSION_base(4,10,0)
 emptyGCStats = Stats.GCStats
     { bytesAllocated         = 0
     , numGcs                 = 0
@@ -465,40 +551,18 @@
     , wallSeconds            = 0
     , parTotBytesCopied      = 0
     , parMaxBytesCopied      = 0
-    , mblocksAllocated       = 0
     }
 # else
-emptyGCStats = Stats.GCStats
-    { bytesAllocated         = 0
-    , numGcs                 = 0
-    , maxBytesUsed           = 0
-    , numByteUsageSamples    = 0
-    , cumulativeBytesUsed    = 0
-    , bytesCopied            = 0
-    , currentBytesUsed       = 0
-    , currentBytesSlop       = 0
-    , maxBytesSlop           = 0
-    , peakMegabytesAllocated = 0
-    , mutatorCpuSeconds      = 0
-    , mutatorWallSeconds     = 0
-    , gcCpuSeconds           = 0
-    , gcWallSeconds          = 0
-    , cpuSeconds             = 0
-    , wallSeconds            = 0
-    , parTotBytesCopied      = 0
-    , parMaxBytesCopied      = 0
-    }
-# endif
-#else
 getGcStats = Stats.getGCStats
-#endif
+# endif
 
 -- | Helper to work around rename in GHC.Stats in base-4.6.
 gcParTotBytesCopied :: Stats.GCStats -> Int64
-#if MIN_VERSION_base(4,6,0)
+# if MIN_VERSION_base(4,6,0)
 gcParTotBytesCopied = Stats.parTotBytesCopied
-#else
+# else
 gcParTotBytesCopied = Stats.parAvgBytesCopied
+# endif
 #endif
 
 ------------------------------------------------------------------------
diff --git a/ekg-core.cabal b/ekg-core.cabal
--- a/ekg-core.cabal
+++ b/ekg-core.cabal
@@ -1,5 +1,5 @@
 name:                ekg-core
-version:             0.1.1.3
+version:             0.1.1.4
 synopsis:            Tracking of system metrics
 description:
   This library lets you defined and track system metrics.
@@ -14,7 +14,8 @@
 build-type:          Simple
 extra-source-files:  CHANGES.md
 cabal-version:       >=1.10
-tested-with:         GHC==8.2.1, GHC==8.0.2, GHC == 7.10.3, GHC == 7.8.4, GHC == 7.6.3
+tested-with:         GHC == 8.4.1, GHC == 8.2.2, GHC == 8.0.2, GHC == 7.10.3
+                   , GHC == 7.8.4, GHC == 7.6.3
 
 library
   exposed-modules:
