diff --git a/deps/histogram/histogram.gyp b/deps/histogram/histogram.gyp
index 54999412ad99d7..3ab9bb070c64d6 100644
--- a/deps/histogram/histogram.gyp
+++ b/deps/histogram/histogram.gyp
@@ -2,6 +2,7 @@
   'variables': {
     'histogram_sources': [
       'src/hdr_histogram.c',
+      'include/hdr/hdr_histogram.h',
     ]
   },
   'targets': [
@@ -12,9 +13,9 @@
       'xcode_settings': {
         'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES',  # -fvisibility=hidden
       },
-      'include_dirs': ['src'],
+      'include_dirs': ['src', 'include'],
       'direct_dependent_settings': {
-        'include_dirs': [ 'src' ]
+        'include_dirs': [ 'src', 'include' ]
       },
       'sources': [
         '<@(histogram_sources)',
diff --git a/deps/histogram/src/hdr_histogram.h b/deps/histogram/include/hdr/hdr_histogram.h
similarity index 90%
rename from deps/histogram/src/hdr_histogram.h
rename to deps/histogram/include/hdr/hdr_histogram.h
index aff51f1c11526a..59ffe54d5cdd1d 100644
--- a/deps/histogram/src/hdr_histogram.h
+++ b/deps/histogram/include/hdr/hdr_histogram.h
@@ -16,7 +16,7 @@
 
 struct hdr_histogram
 {
-    int64_t lowest_trackable_value;
+    int64_t lowest_discernible_value;
     int64_t highest_trackable_value;
     int32_t unit_magnitude;
     int32_t significant_figures;
@@ -45,8 +45,8 @@ extern "C" {
  * involved math on the input parameters this function it is tricky to stack allocate.
  * The histogram should be released with hdr_close
  *
- * @param lowest_trackable_value The smallest possible value to be put into the
- * histogram.
+ * @param lowest_discernible_value The smallest possible value that is distinguishable from 0.
+ * Must be a positive integer that is >= 1. May be internally rounded down to nearest power of 2.
  * @param highest_trackable_value The largest possible value to be put into the
  * histogram.
  * @param significant_figures The level of precision for this histogram, i.e. the number
@@ -54,12 +54,12 @@ extern "C" {
  * the results from the histogram will be accurate up to the first three digits.  Must
  * be a value between 1 and 5 (inclusive).
  * @param result Output parameter to capture allocated histogram.
- * @return 0 on success, EINVAL if lowest_trackable_value is < 1 or the
+ * @return 0 on success, EINVAL if lowest_discernible_value is < 1 or the
  * significant_figure value is outside of the allowed range, ENOMEM if malloc
  * failed.
  */
 int hdr_init(
-    int64_t lowest_trackable_value,
+    int64_t lowest_discernible_value,
     int64_t highest_trackable_value,
     int significant_figures,
     struct hdr_histogram** result);
@@ -159,10 +159,10 @@ bool hdr_record_values_atomic(struct hdr_histogram* h, int64_t value, int64_t co
  * Record a value in the histogram and backfill based on an expected interval.
  *
  * Records a value in the histogram, will round this value of to a precision at or better
- * than the significant_figure specified at contruction time.  This is specifically used
+ * than the significant_figure specified at construction time.  This is specifically used
  * for recording latency.  If the value is larger than the expected_interval then the
  * latency recording system has experienced co-ordinated omission.  This method fills in the
- * values that would have occured had the client providing the load not been blocked.
+ * values that would have occurred had the client providing the load not been blocked.
 
  * @param h "This" pointer
  * @param value Value to add to the histogram
@@ -170,16 +170,16 @@ bool hdr_record_values_atomic(struct hdr_histogram* h, int64_t value, int64_t co
  * @return false if the value is larger than the highest_trackable_value and can't be recorded,
  * true otherwise.
  */
-bool hdr_record_corrected_value(struct hdr_histogram* h, int64_t value, int64_t expexcted_interval);
+bool hdr_record_corrected_value(struct hdr_histogram* h, int64_t value, int64_t expected_interval);
 
 /**
  * Record a value in the histogram and backfill based on an expected interval.
  *
  * Records a value in the histogram, will round this value of to a precision at or better
- * than the significant_figure specified at contruction time.  This is specifically used
+ * than the significant_figure specified at construction time.  This is specifically used
  * for recording latency.  If the value is larger than the expected_interval then the
  * latency recording system has experienced co-ordinated omission.  This method fills in the
- * values that would have occured had the client providing the load not been blocked.
+ * values that would have occurred had the client providing the load not been blocked.
  *
  * Will record this value atomically, however the whole structure may appear inconsistent
  * when read concurrently with this update.  Do NOT mix calls to this method with calls
@@ -191,7 +191,7 @@ bool hdr_record_corrected_value(struct hdr_histogram* h, int64_t value, int64_t
  * @return false if the value is larger than the highest_trackable_value and can't be recorded,
  * true otherwise.
  */
-bool hdr_record_corrected_value_atomic(struct hdr_histogram* h, int64_t value, int64_t expexcted_interval);
+bool hdr_record_corrected_value_atomic(struct hdr_histogram* h, int64_t value, int64_t expected_interval);
 
 /**
  * Record a value in the histogram 'count' times.  Applies the same correcting logic
@@ -226,7 +226,7 @@ bool hdr_record_corrected_values_atomic(struct hdr_histogram* h, int64_t value,
 /**
  * Adds all of the values from 'from' to 'this' histogram.  Will return the
  * number of values that are dropped when copying.  Values will be dropped
- * if they around outside of h.lowest_trackable_value and
+ * if they around outside of h.lowest_discernible_value and
  * h.highest_trackable_value.
  *
  * @param h "This" pointer
@@ -238,7 +238,7 @@ int64_t hdr_add(struct hdr_histogram* h, const struct hdr_histogram* from);
 /**
  * Adds all of the values from 'from' to 'this' histogram.  Will return the
  * number of values that are dropped when copying.  Values will be dropped
- * if they around outside of h.lowest_trackable_value and
+ * if they around outside of h.lowest_discernible_value and
  * h.highest_trackable_value.
  *
  * @param h "This" pointer
@@ -272,6 +272,18 @@ int64_t hdr_max(const struct hdr_histogram* h);
  */
 int64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile);
 
+/**
+ * Get the values at the given percentiles.
+ *
+ * @param h "This" pointer.
+ * @param percentiles The ordered percentiles array to get the values for.
+ * @param length Number of elements in the arrays.
+ * @param values Destination array containing the values at the given percentiles.
+ * The values array should be allocated by the caller.
+ * @return 0 on success, ENOMEM if the provided destination array is null.
+ */
+int hdr_value_at_percentiles(const struct hdr_histogram *h, const double *percentiles, int64_t *values, size_t length);
+
 /**
  * Gets the standard deviation for the values in the histogram.
  *
@@ -465,7 +477,7 @@ int hdr_percentiles_print(
 */
 struct hdr_histogram_bucket_config
 {
-    int64_t lowest_trackable_value;
+    int64_t lowest_discernible_value;
     int64_t highest_trackable_value;
     int64_t unit_magnitude;
     int64_t significant_figures;
@@ -478,7 +490,7 @@ struct hdr_histogram_bucket_config
 };
 
 int hdr_calculate_bucket_config(
-    int64_t lowest_trackable_value,
+    int64_t lowest_discernible_value,
     int64_t highest_trackable_value,
     int significant_figures,
     struct hdr_histogram_bucket_config* cfg);
@@ -492,7 +504,7 @@ int64_t hdr_next_non_equivalent_value(const struct hdr_histogram* h, int64_t val
 int64_t hdr_median_equivalent_value(const struct hdr_histogram* h, int64_t value);
 
 /**
- * Used to reset counters after importing data manuallying into the histogram, used by the logging code
+ * Used to reset counters after importing data manually into the histogram, used by the logging code
  * and other custom serialisation tools.
  */
 void hdr_reset_internal_counters(struct hdr_histogram* h);
diff --git a/deps/histogram/include/hdr/hdr_histogram_version.h b/deps/histogram/include/hdr/hdr_histogram_version.h
new file mode 100644
index 00000000000000..a9a4300170875a
--- /dev/null
+++ b/deps/histogram/include/hdr/hdr_histogram_version.h
@@ -0,0 +1,12 @@
+/**
+ * hdr_histogram_version.h
+ * Written by Marco Ippolito, Michael Barker and released to the public domain,
+ * as explained at http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+#ifndef HDR_HISTOGRAM_VERSION_H
+#define HDR_HISTOGRAM_VERSION_H
+
+#define HDR_HISTOGRAM_VERSION "0.11.8"
+
+#endif  // HDR_HISTOGRAM_VERSION_H
diff --git a/deps/histogram/src/hdr_histogram.c b/deps/histogram/src/hdr_histogram.c
index 0132cbeba7c84e..7a4c4fdfa30ff6 100644
--- a/deps/histogram/src/hdr_histogram.c
+++ b/deps/histogram/src/hdr_histogram.c
@@ -13,10 +13,16 @@
 #include <errno.h>
 #include <inttypes.h>
 
-#include "hdr_histogram.h"
+#include <hdr/hdr_histogram.h>
 #include "hdr_tests.h"
 #include "hdr_atomic.h"
 
+#ifndef HDR_MALLOC_INCLUDE
+#define HDR_MALLOC_INCLUDE "hdr_malloc.h"
+#endif
+
+#include HDR_MALLOC_INCLUDE
+
 /*  ######   #######  ##     ## ##    ## ########  ######  */
 /* ##    ## ##     ## ##     ## ###   ##    ##    ##    ## */
 /* ##       ##     ## ##     ## ####  ##    ##    ##       */
@@ -216,6 +222,15 @@ int64_t hdr_size_of_equivalent_value_range(const struct hdr_histogram* h, int64_
     return INT64_C(1) << (h->unit_magnitude + adjusted_bucket);
 }
 
+static int64_t size_of_equivalent_value_range_given_bucket_indices(
+    const struct hdr_histogram *h,
+    int32_t bucket_index,
+    int32_t sub_bucket_index)
+{
+    const int32_t adjusted_bucket  = (sub_bucket_index >= h->sub_bucket_count) ? (bucket_index + 1) : bucket_index;
+    return INT64_C(1) << (h->unit_magnitude + adjusted_bucket);
+}
+
 static int64_t lowest_equivalent_value(const struct hdr_histogram* h, int64_t value)
 {
     int32_t bucket_index     = get_bucket_index(h, value);
@@ -223,6 +238,14 @@ static int64_t lowest_equivalent_value(const struct hdr_histogram* h, int64_t va
     return value_from_index(bucket_index, sub_bucket_index, h->unit_magnitude);
 }
 
+static int64_t lowest_equivalent_value_given_bucket_indices(
+    const struct hdr_histogram *h,
+    int32_t bucket_index,
+    int32_t sub_bucket_index)
+{
+    return value_from_index(bucket_index, sub_bucket_index, h->unit_magnitude);
+}
+
 int64_t hdr_next_non_equivalent_value(const struct hdr_histogram *h, int64_t value)
 {
     return lowest_equivalent_value(h, value) + hdr_size_of_equivalent_value_range(h, value);
@@ -318,7 +341,7 @@ static int32_t buckets_needed_to_cover_value(int64_t value, int32_t sub_bucket_c
 /* ##     ## ######## ##     ##  #######  ##     ##    ##    */
 
 int hdr_calculate_bucket_config(
-        int64_t lowest_trackable_value,
+        int64_t lowest_discernible_value,
         int64_t highest_trackable_value,
         int significant_figures,
         struct hdr_histogram_bucket_config* cfg)
@@ -326,14 +349,14 @@ int hdr_calculate_bucket_config(
     int32_t sub_bucket_count_magnitude;
     int64_t largest_value_with_single_unit_resolution;
 
-    if (lowest_trackable_value < 1 ||
+    if (lowest_discernible_value < 1 ||
             significant_figures < 1 || 5 < significant_figures ||
-            lowest_trackable_value * 2 > highest_trackable_value)
+            lowest_discernible_value * 2 > highest_trackable_value)
     {
         return EINVAL;
     }
 
-    cfg->lowest_trackable_value = lowest_trackable_value;
+    cfg->lowest_discernible_value = lowest_discernible_value;
     cfg->significant_figures = significant_figures;
     cfg->highest_trackable_value = highest_trackable_value;
 
@@ -341,7 +364,7 @@ int hdr_calculate_bucket_config(
     sub_bucket_count_magnitude = (int32_t) ceil(log((double)largest_value_with_single_unit_resolution) / log(2));
     cfg->sub_bucket_half_count_magnitude = ((sub_bucket_count_magnitude > 1) ? sub_bucket_count_magnitude : 1) - 1;
 
-    double unit_magnitude = log((double)lowest_trackable_value) / log(2);
+    double unit_magnitude = log((double)lowest_discernible_value) / log(2);
     if (INT32_MAX < unit_magnitude)
     {
         return EINVAL;
@@ -365,7 +388,7 @@ int hdr_calculate_bucket_config(
 
 void hdr_init_preallocated(struct hdr_histogram* h, struct hdr_histogram_bucket_config* cfg)
 {
-    h->lowest_trackable_value          = cfg->lowest_trackable_value;
+    h->lowest_discernible_value        = cfg->lowest_discernible_value;
     h->highest_trackable_value         = cfg->highest_trackable_value;
     h->unit_magnitude                  = (int32_t)cfg->unit_magnitude;
     h->significant_figures             = (int32_t)cfg->significant_figures;
@@ -383,7 +406,7 @@ void hdr_init_preallocated(struct hdr_histogram* h, struct hdr_histogram_bucket_
 }
 
 int hdr_init(
-        int64_t lowest_trackable_value,
+        int64_t lowest_discernible_value,
         int64_t highest_trackable_value,
         int significant_figures,
         struct hdr_histogram** result)
@@ -392,22 +415,22 @@ int hdr_init(
     struct hdr_histogram_bucket_config cfg;
     struct hdr_histogram* histogram;
 
-    int r = hdr_calculate_bucket_config(lowest_trackable_value, highest_trackable_value, significant_figures, &cfg);
+    int r = hdr_calculate_bucket_config(lowest_discernible_value, highest_trackable_value, significant_figures, &cfg);
     if (r)
     {
         return r;
     }
 
-    counts = (int64_t*) calloc((size_t) cfg.counts_len, sizeof(int64_t));
+    counts = (int64_t*) hdr_calloc((size_t) cfg.counts_len, sizeof(int64_t));
     if (!counts)
     {
         return ENOMEM;
     }
 
-    histogram = (struct hdr_histogram*) calloc(1, sizeof(struct hdr_histogram));
+    histogram = (struct hdr_histogram*) hdr_calloc(1, sizeof(struct hdr_histogram));
     if (!histogram)
     {
-        free(counts);
+        hdr_free(counts);
         return ENOMEM;
     }
 
@@ -422,8 +445,8 @@ int hdr_init(
 void hdr_close(struct hdr_histogram* h)
 {
     if (h) {
-	free(h->counts);
-	free(h);
+	hdr_free(h->counts);
+	hdr_free(h);
     }
 }
 
@@ -643,47 +666,89 @@ int64_t hdr_min(const struct hdr_histogram* h)
     return non_zero_min(h);
 }
 
+static int64_t get_value_from_idx_up_to_count(const struct hdr_histogram* h, int64_t count_at_percentile)
+{
+    int64_t count_to_idx = 0;
+
+    count_at_percentile = 0 < count_at_percentile ? count_at_percentile : 1;
+    for (int32_t idx = 0; idx < h->counts_len; idx++)
+    {
+        count_to_idx += h->counts[idx];
+        if (count_to_idx >= count_at_percentile)
+        {
+            return hdr_value_at_index(h, idx);
+        }
+    }
+
+    return 0;
+}
+
+
 int64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile)
 {
-    struct hdr_iter iter;
-    int64_t total = 0;
     double requested_percentile = percentile < 100.0 ? percentile : 100.0;
     int64_t count_at_percentile =
         (int64_t) (((requested_percentile / 100) * h->total_count) + 0.5);
-    count_at_percentile = count_at_percentile > 1 ? count_at_percentile : 1;
+    int64_t value_from_idx = get_value_from_idx_up_to_count(h, count_at_percentile);
+    if (percentile == 0.0)
+    {
+        return lowest_equivalent_value(h, value_from_idx);
+    }
+    return highest_equivalent_value(h, value_from_idx);
+}
 
-    hdr_iter_init(&iter, h);
+int hdr_value_at_percentiles(const struct hdr_histogram *h, const double *percentiles, int64_t *values, size_t length)
+{
+    if (NULL == percentiles || NULL == values)
+    {
+        return EINVAL;
+    }
 
-    while (hdr_iter_next(&iter))
+    struct hdr_iter iter;
+    const int64_t total_count = h->total_count;
+    // to avoid allocations we use the values array for intermediate computation
+    // i.e. to store the expected cumulative count at each percentile
+    for (size_t i = 0; i < length; i++)
     {
-        total += iter.count;
+        const double requested_percentile = percentiles[i] < 100.0 ? percentiles[i] : 100.0;
+        const int64_t count_at_percentile =
+        (int64_t) (((requested_percentile / 100) * total_count) + 0.5);
+        values[i] = count_at_percentile > 1 ? count_at_percentile : 1;
+    }
 
-        if (total >= count_at_percentile)
+    hdr_iter_init(&iter, h);
+    int64_t total = 0;
+    size_t at_pos = 0;
+    while (hdr_iter_next(&iter) && at_pos < length)
+    {
+        total += iter.count;
+        while (at_pos < length && total >= values[at_pos])
         {
-            int64_t value_from_index = iter.value;
-            return highest_equivalent_value(h, value_from_index);
+            values[at_pos] = highest_equivalent_value(h, iter.value);
+            at_pos++;
         }
     }
-
     return 0;
 }
 
 double hdr_mean(const struct hdr_histogram* h)
 {
     struct hdr_iter iter;
-    int64_t total = 0;
+    int64_t total = 0, count = 0;
+    int64_t total_count = h->total_count;
 
     hdr_iter_init(&iter, h);
 
-    while (hdr_iter_next(&iter))
+    while (hdr_iter_next(&iter) && count < total_count)
     {
         if (0 != iter.count)
         {
+            count += iter.count;
             total += iter.count * hdr_median_equivalent_value(h, iter.value);
         }
     }
 
-    return (total * 1.0) / h->total_count;
+    return (total * 1.0) / total_count;
 }
 
 double hdr_stddev(const struct hdr_histogram* h)
@@ -757,11 +822,16 @@ static bool move_next(struct hdr_iter* iter)
 
     iter->count = counts_get_normalised(iter->h, iter->counts_index);
     iter->cumulative_count += iter->count;
-
-    iter->value = hdr_value_at_index(iter->h, iter->counts_index);
-    iter->highest_equivalent_value = highest_equivalent_value(iter->h, iter->value);
-    iter->lowest_equivalent_value = lowest_equivalent_value(iter->h, iter->value);
-    iter->median_equivalent_value = hdr_median_equivalent_value(iter->h, iter->value);
+    const int64_t value = hdr_value_at_index(iter->h, iter->counts_index);
+    const int32_t bucket_index = get_bucket_index(iter->h, value);
+    const int32_t sub_bucket_index = get_sub_bucket_index(value, bucket_index, iter->h->unit_magnitude);
+    const int64_t leq = lowest_equivalent_value_given_bucket_indices(iter->h, bucket_index, sub_bucket_index);
+    const int64_t size_of_equivalent_value_range = size_of_equivalent_value_range_given_bucket_indices(
+        iter->h, bucket_index, sub_bucket_index);
+    iter->lowest_equivalent_value = leq;
+    iter->value = value;
+    iter->highest_equivalent_value = leq + size_of_equivalent_value_range - 1;
+    iter->median_equivalent_value = leq + (size_of_equivalent_value_range >> 1);
 
     return true;
 }
diff --git a/deps/histogram/src/hdr_malloc.h b/deps/histogram/src/hdr_malloc.h
new file mode 100644
index 00000000000000..6fefc6881b1df8
--- /dev/null
+++ b/deps/histogram/src/hdr_malloc.h
@@ -0,0 +1,19 @@
+/**
+ * hdr_malloc.h
+ * Written by Filipe Oliveira and released to the public domain,
+ * as explained at http://creativecommons.org/publicdomain/zero/1.0/
+ *
+ * Allocator selection.
+ *
+ * This file is used in order to change the HdrHistogram allocator at compile time.
+ * Just define the following defines to what you want to use. Also add
+ * the include of your alternate allocator if needed (not needed in order
+ * to use the default libc allocator). */
+
+#ifndef HDR_MALLOC_H__
+#define HDR_MALLOC_H__
+#define hdr_malloc malloc
+#define hdr_calloc calloc
+#define hdr_realloc realloc
+#define hdr_free free
+#endif
diff --git a/deps/histogram/src/hdr_tests.h b/deps/histogram/src/hdr_tests.h
index c016d3a6de09aa..5cc65a0c71d008 100644
--- a/deps/histogram/src/hdr_tests.h
+++ b/deps/histogram/src/hdr_tests.h
@@ -3,7 +3,7 @@
 
 /* These are functions used in tests and are not intended for normal usage. */
 
-#include "hdr_histogram.h"
+#include <hdr/hdr_histogram.h>
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/src/histogram.h b/src/histogram.h
index b3df6c975d90b0..773161fedbd2ed 100644
--- a/src/histogram.h
+++ b/src/histogram.h
@@ -3,13 +3,13 @@
 
 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
 
-#include "hdr_histogram.h"
+#include <hdr/hdr_histogram.h>
 #include "base_object.h"
 #include "memory_tracker.h"
 #include "node_messaging.h"
 #include "util.h"
-#include "v8.h"
 #include "uv.h"
+#include "v8.h"
 
 #include <functional>
 #include <limits>