diff --git a/include/grpc/support/time.h b/include/grpc/support/time.h
index 1fd3181859f584e92168b71e10f63990fd6d1a3e..a5c947dfc8bd3e4edd04cce99b40e8039b16dd5d 100644
--- a/include/grpc/support/time.h
+++ b/include/grpc/support/time.h
@@ -46,8 +46,8 @@ extern "C" {
 #endif
 
 typedef struct gpr_timespec {
-    time_t tv_sec;
-    int tv_nsec;
+  time_t tv_sec;
+  int tv_nsec;
 } gpr_timespec;
 
 /* Time constants. */
@@ -62,8 +62,20 @@ extern const gpr_timespec gpr_inf_past;   /* The far past. */
 #define GPR_NS_PER_US 1000
 #define GPR_US_PER_MS 1000
 
-/* Return the current time measured from the system's default epoch. */
-gpr_timespec gpr_now(void);
+/* The clocks we support. */
+typedef enum {
+  /* Monotonic clock. Epoch undefined. Always moves forwards. */
+  GPR_CLOCK_MONOTONIC = 0,
+  /* Realtime clock. May jump forwards or backwards. Settable by
+     the system administrator. Has its epoch at 0:00:00 UTC 1 Jan 1970. */
+  GPR_CLOCK_REALTIME
+} gpr_clock_type;
+
+/* initialize time subsystem */
+void gpr_time_init(void);
+
+/* Return the current time measured from the given clocks epoch. */
+gpr_timespec gpr_now(gpr_clock_type clock);
 
 /* Return -ve, 0, or +ve according to whether a < b, a == b, or a > b
    respectively.  */
@@ -100,4 +112,4 @@ double gpr_timespec_to_micros(gpr_timespec t);
 }
 #endif
 
-#endif  /* GRPC_SUPPORT_TIME_H */
+#endif /* GRPC_SUPPORT_TIME_H */
diff --git a/src/core/channel/census_filter.c b/src/core/channel/census_filter.c
index 43ef5fb3ffb0c7d8f9e0b2721db7aaa00afe77f1..d996c3475e42b80460799f414218009709aed404 100644
--- a/src/core/channel/census_filter.c
+++ b/src/core/channel/census_filter.c
@@ -151,7 +151,7 @@ static void client_init_call_elem(grpc_call_element* elem,
   call_data* d = elem->call_data;
   GPR_ASSERT(d != NULL);
   init_rpc_stats(&d->stats);
-  d->start_ts = gpr_now();
+  d->start_ts = gpr_now(GPR_CLOCK_REALTIME);
   d->op_id = census_tracing_start_op();
   if (initial_op) client_mutate_op(elem, initial_op);
 }
@@ -169,7 +169,7 @@ static void server_init_call_elem(grpc_call_element* elem,
   call_data* d = elem->call_data;
   GPR_ASSERT(d != NULL);
   init_rpc_stats(&d->stats);
-  d->start_ts = gpr_now();
+  d->start_ts = gpr_now(GPR_CLOCK_REALTIME);
   d->op_id = census_tracing_start_op();
   if (initial_op) server_mutate_op(elem, initial_op);
 }
@@ -177,8 +177,8 @@ static void server_init_call_elem(grpc_call_element* elem,
 static void server_destroy_call_elem(grpc_call_element* elem) {
   call_data* d = elem->call_data;
   GPR_ASSERT(d != NULL);
-  d->stats.elapsed_time_ms =
-      gpr_timespec_to_micros(gpr_time_sub(gpr_now(), d->start_ts));
+  d->stats.elapsed_time_ms = gpr_timespec_to_micros(
+      gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), d->start_ts));
   census_record_rpc_server_stats(d->op_id, &d->stats);
   census_tracing_end_op(d->op_id);
 }
diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c
index 6cf9062ab0c16a39a704de2ceb0ca2028dd446ff..8cdad1015f6425ccfd66995bda17367c61d0e461 100644
--- a/src/core/client_config/subchannel.c
+++ b/src/core/client_config/subchannel.c
@@ -300,7 +300,7 @@ static void continue_connect(grpc_subchannel *c) {
 }
 
 static void start_connect(grpc_subchannel *c) {
-  gpr_timespec now = gpr_now();
+  gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
   c->next_attempt = now;
   c->backoff_delta = gpr_time_from_seconds(1);
 
@@ -585,7 +585,7 @@ static void subchannel_connected(void *arg, int iomgr_success) {
     c->have_alarm = 1;
     c->next_attempt = gpr_time_add(c->next_attempt, c->backoff_delta);
     c->backoff_delta = gpr_time_add(c->backoff_delta, c->backoff_delta);
-    grpc_alarm_init(&c->alarm, c->next_attempt, on_alarm, c, gpr_now());
+    grpc_alarm_init(&c->alarm, c->next_attempt, on_alarm, c, gpr_now(GPR_CLOCK_REALTIME));
     gpr_mu_unlock(&c->mu);
   }
 }
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 4a2c45a023d107cd2874a832116cb815755a007e..cca92d3b32d987f147f219916fced4e521e4ed50 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -59,7 +59,7 @@ static void background_callback_executor(void *ignored) {
   while (!g_shutdown) {
     gpr_timespec deadline = gpr_inf_future;
     gpr_timespec short_deadline =
-        gpr_time_add(gpr_now(), gpr_time_from_millis(100));
+        gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(100));
     if (g_cbs_head) {
       grpc_iomgr_closure *closure = g_cbs_head;
       g_cbs_head = closure->next;
@@ -67,7 +67,8 @@ static void background_callback_executor(void *ignored) {
       gpr_mu_unlock(&g_mu);
       closure->cb(closure->cb_arg, closure->success);
       gpr_mu_lock(&g_mu);
-    } else if (grpc_alarm_check(&g_mu, gpr_now(), &deadline)) {
+    } else if (grpc_alarm_check(&g_mu, gpr_now(GPR_CLOCK_REALTIME),
+                                &deadline)) {
     } else {
       gpr_mu_unlock(&g_mu);
       gpr_sleep_until(gpr_time_min(short_deadline, deadline));
@@ -89,7 +90,7 @@ void grpc_iomgr_init(void) {
   gpr_thd_id id;
   gpr_mu_init(&g_mu);
   gpr_cv_init(&g_rcv);
-  grpc_alarm_list_init(gpr_now());
+  grpc_alarm_list_init(gpr_now(GPR_CLOCK_REALTIME));
   g_root_object.next = g_root_object.prev = &g_root_object;
   g_root_object.name = "root";
   grpc_iomgr_platform_init();
@@ -110,26 +111,27 @@ void grpc_iomgr_shutdown(void) {
   grpc_iomgr_object *obj;
   grpc_iomgr_closure *closure;
   gpr_timespec shutdown_deadline =
-      gpr_time_add(gpr_now(), gpr_time_from_seconds(10));
-  gpr_timespec last_warning_time = gpr_now();
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10));
+  gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
 
   gpr_mu_lock(&g_mu);
   g_shutdown = 1;
   while (g_cbs_head != NULL || g_root_object.next != &g_root_object) {
-    if (gpr_time_cmp(gpr_time_sub(gpr_now(), last_warning_time),
-                     gpr_time_from_seconds(1)) >= 0) {
-    if (g_cbs_head != NULL && g_root_object.next != &g_root_object) {
-      gpr_log(GPR_DEBUG,
-              "Waiting for %d iomgr objects to be destroyed and executing "
-              "final callbacks",
-              count_objects());
-    } else if (g_cbs_head != NULL) {
-      gpr_log(GPR_DEBUG, "Executing final iomgr callbacks");
-    } else {
-      gpr_log(GPR_DEBUG, "Waiting for %d iomgr objects to be destroyed",
-              count_objects());
-    }
-    last_warning_time = gpr_now();
+    if (gpr_time_cmp(
+            gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), last_warning_time),
+            gpr_time_from_seconds(1)) >= 0) {
+      if (g_cbs_head != NULL && g_root_object.next != &g_root_object) {
+        gpr_log(GPR_DEBUG,
+                "Waiting for %d iomgr objects to be destroyed and executing "
+                "final callbacks",
+                count_objects());
+      } else if (g_cbs_head != NULL) {
+        gpr_log(GPR_DEBUG, "Executing final iomgr callbacks");
+      } else {
+        gpr_log(GPR_DEBUG, "Waiting for %d iomgr objects to be destroyed",
+                count_objects());
+      }
+      last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
     }
     if (g_cbs_head) {
       do {
@@ -150,9 +152,9 @@ void grpc_iomgr_shutdown(void) {
     if (g_root_object.next != &g_root_object) {
       int timeout = 0;
       gpr_timespec short_deadline =
-          gpr_time_add(gpr_now(), gpr_time_from_millis(100));
+          gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(100));
       while (gpr_cv_wait(&g_rcv, &g_mu, short_deadline) && g_cbs_head == NULL) {
-        if (gpr_time_cmp(gpr_now(), shutdown_deadline) > 0) {
+        if (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), shutdown_deadline) > 0) {
           timeout = 1;
           break;
         }
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index 12496440dedd40c609fc3c495ec8ef2214fef937..85101764d2591b8c6917800105d8369498a8b385 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -122,7 +122,7 @@ static void finish_shutdown(grpc_pollset *pollset) {
 
 int grpc_pollset_work(grpc_pollset *pollset, gpr_timespec deadline) {
   /* pollset->mu already held */
-  gpr_timespec now = gpr_now();
+  gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
   if (gpr_time_cmp(now, deadline) > 0) {
     return 0;
   }
@@ -187,15 +187,16 @@ void grpc_pollset_destroy(grpc_pollset *pollset) {
   gpr_mu_destroy(&pollset->mu);
 }
 
-int grpc_poll_deadline_to_millis_timeout(gpr_timespec deadline, gpr_timespec now) {
+int grpc_poll_deadline_to_millis_timeout(gpr_timespec deadline,
+                                         gpr_timespec now) {
   gpr_timespec timeout;
   static const int max_spin_polling_us = 10;
   if (gpr_time_cmp(deadline, gpr_inf_future) == 0) {
     return -1;
   }
   if (gpr_time_cmp(
-        deadline, 
-        gpr_time_add(now, gpr_time_from_micros(max_spin_polling_us))) <= 0) {
+          deadline,
+          gpr_time_add(now, gpr_time_from_micros(max_spin_polling_us))) <= 0) {
     return 0;
   }
   timeout = gpr_time_sub(deadline, now);
diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c
index 8d6bc79c96c65245f091c238767f4658d09bfac9..24226cc9801c7fbdcc7b3fcec980524e915b82ef 100644
--- a/src/core/iomgr/pollset_windows.c
+++ b/src/core/iomgr/pollset_windows.c
@@ -70,7 +70,7 @@ void grpc_pollset_destroy(grpc_pollset *pollset) {
 
 int grpc_pollset_work(grpc_pollset *pollset, gpr_timespec deadline) {
   gpr_timespec now;
-  now = gpr_now();
+  now = gpr_now(GPR_CLOCK_REALTIME);
   if (gpr_time_cmp(now, deadline) > 0) {
     return 0 /* GPR_FALSE */;
   }
@@ -86,8 +86,6 @@ int grpc_pollset_work(grpc_pollset *pollset, gpr_timespec deadline) {
   return 1 /* GPR_TRUE */;
 }
 
-void grpc_pollset_kick(grpc_pollset *p) {
-  gpr_cv_signal(&p->cv);
-}
+void grpc_pollset_kick(grpc_pollset *p) { gpr_cv_signal(&p->cv); }
 
 #endif /* GPR_WINSOCK_SOCKET */
diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index 2c6ff4e9c43ea92149ae81f7aa69cb3c9b55c52f..dc0489e64f4b84bd166c5d920a50cb80f14f8112 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -253,7 +253,8 @@ void grpc_tcp_client_connect(void (*cb)(void *arg, grpc_endpoint *ep),
   ac->write_closure.cb_arg = ac;
 
   gpr_mu_lock(&ac->mu);
-  grpc_alarm_init(&ac->alarm, deadline, on_alarm, ac, gpr_now());
+  grpc_alarm_init(&ac->alarm, deadline, on_alarm, ac,
+                  gpr_now(GPR_CLOCK_REALTIME));
   grpc_fd_notify_on_write(ac->fd, &ac->write_closure);
   gpr_mu_unlock(&ac->mu);
 
diff --git a/src/core/iomgr/tcp_client_windows.c b/src/core/iomgr/tcp_client_windows.c
index b1a169b519206c1b1ab6cdba78419afde9703cd1..16741452b9134385fd6e663a6159b04a3f35163b 100644
--- a/src/core/iomgr/tcp_client_windows.c
+++ b/src/core/iomgr/tcp_client_windows.c
@@ -215,7 +215,8 @@ void grpc_tcp_client_connect(void (*cb)(void *arg, grpc_endpoint *tcp),
   ac->refs = 2;
   ac->aborted = 0;
 
-  grpc_alarm_init(&ac->alarm, deadline, on_alarm, ac, gpr_now());
+  grpc_alarm_init(&ac->alarm, deadline, on_alarm, ac,
+                  gpr_now(GPR_CLOCK_REALTIME));
   socket->write_info.outstanding = 1;
   grpc_socket_notify_on_write(socket, on_connect, ac);
   return;
diff --git a/src/core/profiling/timers_preciseclock.h b/src/core/profiling/timers_preciseclock.h
index 163d52b7974bb2b0478ec9482c537c527c3d57a3..5c251b47e6f01501895eac0f3ae9eb0d3abd0582 100644
--- a/src/core/profiling/timers_preciseclock.h
+++ b/src/core/profiling/timers_preciseclock.h
@@ -82,7 +82,7 @@ struct grpc_precise_clock {
   gpr_timespec clock;
 };
 static void grpc_precise_clock_now(grpc_precise_clock* clk) {
-  clk->clock = gpr_now();
+  clk->clock = gpr_now(GPR_CLOCK_REALTIME);
 }
 #define GRPC_PRECISE_CLOCK_FORMAT "%ld.%09d"
 #define GRPC_PRECISE_CLOCK_PRINTF_ARGS(clk) \
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 52fd5a25b317f9cd2d469fb371aa2912edb02d33..230f0dfb85faa966dbb4a221524453ba34332872 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -357,7 +357,8 @@ static void jwt_get_request_metadata(grpc_credentials *creds,
     if (c->cached.service_url != NULL &&
         strcmp(c->cached.service_url, service_url) == 0 &&
         c->cached.jwt_md != NULL &&
-        (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now()),
+        (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration,
+                                   gpr_now(GPR_CLOCK_REALTIME)),
                       refresh_threshold) > 0)) {
       jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md);
     }
@@ -374,7 +375,8 @@ static void jwt_get_request_metadata(grpc_credentials *creds,
       char *md_value;
       gpr_asprintf(&md_value, "Bearer %s", jwt);
       gpr_free(jwt);
-      c->cached.jwt_expiration = gpr_time_add(gpr_now(), c->jwt_lifetime);
+      c->cached.jwt_expiration =
+          gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime);
       c->cached.service_url = gpr_strdup(service_url);
       c->cached.jwt_md = grpc_credentials_md_store_create(1);
       grpc_credentials_md_store_add_cstrings(
@@ -545,7 +547,8 @@ static void on_oauth2_token_fetcher_http_response(
   status = grpc_oauth2_token_fetcher_credentials_parse_server_response(
       response, &c->access_token_md, &token_lifetime);
   if (status == GRPC_CREDENTIALS_OK) {
-    c->token_expiration = gpr_time_add(gpr_now(), token_lifetime);
+    c->token_expiration =
+        gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime);
     r->cb(r->user_data, c->access_token_md->entries,
           c->access_token_md->num_entries, status);
   } else {
@@ -567,8 +570,9 @@ static void oauth2_token_fetcher_get_request_metadata(
   {
     gpr_mu_lock(&c->mu);
     if (c->access_token_md != NULL &&
-        (gpr_time_cmp(gpr_time_sub(c->token_expiration, gpr_now()),
-                      refresh_threshold) > 0)) {
+        (gpr_time_cmp(
+             gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_REALTIME)),
+             refresh_threshold) > 0)) {
       cached_access_token_md =
           grpc_credentials_md_store_ref(c->access_token_md);
     }
@@ -582,7 +586,7 @@ static void oauth2_token_fetcher_get_request_metadata(
     c->fetch_func(
         grpc_credentials_metadata_request_create(creds, cb, user_data),
         &c->httpcli_context, pollset, on_oauth2_token_fetcher_http_response,
-        gpr_time_add(gpr_now(), refresh_threshold));
+        gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold));
   }
 }
 
diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c
index cd92f9dc30f56b8a2359b8aa755d8e7dd3c458c6..f622deff425cba57f93f09867f2d4903774186fb 100644
--- a/src/core/security/google_default_credentials.c
+++ b/src/core/security/google_default_credentials.c
@@ -103,9 +103,10 @@ static int is_stack_running_on_compute_engine(void) {
 
   grpc_httpcli_context_init(&context);
 
-  grpc_httpcli_get(&context, &detector.pollset, &request,
-                   gpr_time_add(gpr_now(), max_detection_delay),
-                   on_compute_engine_detection_http_response, &detector);
+  grpc_httpcli_get(
+      &context, &detector.pollset, &request,
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
+      on_compute_engine_detection_http_response, &detector);
 
   /* Block until we get the response. This is not ideal but this should only be
      called once for the lifetime of the process by the default credentials. */
diff --git a/src/core/security/json_token.c b/src/core/security/json_token.c
index 2e2b9801293add502ed707927602834fe4463877..9b1ea255aec1ed756c35e37540a8416cba10d38c 100644
--- a/src/core/security/json_token.c
+++ b/src/core/security/json_token.c
@@ -207,7 +207,7 @@ static char *encoded_jwt_claim(const grpc_auth_json_key *json_key,
   grpc_json *child = NULL;
   char *json_str = NULL;
   char *result = NULL;
-  gpr_timespec now = gpr_now();
+  gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
   gpr_timespec expiration = gpr_time_add(now, token_lifetime);
   char now_str[GPR_LTOA_MIN_BUFSIZE];
   char expiration_str[GPR_LTOA_MIN_BUFSIZE];
@@ -218,8 +218,8 @@ static char *encoded_jwt_claim(const grpc_auth_json_key *json_key,
   gpr_ltoa(now.tv_sec, now_str);
   gpr_ltoa(expiration.tv_sec, expiration_str);
 
-  child = create_child(NULL, json, "iss", json_key->client_email,
-                       GRPC_JSON_STRING);
+  child =
+      create_child(NULL, json, "iss", json_key->client_email, GRPC_JSON_STRING);
   if (scope != NULL) {
     child = create_child(child, json, "scope", scope, GRPC_JSON_STRING);
   } else {
@@ -403,4 +403,3 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token) {
     refresh_token->refresh_token = NULL;
   }
 }
-
diff --git a/src/core/security/jwt_verifier.c b/src/core/security/jwt_verifier.c
index 01007a1a84dee559c91eb3037ede287f26b0d65a..9140eb2ef7920c168fb165c2cc902e0e4e49b943 100644
--- a/src/core/security/jwt_verifier.c
+++ b/src/core/security/jwt_verifier.c
@@ -189,7 +189,6 @@ struct grpc_jwt_claims {
   gpr_slice buffer;
 };
 
-
 void grpc_jwt_claims_destroy(grpc_jwt_claims *claims) {
   grpc_json_destroy(claims->json);
   gpr_slice_unref(claims->buffer);
@@ -286,12 +285,14 @@ grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
 
   GPR_ASSERT(claims != NULL);
 
-  skewed_now = gpr_time_add(gpr_now(), grpc_jwt_verifier_clock_skew);
+  skewed_now =
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew);
   if (gpr_time_cmp(skewed_now, claims->nbf) < 0) {
     gpr_log(GPR_ERROR, "JWT is not valid yet.");
     return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE;
   }
-  skewed_now = gpr_time_sub(gpr_now(), grpc_jwt_verifier_clock_skew);
+  skewed_now =
+      gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew);
   if (gpr_time_cmp(skewed_now, claims->exp) > 0) {
     gpr_log(GPR_ERROR, "JWT is expired.");
     return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE;
@@ -327,10 +328,10 @@ typedef struct {
 
 /* Takes ownership of the header, claims and signature. */
 static verifier_cb_ctx *verifier_cb_ctx_create(
-    grpc_jwt_verifier *verifier, grpc_pollset *pollset,
-    jose_header * header, grpc_jwt_claims *claims, const char *audience,
-    gpr_slice signature, const char *signed_jwt, size_t signed_jwt_len,
-    void *user_data, grpc_jwt_verification_done_cb cb) {
+    grpc_jwt_verifier *verifier, grpc_pollset *pollset, jose_header *header,
+    grpc_jwt_claims *claims, const char *audience, gpr_slice signature,
+    const char *signed_jwt, size_t signed_jwt_len, void *user_data,
+    grpc_jwt_verification_done_cb cb) {
   verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx));
   memset(ctx, 0, sizeof(verifier_cb_ctx));
   ctx->verifier = verifier;
@@ -604,7 +605,7 @@ end:
 
 static void on_openid_config_retrieved(void *user_data,
                                        const grpc_httpcli_response *response) {
-  const grpc_json* cur;
+  const grpc_json *cur;
   grpc_json *json = json_from_http(response);
   verifier_cb_ctx *ctx = (verifier_cb_ctx *)user_data;
   grpc_httpcli_request req;
@@ -632,9 +633,10 @@ static void on_openid_config_retrieved(void *user_data,
   } else {
     *(req.host + (req.path - jwks_uri)) = '\0';
   }
-  grpc_httpcli_get(&ctx->verifier->http_ctx, ctx->pollset, &req,
-                   gpr_time_add(gpr_now(), grpc_jwt_verifier_max_delay),
-                   on_keys_retrieved, ctx);
+  grpc_httpcli_get(
+      &ctx->verifier->http_ctx, ctx->pollset, &req,
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
+      on_keys_retrieved, ctx);
   grpc_json_destroy(json);
   gpr_free(req.host);
   return;
@@ -645,8 +647,8 @@ error:
   verifier_cb_ctx_destroy(ctx);
 }
 
-static email_key_mapping *verifier_get_mapping(
-    grpc_jwt_verifier *v, const char *email_domain) {
+static email_key_mapping *verifier_get_mapping(grpc_jwt_verifier *v,
+                                               const char *email_domain) {
   size_t i;
   if (v->mappings == NULL) return NULL;
   for (i = 0; i < v->num_mappings; i++) {
@@ -733,9 +735,10 @@ static void retrieve_key_and_verify(verifier_cb_ctx *ctx) {
     http_cb = on_openid_config_retrieved;
   }
 
-  grpc_httpcli_get(&ctx->verifier->http_ctx, ctx->pollset, &req,
-                   gpr_time_add(gpr_now(), grpc_jwt_verifier_max_delay),
-                   http_cb, ctx);
+  grpc_httpcli_get(
+      &ctx->verifier->http_ctx, ctx->pollset, &req,
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
+      http_cb, ctx);
   gpr_free(req.host);
   gpr_free(req.path);
   return;
@@ -764,7 +767,7 @@ void grpc_jwt_verifier_verify(grpc_jwt_verifier *verifier,
   dot = strchr(cur, '.');
   if (dot == NULL) goto error;
   json = parse_json_part_from_jwt(cur, dot - cur, &header_buffer);
-  if (json == NULL)  goto error;
+  if (json == NULL) goto error;
   header = jose_header_from_json(json, header_buffer);
   if (header == NULL) goto error;
 
@@ -772,7 +775,7 @@ void grpc_jwt_verifier_verify(grpc_jwt_verifier *verifier,
   dot = strchr(cur, '.');
   if (dot == NULL) goto error;
   json = parse_json_part_from_jwt(cur, dot - cur, &claims_buffer);
-  if (json == NULL)  goto error;
+  if (json == NULL) goto error;
   claims = grpc_jwt_claims_from_json(json, claims_buffer);
   if (claims == NULL) goto error;
 
@@ -827,4 +830,3 @@ void grpc_jwt_verifier_destroy(grpc_jwt_verifier *v) {
   }
   gpr_free(v);
 }
-
diff --git a/src/core/statistics/census_rpc_stats.c b/src/core/statistics/census_rpc_stats.c
index 0491c91947968d1c5c18ed748c11a766994c90f4..3e571b1143ed542b57244448a6ffabc4c85b83a2 100644
--- a/src/core/statistics/census_rpc_stats.c
+++ b/src/core/statistics/census_rpc_stats.c
@@ -157,7 +157,7 @@ static void record_stats(census_ht* store, census_op_id op_id,
         key.ptr = gpr_strdup(key.ptr);
         census_ht_insert(store, key, (void*)window_stats);
       }
-      census_window_stats_add(window_stats, gpr_now(), stats);
+      census_window_stats_add(window_stats, gpr_now(GPR_CLOCK_REALTIME), stats);
     } else {
       census_internal_unlock_trace_store();
     }
@@ -185,7 +185,7 @@ static void get_stats(census_ht* store, census_aggregated_rpc_stats* data) {
   if (store != NULL) {
     size_t n;
     unsigned i, j;
-    gpr_timespec now = gpr_now();
+    gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
     census_ht_kv* kv = census_ht_get_all_elements(store, &n);
     if (kv != NULL) {
       data->num_entries = n;
diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c
index 05e72b99c0bc492dc62db1b8a13ebe7668ccd482..3036ba5407f570b7108ce9d77b2ffc215b11743c 100644
--- a/src/core/statistics/census_tracing.c
+++ b/src/core/statistics/census_tracing.c
@@ -94,7 +94,7 @@ census_op_id census_tracing_start_op(void) {
     g_id++;
     memcpy(&ret->id, &g_id, sizeof(census_op_id));
     ret->rpc_stats.cnt = 1;
-    ret->ts = gpr_now();
+    ret->ts = gpr_now(GPR_CLOCK_REALTIME);
     census_ht_insert(g_trace_store, op_id_as_key(&ret->id), (void*)ret);
     gpr_log(GPR_DEBUG, "Start tracing for id %lu", g_id);
     gpr_mu_unlock(&g_mu);
@@ -122,7 +122,7 @@ void census_tracing_print(census_op_id op_id, const char* anno_txt) {
   trace = census_ht_find(g_trace_store, op_id_as_key(&op_id));
   if (trace != NULL) {
     census_trace_annotation* anno = gpr_malloc(sizeof(census_trace_annotation));
-    anno->ts = gpr_now();
+    anno->ts = gpr_now(GPR_CLOCK_REALTIME);
     {
       char* d = anno->txt;
       const char* s = anno_txt;
@@ -143,8 +143,8 @@ void census_tracing_end_op(census_op_id op_id) {
   gpr_mu_lock(&g_mu);
   trace = census_ht_find(g_trace_store, op_id_as_key(&op_id));
   if (trace != NULL) {
-    trace->rpc_stats.elapsed_time_ms =
-        gpr_timespec_to_micros(gpr_time_sub(gpr_now(), trace->ts));
+    trace->rpc_stats.elapsed_time_ms = gpr_timespec_to_micros(
+        gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), trace->ts));
     gpr_log(GPR_DEBUG, "End tracing for id %lu, method %s, latency %f us",
             op_id_2_uint64(&op_id), trace->method,
             trace->rpc_stats.elapsed_time_ms);
@@ -194,8 +194,8 @@ const char* census_get_trace_method_name(const census_trace_obj* trace) {
 
 static census_trace_annotation* dup_annotation_chain(
     census_trace_annotation* from) {
-  census_trace_annotation *ret = NULL;
-  census_trace_annotation **to = &ret;
+  census_trace_annotation* ret = NULL;
+  census_trace_annotation** to = &ret;
   for (; from != NULL; from = from->next) {
     *to = gpr_malloc(sizeof(census_trace_annotation));
     memcpy(*to, from, sizeof(census_trace_annotation));
@@ -223,9 +223,9 @@ census_trace_obj** census_get_active_ops(int* num_active_ops) {
     size_t n = 0;
     census_ht_kv* all_kvs = census_ht_get_all_elements(g_trace_store, &n);
     *num_active_ops = (int)n;
-    if (n != 0 ) {
+    if (n != 0) {
       size_t i = 0;
-      ret = gpr_malloc(sizeof(census_trace_obj *) * n);
+      ret = gpr_malloc(sizeof(census_trace_obj*) * n);
       for (i = 0; i < n; i++) {
         ret[i] = trace_obj_dup((census_trace_obj*)all_kvs[i].v);
       }
diff --git a/src/core/statistics/window_stats.h b/src/core/statistics/window_stats.h
index d733d8d247a210084ef8f733788414bd30d31c14..0020f6b44caf7f606633a719c3233197cd6bfab1 100644
--- a/src/core/statistics/window_stats.h
+++ b/src/core/statistics/window_stats.h
@@ -90,11 +90,11 @@
     // Record a new event, taking 15.3ms, transferring 1784 bytes.
     stat.latency = 0.153;
     stat.bytes = 1784;
-    census_window_stats_add(stats, gpr_now(), &stat);
+    census_window_stats_add(stats, gpr_now(GPR_CLOCK_REALTIME), &stat);
     // Get sums and print them out
     result[kMinInterval].statistic = &sums[kMinInterval];
     result[kHourInterval].statistic = &sums[kHourInterval];
-    census_window_stats_get_sums(stats, gpr_now(), result);
+    census_window_stats_get_sums(stats, gpr_now(GPR_CLOCK_REALTIME), result);
     printf("%d events/min, average time %gs, average bytes %g\n",
            result[kMinInterval].count,
            (my_stat*)result[kMinInterval].statistic->latency /
@@ -170,4 +170,4 @@ void census_window_stats_get_sums(const struct census_window_stats* wstats,
    assertion failure). This function is thread-compatible. */
 void census_window_stats_destroy(struct census_window_stats* wstats);
 
-#endif  /* GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H */
+#endif /* GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H */
diff --git a/src/core/support/cancellable.c b/src/core/support/cancellable.c
index 5a4d488dd3cf1c0c97bab5f17091c95e6d1d78d9..3cbb318ab6c296eba62901775ce339b3969005fe 100644
--- a/src/core/support/cancellable.c
+++ b/src/core/support/cancellable.c
@@ -121,8 +121,8 @@ void gpr_cancellable_cancel(gpr_cancellable *c) {
         } else {
           gpr_event ev;
           gpr_event_init(&ev);
-          gpr_event_wait(&ev,
-                         gpr_time_add(gpr_now(), gpr_time_from_micros(1000)));
+          gpr_event_wait(&ev, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                                           gpr_time_from_micros(1000)));
         }
       }
     } while (failures != 0);
diff --git a/src/core/support/log_linux.c b/src/core/support/log_linux.c
index 7937466b79abcb1fec02bddbea188956f0e2717a..5ac36e7b9507af37c689ca9a5c67707438da744a 100644
--- a/src/core/support/log_linux.c
+++ b/src/core/support/log_linux.c
@@ -76,7 +76,7 @@ void gpr_default_log(gpr_log_func_args *args) {
   char *prefix;
   const char *display_file;
   char time_buffer[64];
-  gpr_timespec now = gpr_now();
+  gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
   struct tm tm;
 
   final_slash = strrchr(args->file, '/');
diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c
index afca792c404b4158478f1a4e2c89382900afca60..940ee20f1513070e95ae6e6c543bc3ed786d8b7c 100644
--- a/src/core/support/log_posix.c
+++ b/src/core/support/log_posix.c
@@ -75,7 +75,7 @@ void gpr_default_log(gpr_log_func_args *args) {
   char *final_slash;
   const char *display_file;
   char time_buffer[64];
-  gpr_timespec now = gpr_now();
+  gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
   struct tm tm;
 
   final_slash = strrchr(args->file, '/');
diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c
index d249be7d2ec111f97d071ce5e743fed37806373a..629781da8a21de001a05565016af974bab62664e 100644
--- a/src/core/support/log_win32.c
+++ b/src/core/support/log_win32.c
@@ -82,7 +82,7 @@ void gpr_log(const char *file, int line, gpr_log_severity severity,
 /* Simple starter implementation */
 void gpr_default_log(gpr_log_func_args *args) {
   char time_buffer[64];
-  gpr_timespec now = gpr_now();
+  gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
   struct tm tm;
 
   if (localtime_s(&tm, &now.tv_sec)) {
diff --git a/src/core/support/sync_win32.c b/src/core/support/sync_win32.c
index 72f39f8d464a3b109838e6fad653392518ea9ae7..29b77fc4c25e113b8ae5ac688b93bcea9af5d9e5 100644
--- a/src/core/support/sync_win32.c
+++ b/src/core/support/sync_win32.c
@@ -86,7 +86,7 @@ int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline) {
   if (gpr_time_cmp(abs_deadline, gpr_inf_future) == 0) {
     SleepConditionVariableCS(cv, &mu->cs, INFINITE);
   } else {
-    gpr_timespec now = gpr_now();
+    gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
     gpr_int64 now_ms = now.tv_sec * 1000 + now.tv_nsec / 1000000;
     gpr_int64 deadline_ms =
         abs_deadline.tv_sec * 1000 + abs_deadline.tv_nsec / 1000000;
diff --git a/src/core/support/time_posix.c b/src/core/support/time_posix.c
index afb58ef2313b7e5e0003a0ac956f972fad012a5a..f9b79587831d5f3e6d4383011fcf999febc491e8 100644
--- a/src/core/support/time_posix.c
+++ b/src/core/support/time_posix.c
@@ -55,22 +55,52 @@ static gpr_timespec gpr_from_timespec(struct timespec ts) {
   return rv;
 }
 
-gpr_timespec gpr_now(void) {
+/** maps gpr_clock_type --> clockid_t for clock_gettime */
+static clockid_t clockid_for_gpr_clock[] = {CLOCK_MONOTONIC, CLOCK_REALTIME};
+
+void gpr_time_init(void) {}
+
+gpr_timespec gpr_now(gpr_clock_type clock) {
   struct timespec now;
-  clock_gettime(CLOCK_REALTIME, &now);
+  clock_gettime(clockid_for_gpr_clock[clock], &now);
   return gpr_from_timespec(now);
 }
 #else
 /* For some reason Apple's OSes haven't implemented clock_gettime. */
 
 #include <sys/time.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+
+static double g_time_scale;
+static uint64_t g_time_start;
+
+void gpr_time_init(void) {
+  mach_timebase_info_data_t tb = {0, 1};
+  mach_timebase_info(&tb);
+  g_time_scale = tb.numer;
+  g_time_scale /= tb.denom;
+  g_time_start = mach_absolute_time();
+}
 
-gpr_timespec gpr_now(void) {
+gpr_timespec gpr_now(gpr_clock_type clock) {
   gpr_timespec now;
   struct timeval now_tv;
-  gettimeofday(&now_tv, NULL);
-  now.tv_sec = now_tv.tv_sec;
-  now.tv_nsec = now_tv.tv_usec * 1000;
+  double now_dbl;
+
+  switch (clock) {
+    case GPR_CLOCK_REALTIME:
+      gettimeofday(&now_tv, NULL);
+      now.tv_sec = now_tv.tv_sec;
+      now.tv_nsec = now_tv.tv_usec * 1000;
+      break;
+    case GPR_CLOCK_MONOTONIC:
+      now_dbl = (mach_absolute_time() - g_time_start) * g_time_scale;
+      now.tv_sec = now_dbl * 1e-9;
+      now.tv_nsec = now_dbl - now.tv_sec * 1e9;
+      break;
+  }
+
   return now;
 }
 #endif
@@ -83,7 +113,7 @@ void gpr_sleep_until(gpr_timespec until) {
   for (;;) {
     /* We could simplify by using clock_nanosleep instead, but it might be
      * slightly less portable. */
-    now = gpr_now();
+    now = gpr_now(GPR_CLOCK_REALTIME);
     if (gpr_time_cmp(until, now) <= 0) {
       return;
     }
diff --git a/src/core/support/time_win32.c b/src/core/support/time_win32.c
index 9db267c01b064d2e7509d70348ae981e055cf57a..fa77c74eeb1fe5ec987a0d56ba6c391a9711a5d3 100644
--- a/src/core/support/time_win32.c
+++ b/src/core/support/time_win32.c
@@ -40,12 +40,34 @@
 #include <grpc/support/time.h>
 #include <sys/timeb.h>
 
-gpr_timespec gpr_now(void) {
+static LARGE_INTEGER g_start_time;
+static double g_time_scale;
+
+void gpr_time_init(void) {
+  LARGE_INTEGER frequency;
+  QueryPerformanceFrequency(&frequency);
+  QueryPerformanceCounter(&g_start_time);
+  g_time_scale = 1.0 / frequency.QuadPart;
+}
+
+gpr_timespec gpr_now(gpr_clock_type clock) {
   gpr_timespec now_tv;
   struct _timeb now_tb;
-  _ftime_s(&now_tb);
-  now_tv.tv_sec = now_tb.time;
-  now_tv.tv_nsec = now_tb.millitm * 1000000;
+  LARGE_INTEGER timestamp;
+  double now_dbl;
+  switch (clock) {
+    case GPR_CLOCK_REALTIME:
+      _ftime_s(&now_tb);
+      now_tv.tv_sec = now_tb.time;
+      now_tv.tv_nsec = now_tb.millitm * 1000000;
+      break;
+    case GPR_CLOCK_MONOTONIC:
+      QueryPerformanceCounter(&timestamp);
+      now_dbl = (timestamp.QuadPart - g_start_time.QuadPart) * g_time_scale;
+      now_tv.tv_sec = (time_t)now_dbl;
+      now_tv.tv_nsec = (int)((now_dbl - (double)now_tv.tv_sec) * 1e9);
+      break;
+  }
   return now_tv;
 }
 
@@ -57,13 +79,14 @@ void gpr_sleep_until(gpr_timespec until) {
   for (;;) {
     /* We could simplify by using clock_nanosleep instead, but it might be
      * slightly less portable. */
-    now = gpr_now();
+    now = gpr_now(GPR_CLOCK_REALTIME);
     if (gpr_time_cmp(until, now) <= 0) {
       return;
     }
 
     delta = gpr_time_sub(until, now);
-    sleep_millis = (DWORD)delta.tv_sec * GPR_MS_PER_SEC + delta.tv_nsec / GPR_NS_PER_MS;
+    sleep_millis =
+        (DWORD)delta.tv_sec * GPR_MS_PER_SEC + delta.tv_nsec / GPR_NS_PER_MS;
     Sleep(sleep_millis);
   }
 }
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index fb3b0b19189a7313bd209ce8cd34eeee65c869e8..8e6047d89cd352d771222dc705399ba632b9fe10 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -1188,7 +1188,8 @@ static void set_deadline_alarm(grpc_call *call, gpr_timespec deadline) {
   }
   GRPC_CALL_INTERNAL_REF(call, "alarm");
   call->have_alarm = 1;
-  grpc_alarm_init(&call->alarm, deadline, call_alarm, call, gpr_now());
+  grpc_alarm_init(&call->alarm, deadline, call_alarm, call,
+                  gpr_now(GPR_CLOCK_REALTIME));
 }
 
 /* we offset status by a small amount when storing it into transport metadata
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
index 030a8b4e6fc020d1edabe89370421cf2a9e6825a..c3f209667f5fdd6ad5d080e958569193ce7299e5 100644
--- a/src/core/surface/completion_queue.c
+++ b/src/core/surface/completion_queue.c
@@ -90,9 +90,8 @@ grpc_completion_queue *grpc_completion_queue_create(void) {
 #ifdef GRPC_CQ_REF_COUNT_DEBUG
 void grpc_cq_internal_ref(grpc_completion_queue *cc, const char *reason,
                           const char *file, int line) {
-  gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p   ref %d -> %d %s",
-          cc, (int)cc->owning_refs.count, (int)cc->owning_refs.count + 1,
-          reason);
+  gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p   ref %d -> %d %s", cc,
+          (int)cc->owning_refs.count, (int)cc->owning_refs.count + 1, reason);
 #else
 void grpc_cq_internal_ref(grpc_completion_queue *cc) {
 #endif
@@ -107,9 +106,8 @@ static void on_pollset_destroy_done(void *arg) {
 #ifdef GRPC_CQ_REF_COUNT_DEBUG
 void grpc_cq_internal_unref(grpc_completion_queue *cc, const char *reason,
                             const char *file, int line) {
-  gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p unref %d -> %d %s",
-          cc, (int)cc->owning_refs.count, (int)cc->owning_refs.count - 1,
-          reason);
+  gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p unref %d -> %d %s", cc,
+          (int)cc->owning_refs.count, (int)cc->owning_refs.count - 1, reason);
 #else
 void grpc_cq_internal_unref(grpc_completion_queue *cc) {
 #endif
@@ -324,8 +322,8 @@ grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
 void grpc_cq_hack_spin_pollset(grpc_completion_queue *cc) {
   gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
   grpc_pollset_kick(&cc->pollset);
-  grpc_pollset_work(&cc->pollset,
-                    gpr_time_add(gpr_now(), gpr_time_from_millis(100)));
+  grpc_pollset_work(&cc->pollset, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                                               gpr_time_from_millis(100)));
   gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
 }
 
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
index 3847ded28c8fd5196c747584d9c0807ebb61a9a5..04e27d30ac7f1dfc6e7a49056d7a55788283ec7d 100644
--- a/src/core/surface/init.c
+++ b/src/core/surface/init.c
@@ -35,6 +35,7 @@
 
 #include <grpc/census.h>
 #include <grpc/grpc.h>
+#include <grpc/support/time.h>
 #include "src/core/channel/channel_stack.h"
 #include "src/core/client_config/resolver_registry.h"
 #include "src/core/client_config/resolvers/dns_resolver.h"
@@ -64,6 +65,7 @@ void grpc_init(void) {
 
   gpr_mu_lock(&g_init_mu);
   if (++g_initializations == 1) {
+    gpr_time_init();
     grpc_resolver_registry_init("dns:///");
     grpc_register_resolver_type("dns", grpc_dns_resolver_factory_create());
 #ifdef GPR_POSIX_SOCKET
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index adc7ef8efe98dbe073b7c9a465234b3f975f0321..4f868c52b66cb7475ec10f1ebb65088212c25fd0 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -503,9 +503,9 @@ static void maybe_finish_shutdown(grpc_server *server) {
   if (server->root_channel_data.next != &server->root_channel_data ||
       server->listeners_destroyed < num_listeners(server)) {
     if (gpr_time_cmp(
-            gpr_time_sub(gpr_now(), server->last_shutdown_message_time),
+            gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), server->last_shutdown_message_time),
             gpr_time_from_seconds(1)) >= 0) {
-      server->last_shutdown_message_time = gpr_now();
+      server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
       gpr_log(GPR_DEBUG,
               "Waiting for %d channels and %d/%d listeners to be destroyed"
               " before shutting down server",
@@ -962,7 +962,7 @@ void grpc_server_shutdown_and_notify(grpc_server *server,
     return;
   }
 
-  server->last_shutdown_message_time = gpr_now();
+  server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
 
   channel_broadcaster_init(server, &broadcaster);
 
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index 130167f8302a631acd1305d8c862099badd17f56..9597395aab8a0cfaf6c2874da5a946bcd13b5f1a 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -205,7 +205,8 @@ void grpc_chttp2_publish_reads(
     }
     if (stream_parsing->saw_rst_stream) {
       stream_global->cancelled = 1;
-      stream_global->cancelled_status = grpc_chttp2_http2_error_to_grpc_status(stream_parsing->rst_stream_reason);
+      stream_global->cancelled_status = grpc_chttp2_http2_error_to_grpc_status(
+          stream_parsing->rst_stream_reason);
       if (stream_parsing->rst_stream_reason == GRPC_CHTTP2_NO_ERROR) {
         stream_global->published_cancelled = 1;
       }
@@ -599,7 +600,7 @@ static void on_header(void *tp, grpc_mdelem *md) {
     }
     grpc_chttp2_incoming_metadata_buffer_set_deadline(
         &stream_parsing->incoming_metadata,
-        gpr_time_add(gpr_now(), *cached_timeout));
+        gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), *cached_timeout));
     GRPC_MDELEM_UNREF(md);
   } else {
     grpc_chttp2_incoming_metadata_buffer_add(&stream_parsing->incoming_metadata,
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index 56ab82006ac72a21310a450d71ac76d7e6f05a1a..d553d80085ef5bc2ffc6c4aa7bc323567dc27301 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -437,7 +437,8 @@ static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
                          framer_state *st) {
   char timeout_str[GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE];
   grpc_mdelem *mdelem;
-  grpc_chttp2_encode_timeout(gpr_time_sub(deadline, gpr_now()), timeout_str);
+  grpc_chttp2_encode_timeout(
+      gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME)), timeout_str);
   mdelem = grpc_mdelem_from_metadata_strings(
       c->mdctx, GRPC_MDSTR_REF(c->timeout_key_str),
       grpc_mdstr_from_string(c->mdctx, timeout_str));
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index 9cbb0952d0386469391f784d5f59ea97ddd061d5..acd00986f3b7f2716a8e10f5697da122035c81c1 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -183,7 +183,7 @@ grpc_mdctx *grpc_mdctx_create(void) {
   /* This seed is used to prevent remote connections from controlling hash table
    * collisions. It needs to be somewhat unpredictable to a remote connection.
    */
-  return grpc_mdctx_create_with_seed(gpr_now().tv_nsec);
+  return grpc_mdctx_create_with_seed(gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
 }
 
 static void discard_metadata(grpc_mdctx *ctx) {
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index ec125db78bfb6ecd6ea1014dfbb06e33906913c9..a55cc9e247f8cb55c1520e4aaec47c6f71872744 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -379,7 +379,7 @@ grpcsharp_channel_args_destroy(grpc_channel_args *args) {
 
 /* Timespec */
 
-GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(void) { return gpr_now(); }
+GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(void) { return gpr_now(GPR_CLOCK_REALTIME); }
 
 GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_future(void) {
   return gpr_inf_future;
diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c
index 8a278d676070653dcdb476d162d07dd380f46ce3..ccf7f0f81af5db163931c7ab50e19ca6cfe61606 100644
--- a/src/php/ext/grpc/timeval.c
+++ b/src/php/ext/grpc/timeval.c
@@ -208,7 +208,7 @@ PHP_METHOD(Timeval, similar) {
  * @return Timeval The current time
  */
 PHP_METHOD(Timeval, now) {
-  zval *now = grpc_php_wrap_timeval(gpr_now());
+  zval *now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME));
   RETURN_DESTROY_ZVAL(now);
 }
 
diff --git a/src/ruby/ext/grpc/rb_completion_queue.c b/src/ruby/ext/grpc/rb_completion_queue.c
index 8fb3949b3dc7cf8a2eff4770e92e9480463d1a7b..2d52d96dc8566105afa0aa1e053f6993f3918456 100644
--- a/src/ruby/ext/grpc/rb_completion_queue.c
+++ b/src/ruby/ext/grpc/rb_completion_queue.c
@@ -91,7 +91,7 @@ static void grpc_rb_completion_queue_shutdown_drain(grpc_completion_queue *cq) {
    * - investigate further, this is probably another example of C-level cleanup
    * not working consistently in all cases.
    */
-  next_call.timeout = gpr_time_add(gpr_now(), gpr_time_from_micros(5e3));
+  next_call.timeout = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(5e3));
   do {
     rb_thread_call_without_gvl(grpc_rb_completion_queue_next_no_gil,
                                (void *)&next_call, NULL, NULL);
diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c
index 33f7c02b612c6e6fbc603ec5f66e9c4b48ddf8df..407c72b519f5f26ebf9ce916bef63823d42e3569 100644
--- a/test/core/end2end/cq_verifier.c
+++ b/test/core/end2end/cq_verifier.c
@@ -248,7 +248,8 @@ void cq_verify(cq_verifier *v) {
 }
 
 void cq_verify_empty(cq_verifier *v) {
-  gpr_timespec deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(1));
+  gpr_timespec deadline =
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(1));
   grpc_event ev;
 
   GPR_ASSERT(v->expect.next == &v->expect && "expectation queue must be empty");
diff --git a/test/core/fling/client.c b/test/core/fling/client.c
index ee5e390c396bb9eb90db4dfda1c886d4f67e426e..6741a9dec849ca07fdcec0bf940af3fd53f7e6ea 100644
--- a/test/core/fling/client.c
+++ b/test/core/fling/client.c
@@ -124,7 +124,7 @@ static void step_ping_pong_stream(void) {
 }
 
 static double now(void) {
-  gpr_timespec tv = gpr_now();
+  gpr_timespec tv = gpr_now(GPR_CLOCK_REALTIME);
   return 1e9 * tv.tv_sec + tv.tv_nsec;
 }
 
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index 9542e15ad06d1c38234229be5b8637be977706c8..468013c3ecc3f680cb7d123456dd486f87bbb65b 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -241,7 +241,8 @@ int main(int argc, char **argv) {
       shutdown_started = 1;
     }
     ev = grpc_completion_queue_next(
-        cq, gpr_time_add(gpr_now(), gpr_time_from_micros(1000000)));
+        cq, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                         gpr_time_from_micros(1000000)));
     s = ev.tag;
     switch (ev.type) {
       case GRPC_OP_COMPLETE:
diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c
index 6e579bc04509e3ad5e856e45ec96cffa144e56fb..ca0b2d1519a603825477c89189b33368594abaa3 100644
--- a/test/core/httpcli/httpcli_test.c
+++ b/test/core/httpcli/httpcli_test.c
@@ -145,7 +145,8 @@ int main(int argc, char **argv) {
   gpr_free(args[0]);
   gpr_free(args[2]);
 
-  gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5)));
+  gpr_sleep_until(
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(5)));
 
   grpc_test_init(argc, argv);
   grpc_init();
diff --git a/test/core/iomgr/alarm_list_test.c b/test/core/iomgr/alarm_list_test.c
index 684e3f579a45b70debd0742f1a2da6884f8192c5..225c449d4b0d8d143e90970f8674bbc5dbe0cfbb 100644
--- a/test/core/iomgr/alarm_list_test.c
+++ b/test/core/iomgr/alarm_list_test.c
@@ -51,7 +51,7 @@ static void cb(void *arg, int success) {
 }
 
 static void add_test(void) {
-  gpr_timespec start = gpr_now();
+  gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
   int i;
   grpc_alarm alarms[20];
 
@@ -61,13 +61,13 @@ static void add_test(void) {
   /* 10 ms alarms.  will expire in the current epoch */
   for (i = 0; i < 10; i++) {
     grpc_alarm_init(&alarms[i], gpr_time_add(start, gpr_time_from_millis(10)),
-                    cb, (void *)(gpr_intptr) i, start);
+                    cb, (void *)(gpr_intptr)i, start);
   }
 
   /* 1010 ms alarms.  will expire in the next epoch */
   for (i = 10; i < 20; i++) {
     grpc_alarm_init(&alarms[i], gpr_time_add(start, gpr_time_from_millis(1010)),
-                    cb, (void *)(gpr_intptr) i, start);
+                    cb, (void *)(gpr_intptr)i, start);
   }
 
   /* collect alarms.  Only the first batch should be ready. */
@@ -115,15 +115,15 @@ void destruction_test(void) {
   memset(cb_called, 0, sizeof(cb_called));
 
   grpc_alarm_init(&alarms[0], gpr_time_from_millis(100), cb,
-                  (void *)(gpr_intptr) 0, gpr_time_0);
+                  (void *)(gpr_intptr)0, gpr_time_0);
   grpc_alarm_init(&alarms[1], gpr_time_from_millis(3), cb,
-                  (void *)(gpr_intptr) 1, gpr_time_0);
+                  (void *)(gpr_intptr)1, gpr_time_0);
   grpc_alarm_init(&alarms[2], gpr_time_from_millis(100), cb,
-                  (void *)(gpr_intptr) 2, gpr_time_0);
+                  (void *)(gpr_intptr)2, gpr_time_0);
   grpc_alarm_init(&alarms[3], gpr_time_from_millis(3), cb,
-                  (void *)(gpr_intptr) 3, gpr_time_0);
+                  (void *)(gpr_intptr)3, gpr_time_0);
   grpc_alarm_init(&alarms[4], gpr_time_from_millis(1), cb,
-                  (void *)(gpr_intptr) 4, gpr_time_0);
+                  (void *)(gpr_intptr)4, gpr_time_0);
   GPR_ASSERT(1 == grpc_alarm_check(NULL, gpr_time_from_millis(2), NULL));
   GPR_ASSERT(1 == cb_called[4][1]);
   grpc_alarm_cancel(&alarms[0]);
diff --git a/test/core/iomgr/alarm_test.c b/test/core/iomgr/alarm_test.c
index 0ccec435e610f4086662ac8ea7e8bd4d77eb8316..362eb5fe6340e289d45833cc9c6c212ab343b385 100644
--- a/test/core/iomgr/alarm_test.c
+++ b/test/core/iomgr/alarm_test.c
@@ -113,7 +113,7 @@ static void test_grpc_alarm(void) {
   gpr_event_init(&arg.fcb_arg);
 
   grpc_alarm_init(&alarm, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100), alarm_cb, &arg,
-                  gpr_now());
+                  gpr_now(GPR_CLOCK_REALTIME));
 
   alarm_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
   gpr_mu_lock(&arg.mu);
@@ -165,7 +165,7 @@ static void test_grpc_alarm(void) {
   gpr_event_init(&arg2.fcb_arg);
 
   grpc_alarm_init(&alarm_to_cancel, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100),
-                  alarm_cb, &arg2, gpr_now());
+                  alarm_cb, &arg2, gpr_now(GPR_CLOCK_REALTIME));
   grpc_alarm_cancel(&alarm_to_cancel);
 
   alarm_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 8198c247525968b01f966586a945a656627a3180..0cfba5fac81b91007b1e0d6b91ffebce895e06c6 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -254,7 +254,7 @@ static void read_and_write_test(grpc_endpoint_test_config config,
 
   gpr_mu_lock(GRPC_POLLSET_MU(g_pollset));
   while (!state.read_done || !state.write_done) {
-    GPR_ASSERT(gpr_time_cmp(gpr_now(), deadline) < 0);
+    GPR_ASSERT(gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0);
     grpc_pollset_work(g_pollset, deadline);
   }
   gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset));
@@ -350,14 +350,14 @@ static void shutdown_during_write_test(grpc_endpoint_test_config config,
         deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
         gpr_mu_lock(GRPC_POLLSET_MU(g_pollset));
         while (!write_st.done) {
-          GPR_ASSERT(gpr_time_cmp(gpr_now(), deadline) < 0);
+          GPR_ASSERT(gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0);
           grpc_pollset_work(g_pollset, deadline);
         }
         gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset));
         grpc_endpoint_destroy(write_st.ep);
         gpr_mu_lock(GRPC_POLLSET_MU(g_pollset));
         while (!read_st.done) {
-          GPR_ASSERT(gpr_time_cmp(gpr_now(), deadline) < 0);
+          GPR_ASSERT(gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0);
           grpc_pollset_work(g_pollset, deadline);
         }
         gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset));
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index b673c032b27d8e7b79aa4f434046d6c305ff5e75..710cd725df4ce0f834604755853fb72298c247b7 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -187,11 +187,12 @@ void test_times_out(void) {
   /* Make sure the event doesn't trigger early */
   gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
   while (gpr_time_cmp(gpr_time_add(connect_deadline, gpr_time_from_seconds(2)),
-                      gpr_now()) > 0) {
-    int is_after_deadline = gpr_time_cmp(connect_deadline, gpr_now()) <= 0;
+                      gpr_now(GPR_CLOCK_REALTIME)) > 0) {
+    int is_after_deadline =
+        gpr_time_cmp(connect_deadline, gpr_now(GPR_CLOCK_REALTIME)) <= 0;
     if (is_after_deadline &&
         gpr_time_cmp(gpr_time_add(connect_deadline, gpr_time_from_seconds(1)),
-                     gpr_now()) > 0) {
+                     gpr_now(GPR_CLOCK_REALTIME)) > 0) {
       /* allow some slack before insisting that things be done */
     } else {
       GPR_ASSERT(g_connections_complete ==
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index fb262711c0cbd7a0332bad787efc0e4f839248a0..110a2eb1d90a83bf84e5948d620def9a0439dc59 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -135,7 +135,7 @@ static void test_connect(int n) {
 
     gpr_log(GPR_DEBUG, "wait");
     while (g_nconnects == nconnects_before &&
-           gpr_time_cmp(deadline, gpr_now()) > 0) {
+           gpr_time_cmp(deadline, gpr_now(GPR_CLOCK_REALTIME)) > 0) {
       grpc_pollset_work(&g_pollset, deadline);
     }
     gpr_log(GPR_DEBUG, "wait done");
diff --git a/test/core/network_benchmarks/low_level_ping_pong.c b/test/core/network_benchmarks/low_level_ping_pong.c
index 78a0eef1a2eec5829456f0fb63abaf07d7fc8563..0ce4bd4b25013f4217f5550d7ae6774e6522f50b 100644
--- a/test/core/network_benchmarks/low_level_ping_pong.c
+++ b/test/core/network_benchmarks/low_level_ping_pong.c
@@ -296,7 +296,7 @@ static void print_histogram(gpr_histogram *histogram) {
 }
 
 static double now(void) {
-  gpr_timespec tv = gpr_now();
+  gpr_timespec tv = gpr_now(GPR_CLOCK_REALTIME);
   return 1e9 * tv.tv_sec + tv.tv_nsec;
 }
 
diff --git a/test/core/statistics/census_log_tests.c b/test/core/statistics/census_log_tests.c
index 241ec1ce4f43477d0287e41e2d36b930549e52ca..a34dcf07c4d971e6bcb0e4bb3181abb22aee5cfd 100644
--- a/test/core/statistics/census_log_tests.c
+++ b/test/core/statistics/census_log_tests.c
@@ -568,7 +568,7 @@ void test_performance(void) {
     double write_time_micro = 0.0;
     int nrecords = 0;
     setup_test(0);
-    start_time = gpr_now();
+    start_time = gpr_now(GPR_CLOCK_REALTIME);
     while (1) {
       void* record = census_log_start_write(write_size);
       if (record == NULL) {
@@ -577,7 +577,7 @@ void test_performance(void) {
       census_log_end_write(record, write_size);
       nrecords++;
     }
-    write_time = gpr_time_sub(gpr_now(), start_time);
+    write_time = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start_time);
     write_time_micro = write_time.tv_sec * 1000000 + write_time.tv_nsec / 1000;
     census_log_shutdown();
     printf(
diff --git a/test/core/statistics/multiple_writers_circular_buffer_test.c b/test/core/statistics/multiple_writers_circular_buffer_test.c
index a645e15918a93276d6034b816f95d3bc092e6346..56ada893efd39ed43e6f57ce990c56f8daab4ef8 100644
--- a/test/core/statistics/multiple_writers_circular_buffer_test.c
+++ b/test/core/statistics/multiple_writers_circular_buffer_test.c
@@ -40,7 +40,7 @@
 
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
-  srand(gpr_now().tv_nsec);
+  srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
   test_multiple_writers_circular_log();
   return 0;
 }
diff --git a/test/core/statistics/multiple_writers_test.c b/test/core/statistics/multiple_writers_test.c
index 84aef15c1a9c4d0e09482b9b4fdbe79e332a8d25..e524927da62e688f8af417875a99711fb0c6dd39 100644
--- a/test/core/statistics/multiple_writers_test.c
+++ b/test/core/statistics/multiple_writers_test.c
@@ -40,7 +40,7 @@
 
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
-  srand(gpr_now().tv_nsec);
+  srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
   test_multiple_writers();
   return 0;
 }
diff --git a/test/core/statistics/performance_test.c b/test/core/statistics/performance_test.c
index 3c1e28241ec7867699a5f96862907a78d1992a5a..3f0e0800933b5de00d2692860c07696f4e973d60 100644
--- a/test/core/statistics/performance_test.c
+++ b/test/core/statistics/performance_test.c
@@ -40,7 +40,7 @@
 
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
-  srand(gpr_now().tv_nsec);
+  srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
   test_performance();
   return 0;
 }
diff --git a/test/core/statistics/quick_test.c b/test/core/statistics/quick_test.c
index 0e432314bbad5a2644adb3c43c83f90fda0df446..c72ae77b98e37743be0d14df1a220a97ca81bf99 100644
--- a/test/core/statistics/quick_test.c
+++ b/test/core/statistics/quick_test.c
@@ -40,7 +40,7 @@
 
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
-  srand(gpr_now().tv_nsec);
+  srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
   test_invalid_record_size();
   test_end_write_with_different_size();
   test_read_pending_record();
diff --git a/test/core/statistics/small_log_test.c b/test/core/statistics/small_log_test.c
index c151b77f6391585b4c433913d569cda7147bda2f..b26b95f639c2fe88cd6689c1b3e6513ca7ff69a3 100644
--- a/test/core/statistics/small_log_test.c
+++ b/test/core/statistics/small_log_test.c
@@ -40,7 +40,7 @@
 
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
-  srand(gpr_now().tv_nsec);
+  srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
   test_small_log();
   return 0;
 }
diff --git a/test/core/statistics/window_stats_test.c b/test/core/statistics/window_stats_test.c
index d893f7f792b7fe005b56e717ebd5dacdeabf5db9..1c66a874070d74aa4b2774e46372b19cd58d9766 100644
--- a/test/core/statistics/window_stats_test.c
+++ b/test/core/statistics/window_stats_test.c
@@ -83,7 +83,7 @@ void empty_test(void) {
   result.statistic = &sum;
   census_window_stats_get_sums(stats, zero, &result);
   GPR_ASSERT(result.count == 0 && sum.value1 == 0 && sum.value2 == 0);
-  census_window_stats_get_sums(stats, gpr_now(), &result);
+  census_window_stats_get_sums(stats, gpr_now(GPR_CLOCK_REALTIME), &result);
   GPR_ASSERT(result.count == 0 && sum.value1 == 0 && sum.value2 == 0);
   census_window_stats_destroy(stats);
 }
@@ -268,7 +268,7 @@ void rolling_time_test(void) {
   struct census_window_stats* stats =
       census_window_stats_create(1, &kMinInterval, 7, &kMyStatInfo);
   GPR_ASSERT(stats != NULL);
-  srand(gpr_now().tv_nsec);
+  srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
   for (i = 0; i < 100000; i++) {
     increment.tv_nsec = rand() % 100000000; /* up to 1/10th second */
     when = gpr_time_add(when, increment);
@@ -292,7 +292,7 @@ void infinite_interval_test(void) {
   gpr_timespec increment = {0, 0};
   struct census_window_stats* stats =
       census_window_stats_create(1, &gpr_inf_future, 10, &kMyStatInfo);
-  srand(gpr_now().tv_nsec);
+  srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
   for (i = 0; i < count; i++) {
     increment.tv_sec = rand() % 21600; /* 6 hours */
     when = gpr_time_add(when, increment);
diff --git a/test/core/support/cancellable_test.c b/test/core/support/cancellable_test.c
index b2db1afc7619ef87dc27d4b00b6d0e41ca3cb9c9..2f4b67a7857c931cb773275713326a0787b0eb28 100644
--- a/test/core/support/cancellable_test.c
+++ b/test/core/support/cancellable_test.c
@@ -81,22 +81,23 @@ static void test(void) {
   GPR_ASSERT(!gpr_cancellable_is_cancelled(&t.cancel));
 
   /* Test timeout on event wait for uncancelled gpr_cancellable */
-  interval = gpr_now();
-  gpr_event_cancellable_wait(
-      &t.ev, gpr_time_add(gpr_now(), gpr_time_from_micros(1000000)), &t.cancel);
-  interval = gpr_time_sub(gpr_now(), interval);
+  interval = gpr_now(GPR_CLOCK_REALTIME);
+  gpr_event_cancellable_wait(&t.ev, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                                                 gpr_time_from_micros(1000000)),
+                             &t.cancel);
+  interval = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), interval);
   GPR_ASSERT(gpr_time_cmp(interval, gpr_time_from_micros(500000)) >= 0);
   GPR_ASSERT(gpr_time_cmp(gpr_time_from_micros(2000000), interval) >= 0);
 
   /* Test timeout on cv wait for uncancelled gpr_cancellable */
   gpr_mu_lock(&t.mu);
-  interval = gpr_now();
+  interval = gpr_now(GPR_CLOCK_REALTIME);
   while (!gpr_cv_cancellable_wait(
-             &t.cv, &t.mu,
-             gpr_time_add(gpr_now(), gpr_time_from_micros(1000000)),
-             &t.cancel)) {
+      &t.cv, &t.mu,
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(1000000)),
+      &t.cancel)) {
   }
-  interval = gpr_time_sub(gpr_now(), interval);
+  interval = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), interval);
   GPR_ASSERT(gpr_time_cmp(interval, gpr_time_from_micros(500000)) >= 0);
   GPR_ASSERT(gpr_time_cmp(gpr_time_from_micros(2000000), interval) >= 0);
   gpr_mu_unlock(&t.mu);
@@ -112,8 +113,8 @@ static void test(void) {
 
   /* Wait a second, and check that no threads have finished waiting. */
   gpr_mu_lock(&t.mu);
-  gpr_cv_wait(&t.cv, &t.mu,
-              gpr_time_add(gpr_now(), gpr_time_from_micros(1000000)));
+  gpr_cv_wait(&t.cv, &t.mu, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                                         gpr_time_from_micros(1000000)));
   GPR_ASSERT(t.n == n);
   gpr_mu_unlock(&t.mu);
 
@@ -129,21 +130,22 @@ static void test(void) {
 
   /* Test timeout on cv wait for cancelled gpr_cancellable */
   gpr_mu_lock(&t.mu);
-  interval = gpr_now();
+  interval = gpr_now(GPR_CLOCK_REALTIME);
   while (!gpr_cv_cancellable_wait(
-             &t.cv, &t.mu,
-             gpr_time_add(gpr_now(), gpr_time_from_micros(1000000)),
-             &t.cancel)) {
+      &t.cv, &t.mu,
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(1000000)),
+      &t.cancel)) {
   }
-  interval = gpr_time_sub(gpr_now(), interval);
+  interval = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), interval);
   GPR_ASSERT(gpr_time_cmp(gpr_time_from_micros(100000), interval) >= 0);
   gpr_mu_unlock(&t.mu);
 
   /* Test timeout on event wait for cancelled gpr_cancellable */
-  interval = gpr_now();
-  gpr_event_cancellable_wait(
-      &t.ev, gpr_time_add(gpr_now(), gpr_time_from_micros(1000000)), &t.cancel);
-  interval = gpr_time_sub(gpr_now(), interval);
+  interval = gpr_now(GPR_CLOCK_REALTIME);
+  gpr_event_cancellable_wait(&t.ev, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                                                 gpr_time_from_micros(1000000)),
+                             &t.cancel);
+  interval = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), interval);
   GPR_ASSERT(gpr_time_cmp(gpr_time_from_micros(100000), interval) >= 0);
 
   gpr_mu_destroy(&t.mu);
diff --git a/test/core/support/sync_test.c b/test/core/support/sync_test.c
index 44bc6ba47114f9c689aa8858104d665b1f462524..99be5cdc9058230a604f04d84b05bd79b552070f 100644
--- a/test/core/support/sync_test.c
+++ b/test/core/support/sync_test.c
@@ -242,12 +242,12 @@ static void test(const char *name, void (*body)(void *m),
                  void (*extra)(void *m), int timeout_s) {
   gpr_int64 iterations = 1024;
   struct test *m;
-  gpr_timespec start = gpr_now();
+  gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
   gpr_timespec time_taken;
   gpr_timespec deadline =
       gpr_time_add(start, gpr_time_from_micros(timeout_s * 1000000));
   fprintf(stderr, "%s:", name);
-  while (gpr_time_cmp(gpr_now(), deadline) < 0) {
+  while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) {
     iterations <<= 1;
     fprintf(stderr, " %ld", (long)iterations);
     m = test_new(10, iterations);
@@ -265,7 +265,7 @@ static void test(const char *name, void (*body)(void *m),
     }
     test_destroy(m);
   }
-  time_taken = gpr_time_sub(gpr_now(), start);
+  time_taken = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start);
   fprintf(stderr, " done %ld.%09d s\n", (long)time_taken.tv_sec,
           (int)time_taken.tv_nsec);
 }
@@ -323,7 +323,8 @@ static void inc_with_1ms_delay(void *v /*=m*/) {
   for (i = 0; i != m->iterations; i++) {
     gpr_timespec deadline;
     gpr_mu_lock(&m->mu);
-    deadline = gpr_time_add(gpr_now(), gpr_time_from_micros(1000));
+    deadline =
+        gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(1000));
     while (!gpr_cv_wait(&m->cv, &m->mu, deadline)) {
     }
     m->counter++;
@@ -339,7 +340,8 @@ static void inc_with_1ms_delay_event(void *v /*=m*/) {
   gpr_int64 i;
   for (i = 0; i != m->iterations; i++) {
     gpr_timespec deadline;
-    deadline = gpr_time_add(gpr_now(), gpr_time_from_micros(1000));
+    deadline =
+        gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(1000));
     GPR_ASSERT(gpr_event_wait(&m->event, deadline) == NULL);
     gpr_mu_lock(&m->mu);
     m->counter++;
@@ -382,9 +384,9 @@ static void consumer(void *v /*=m*/) {
   gpr_mu_lock(&m->mu);
   m->counter = n;
   gpr_mu_unlock(&m->mu);
-  GPR_ASSERT(
-      !queue_remove(&m->q, &value,
-                    gpr_time_add(gpr_now(), gpr_time_from_micros(1000000))));
+  GPR_ASSERT(!queue_remove(&m->q, &value,
+                           gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                                        gpr_time_from_micros(1000000))));
   mark_thread_done(m);
 }
 
diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c
index eba24f5c6e634cb839e3664837a702f84828e79f..66136cfe5ec7299406ea39f181c90937b0fa8cf0 100644
--- a/test/core/surface/completion_queue_test.c
+++ b/test/core/surface/completion_queue_test.c
@@ -69,7 +69,7 @@ static void test_wait_empty(void) {
   LOG_TEST("test_wait_empty");
 
   cc = grpc_completion_queue_create();
-  GPR_ASSERT(grpc_completion_queue_next(cc, gpr_now()).type ==
+  GPR_ASSERT(grpc_completion_queue_next(cc, gpr_now(GPR_CLOCK_REALTIME)).type ==
              GRPC_QUEUE_TIMEOUT);
   shutdown_and_destroy(cc);
 }
diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h
index 0b3c54373d947f8238a0f56e249c309d05bf3bb3..321895316639e38afb4ff74db6724c3eaeb94837 100644
--- a/test/core/util/test_config.h
+++ b/test/core/util/test_config.h
@@ -52,11 +52,11 @@ extern "C" {
   (GRPC_TEST_SLOWDOWN_BUILD_FACTOR * GRPC_TEST_SLOWDOWN_MACHINE_FACTOR)
 
 #define GRPC_TIMEOUT_SECONDS_TO_DEADLINE(x) \
-  gpr_time_add(gpr_now(),                   \
+  gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), \
                gpr_time_from_micros(GRPC_TEST_SLOWDOWN_FACTOR * 1e6 * (x)))
 
-#define GRPC_TIMEOUT_MILLIS_TO_DEADLINE(x) \
-  gpr_time_add(gpr_now(),                  \
+#define GRPC_TIMEOUT_MILLIS_TO_DEADLINE(x)  \
+  gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), \
                gpr_time_from_micros(GRPC_TEST_SLOWDOWN_FACTOR * 1e3 * (x)))
 
 #ifndef GRPC_TEST_CUSTOM_PICK_PORT
@@ -69,4 +69,4 @@ void grpc_test_init(int argc, char **argv);
 }
 #endif /*  __cplusplus */
 
-#endif  /* GRPC_TEST_CORE_UTIL_TEST_CONFIG_H */
+#endif /* GRPC_TEST_CORE_UTIL_TEST_CONFIG_H */
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 3791d1522042478ba627c29a972886e1fed43614..f0d9f752148d31fd03e113ab24fc7c458e6a6f25 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -115,15 +115,15 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
       }
       while (!context->IsCancelled()) {
         gpr_sleep_until(gpr_time_add(
-            gpr_now(),
+            gpr_now(GPR_CLOCK_REALTIME),
             gpr_time_from_micros(request->param().client_cancel_after_us())));
       }
       return Status::CANCELLED;
     } else if (request->has_param() &&
                request->param().server_cancel_after_us()) {
       gpr_sleep_until(gpr_time_add(
-            gpr_now(),
-            gpr_time_from_micros(request->param().server_cancel_after_us())));
+          gpr_now(GPR_CLOCK_REALTIME),
+          gpr_time_from_micros(request->param().server_cancel_after_us())));
       return Status::CANCELLED;
     } else {
       EXPECT_FALSE(context->IsCancelled());
@@ -527,7 +527,8 @@ TEST_F(End2endTest, BadCredentials) {
 }
 
 void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
-  gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_micros(delay_us)));
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                               gpr_time_from_micros(delay_us)));
   while (!service->signal_client()) {
   }
   context->TryCancel();
diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc
index 3fdae9bc0797fb45bf1bb5da53dc3dc503c9938f..4d4d590bdd701a5d012703e3ff8cd0bd811c8d4b 100644
--- a/test/cpp/end2end/server_crash_test.cc
+++ b/test/cpp/end2end/server_crash_test.cc
@@ -84,7 +84,8 @@ class ServiceImpl GRPC_FINAL
       gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
       response.set_message(request.message());
       stream->Write(response);
-      gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(1)));
+      gpr_sleep_until(
+          gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(1)));
     }
     return Status::OK;
   }
@@ -98,7 +99,8 @@ class ServiceImpl GRPC_FINAL
       msg << "Hello " << i;
       response.set_message(msg.str());
       if (!writer->Write(response)) break;
-      gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(1)));
+      gpr_sleep_until(
+          gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(1)));
     }
     return Status::OK;
   }
@@ -145,7 +147,8 @@ class CrashTest : public ::testing::Test {
 TEST_F(CrashTest, ResponseStream) {
   auto server = CreateServerAndClient("response");
 
-  gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5)));
+  gpr_sleep_until(
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(5)));
   KillClient();
   server->Shutdown();
   GPR_ASSERT(HadOneResponseStream());
@@ -154,7 +157,8 @@ TEST_F(CrashTest, ResponseStream) {
 TEST_F(CrashTest, BidiStream) {
   auto server = CreateServerAndClient("bidi");
 
-  gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5)));
+  gpr_sleep_until(
+      gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(5)));
   KillClient();
   server->Shutdown();
   GPR_ASSERT(HadOneBidiStream());
diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc
index 0b43dfd1062fd605e4973db10f531ecc9a006153..0b4d94256665989cad2d02fd47fae72ad29c0ab8 100644
--- a/test/cpp/end2end/thread_stress_test.cc
+++ b/test/cpp/end2end/thread_stress_test.cc
@@ -96,14 +96,14 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
       }
       while (!context->IsCancelled()) {
         gpr_sleep_until(gpr_time_add(
-            gpr_now(),
+            gpr_now(GPR_CLOCK_REALTIME),
             gpr_time_from_micros(request->param().client_cancel_after_us())));
       }
       return Status::CANCELLED;
     } else if (request->has_param() &&
                request->param().server_cancel_after_us()) {
       gpr_sleep_until(gpr_time_add(
-          gpr_now(),
+          gpr_now(GPR_CLOCK_REALTIME),
           gpr_time_from_micros(request->param().server_cancel_after_us())));
       return Status::CANCELLED;
     } else {
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index c8cc11e6ab3483a4fccf3e579168439c7f64b330..5597bcd5499f846830c7ec71a03db1c1f556d562 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -185,7 +185,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
 
   // Let everything warmup
   gpr_log(GPR_INFO, "Warming up");
-  gpr_timespec start = gpr_now();
+  gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
   gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(warmup_seconds)));
 
   // Start a run
diff --git a/test/cpp/qps/timer.cc b/test/cpp/qps/timer.cc
index d1b6bc1e55a3418114dbda55b9a43035fafa308b..07289f699bf554c40f26af50b2c53a2ab9ac515f 100644
--- a/test/cpp/qps/timer.cc
+++ b/test/cpp/qps/timer.cc
@@ -41,7 +41,7 @@
 Timer::Timer() : start_(Sample()) {}
 
 double Timer::Now() {
-  auto ts = gpr_now();
+  auto ts = gpr_now(GPR_CLOCK_REALTIME);
   return ts.tv_sec + 1e-9 * ts.tv_nsec;
 }
 
diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc
index 14a8b0b0891e201f4bccedc72d5396e32f746a2a..2bc0a5697099cca35eac811bf6a10c3d34b62aa8 100644
--- a/test/cpp/qps/worker.cc
+++ b/test/cpp/qps/worker.cc
@@ -57,7 +57,8 @@ static void RunServer() {
   QpsWorker worker(FLAGS_driver_port, FLAGS_server_port);
 
   while (!got_sigint) {
-    gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5)));
+    gpr_sleep_until(
+        gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(5)));
   }
 }