diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 96e46c29ca7dc1f632b3a136106ca8acd0aa21be..024d9d649f8c8ffc1ebcc5a498c47148369463a5 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -477,6 +477,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 
   t->ping_state.pings_before_data_required =
       t->ping_policy.max_pings_without_data;
+  t->ping_state.is_delayed_ping_timer_set = false;
 
   /** Start client-side keepalive pings */
   if (t->is_client) {
@@ -1395,6 +1396,7 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
 static void retry_initiate_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
                                        grpc_error *error) {
   grpc_chttp2_transport *t = tp;
+  t->ping_state.is_delayed_ping_timer_set = false;
   grpc_chttp2_initiate_write(exec_ctx, t, false, "retry_send_ping");
 }
 
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index a23aa60dbdb85bcec99b785b151f7266a308d692..bfbfd5fd97c8009e9b5c6e21859fb3f01c5b9cb2 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -103,6 +103,7 @@ typedef struct {
   gpr_timespec last_ping_sent_time;
   int pings_before_data_required;
   grpc_timer delayed_ping_timer;
+  bool is_delayed_ping_timer_set;
 } grpc_chttp2_repeated_ping_state;
 
 /* deframer state for the overall http2 stream of bytes */
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index b9c2f15face21cbc512f979a9f99438632592d00..0869056f56d3c5994bb67808ddd6db6c0073f241 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -101,12 +101,14 @@ static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
               "Ping delayed [%p]: not enough time elapsed since last ping",
               t->peer_string);
     }
-
-    grpc_timer_init(exec_ctx, &t->ping_state.delayed_ping_timer,
-                    gpr_time_add(t->ping_state.last_ping_sent_time,
-                                 t->ping_policy.min_time_between_pings),
-                    &t->retry_initiate_ping_locked,
-                    gpr_now(GPR_CLOCK_MONOTONIC));
+    if (!t->ping_state.is_delayed_ping_timer_set) {
+      t->ping_state.is_delayed_ping_timer_set = true;
+      grpc_timer_init(exec_ctx, &t->ping_state.delayed_ping_timer,
+                      gpr_time_add(t->ping_state.last_ping_sent_time,
+                                   t->ping_policy.min_time_between_pings),
+                      &t->retry_initiate_ping_locked,
+                      gpr_now(GPR_CLOCK_MONOTONIC));
+    }
     return;
   }
   /* coalesce equivalent pings into this one */