diff --git a/tests/test_base.py b/tests/test_base.py
index a8eb3b4d..873f4c72 100644
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -737,6 +737,21 @@ def scheduler():
 
 class TestBaseUV(_TestBase, UVTestCase):
 
+    def test__event_loop_utilization(self):
+        self.assertTrue(self.loop._event_loop_utilization() == (0., 0., 0.))
+
+        async def run():
+            await asyncio.sleep(0.2)
+            time.sleep(0.05)
+            return self.loop._event_loop_utilization()
+
+        i, a, p = self.loop.run_until_complete(run())
+        self.assertTrue(100 < i < 400)
+        self.assertTrue(a > 0.)
+        self.assertTrue(0. < p < 1.)
+
+        self.assertTrue(self.loop._event_loop_utilization() == (0., 0., 0.))
+
     def test_loop_create_future(self):
         fut = self.loop.create_future()
         self.assertTrue(isinstance(fut, asyncio.Future))
diff --git a/uvloop/includes/uv.pxd b/uvloop/includes/uv.pxd
index 87651306..d09bb41e 100644
--- a/uvloop/includes/uv.pxd
+++ b/uvloop/includes/uv.pxd
@@ -202,6 +202,10 @@ cdef extern from "uv.h" nogil:
         UV_REQ_TYPE_PRIVATE,
         UV_REQ_TYPE_MAX
 
+    ctypedef enum uv_loop_option:
+        UV_LOOP_BLOCK_SIGNAL = 0,
+        UV_METRICS_IDLE_TIME
+
     ctypedef enum uv_run_mode:
         UV_RUN_DEFAULT = 0,
         UV_RUN_ONCE,
@@ -281,6 +285,7 @@ cdef extern from "uv.h" nogil:
     int uv_loop_init(uv_loop_t* loop)
     int uv_loop_close(uv_loop_t* loop)
     int uv_loop_alive(uv_loop_t* loop)
+    int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...)
     int uv_loop_fork(uv_loop_t* loop)
     int uv_backend_fd(uv_loop_t* loop)
 
@@ -458,6 +463,10 @@ cdef extern from "uv.h" nogil:
                              uv_calloc_func calloc_func,
                              uv_free_func free_func)
 
+    # Metrics
+
+    uint64_t uv_metrics_idle_time(uv_loop_t* loop)
+
     # Process
 
     ctypedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status,
diff --git a/uvloop/loop.pxd b/uvloop/loop.pxd
index 56134733..a941aa4b 100644
--- a/uvloop/loop.pxd
+++ b/uvloop/loop.pxd
@@ -138,6 +138,7 @@ cdef class Loop:
 
     cdef _close(self)
     cdef _stop(self, exc)
+    cdef uint64_t _event_loop_idle_time(self)
     cdef uint64_t _time(self)
 
     cdef inline _queue_write(self, UVStream stream)
diff --git a/uvloop/loop.pyi b/uvloop/loop.pyi
index 9c8c4623..d0151d3d 100644
--- a/uvloop/loop.pyi
+++ b/uvloop/loop.pyi
@@ -37,6 +37,7 @@ class Loop:
     def call_at(
         self, when: float, callback: Callable[..., Any], *args: Any, context: Optional[Any] = ...
     ) -> asyncio.TimerHandle: ...
+    def _event_loop_utilization(self) -> Tuple[float, float, float]: ...
     def time(self) -> float: ...
     def stop(self) -> None: ...
     def run_forever(self) -> None: ...
diff --git a/uvloop/loop.pyx b/uvloop/loop.pyx
index b2ae509b..1db91518 100644
--- a/uvloop/loop.pyx
+++ b/uvloop/loop.pyx
@@ -162,6 +162,10 @@ cdef class Loop:
         self._recv_buffer_in_use = 0
 
         err = uv.uv_loop_init(self.uvloop)
+        if err < 0:
+            raise convert_error(err)
+
+        err = uv.uv_loop_configure(self.uvloop, uv.UV_METRICS_IDLE_TIME)
         if err < 0:
             raise convert_error(err)
         self.uvloop.data = <void*> self
@@ -527,6 +531,7 @@ cdef class Loop:
 
         self._thread_id = PyThread_get_thread_ident()
         self._running = 1
+        self._loop_start_time = self._time()
 
         self.handler_check__exec_writes.start()
         self.handler_idle.start()
@@ -628,6 +633,10 @@ cdef class Loop:
             self._default_executor = None
             executor.shutdown(wait=False)
 
+    cdef uint64_t _event_loop_idle_time(self):
+        """Returns number of nanoseconds the loop has been idle"""
+        return uv.uv_metrics_idle_time(self.uvloop)
+
     cdef uint64_t _time(self):
         # asyncio doesn't have a time cache, neither should uvloop.
         uv.uv_update_time(self.uvloop)  # void
@@ -1337,6 +1346,24 @@ cdef class Loop:
         return self.call_later(
             when - self.time(), callback, *args, context=context)
 
+    def _event_loop_utilization(self):
+        """Returns idle and active time in milliseconds and the percentage of
+        time the event loop is active
+        """
+
+        idle = 0.
+        active = 0.
+        utilization = 0.
+
+        if not self._running:
+            return idle, active, utilization
+
+        idle = self._event_loop_idle_time() / 10 ** 6
+        active = self._time() - self._loop_start_time - idle
+        utilization = active / (active + idle)
+
+        return idle, active, utilization
+
     def time(self):
         """Return the time according to the event loop's clock.