diff --git a/src/core/iomgr/tcp_windows.c b/src/core/iomgr/tcp_windows.c
index 5ff78231bd737c2a5ce62c178edd388ee1b73147..db8e7f56fe94dbe64808fbab2de5efe228288679 100644
--- a/src/core/iomgr/tcp_windows.c
+++ b/src/core/iomgr/tcp_windows.c
@@ -197,7 +197,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
 
   tcp->read_slice = gpr_slice_malloc(8192);
 
-  buffer.len = GPR_SLICE_LENGTH(tcp->read_slice);
+  buffer.len = (ULONG)GPR_SLICE_LENGTH(tcp->read_slice);  // we know slice size fits in 32bit.
   buffer.buf = (char *)GPR_SLICE_START_PTR(tcp->read_slice);
 
   TCP_REF(tcp, "read");
@@ -282,18 +282,20 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   tcp->write_cb = cb;
   tcp->write_slices = slices;
 
+  GPR_ASSERT((tcp->write_slices->count >> 32) == 0);
   if (tcp->write_slices->count > GPR_ARRAY_SIZE(local_buffers)) {
     buffers = (WSABUF *)gpr_malloc(sizeof(WSABUF) * tcp->write_slices->count);
     allocated = buffers;
   }
 
   for (i = 0; i < tcp->write_slices->count; i++) {
-    buffers[i].len = GPR_SLICE_LENGTH(tcp->write_slices->slices[i]);
+    GPR_ASSERT((GPR_SLICE_LENGTH(tcp->write_slices->slices[i]) >> 32) == 0);
+    buffers[i].len = (ULONG) GPR_SLICE_LENGTH(tcp->write_slices->slices[i]);
     buffers[i].buf = (char *)GPR_SLICE_START_PTR(tcp->write_slices->slices[i]);
   }
 
   /* First, let's try a synchronous, non-blocking write. */
-  status = WSASend(socket->socket, buffers, tcp->write_slices->count,
+  status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count,
                    &bytes_sent, 0, NULL, NULL);
   info->wsa_error = status == 0 ? 0 : WSAGetLastError();
 
@@ -322,7 +324,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
   /* If we got a WSAEWOULDBLOCK earlier, then we need to re-do the same
      operation, this time asynchronously. */
   memset(&socket->write_info.overlapped, 0, sizeof(OVERLAPPED));
-  status = WSASend(socket->socket, buffers, tcp->write_slices->count,
+  status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count,
                    &bytes_sent, 0, &socket->write_info.overlapped, NULL);
   if (allocated) gpr_free(allocated);
 
diff --git a/src/core/support/string.c b/src/core/support/string.c
index e0ffeb8a4afecfb6847688f9e1058ee10090df2a..fad0b4008bdb5eb2cde9214387dc3ef6ce55da81 100644
--- a/src/core/support/string.c
+++ b/src/core/support/string.c
@@ -173,6 +173,27 @@ int gpr_ltoa(long value, char *string) {
   return i;
 }
 
+int gpr_int64toa(gpr_int64 value, char *string) {
+  int i = 0;
+  int neg = value < 0;
+
+  if (value == 0) {
+    string[0] = '0';
+    string[1] = 0;
+    return 1;
+  }
+
+  if (neg) value = -value;
+  while (value) {
+    string[i++] = (char)('0' + value % 10);
+    value /= 10;
+  }
+  if (neg) string[i++] = '-';
+  gpr_reverse_bytes(string, i);
+  string[i] = 0;
+  return i;
+}
+
 char *gpr_strjoin(const char **strs, size_t nstrs, size_t *final_length) {
   return gpr_strjoin_sep(strs, nstrs, "", final_length);
 }
diff --git a/src/core/support/string.h b/src/core/support/string.h
index a28e00fd3ec5ab21924af157f72319c4fae51de8..9b604ac5bf59dd5217db356107d0da37c131fd2f 100644
--- a/src/core/support/string.h
+++ b/src/core/support/string.h
@@ -70,6 +70,16 @@ int gpr_parse_bytes_to_uint32(const char *data, size_t length,
    output must be at least GPR_LTOA_MIN_BUFSIZE bytes long. */
 int gpr_ltoa(long value, char *output);
 
+/* Minimum buffer size for calling int64toa */
+#define GPR_INT64TOA_MIN_BUFSIZE (3 * sizeof(gpr_int64))
+
+/* Convert an int64 to a string in base 10; returns the length of the
+output string (or 0 on failure).
+output must be at least GPR_INT64TOA_MIN_BUFSIZE bytes long.
+NOTE: This function ensures sufficient bit width even on Win x64,
+where long is 32bit is size.*/
+int gpr_int64toa(gpr_int64 value, char *output);
+
 /* Reverse a run of bytes */
 void gpr_reverse_bytes(char *str, int len);
 
diff --git a/src/core/transport/chttp2/timeout_encoding.c b/src/core/transport/chttp2/timeout_encoding.c
index 8a9b290ecb9b0a8c6f8f1adb895caa4cfc7029a9..cf81c18a20bbf679231c1bbe6d49d6533149a3c9 100644
--- a/src/core/transport/chttp2/timeout_encoding.c
+++ b/src/core/transport/chttp2/timeout_encoding.c
@@ -36,6 +36,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <grpc/support/port_platform.h>
 #include "src/core/support/string.h"
 
 static int round_up(int x, int divisor) {
@@ -57,13 +58,13 @@ static int round_up_to_three_sig_figs(int x) {
 /* encode our minimum viable timeout value */
 static void enc_tiny(char *buffer) { memcpy(buffer, "1n", 3); }
 
-static void enc_ext(char *buffer, long value, char ext) {
-  int n = gpr_ltoa(value, buffer);
+static void enc_ext(char *buffer, gpr_int64 value, char ext) {
+  int n = gpr_int64toa(value, buffer);
   buffer[n] = ext;
   buffer[n + 1] = 0;
 }
 
-static void enc_seconds(char *buffer, long sec) {
+static void enc_seconds(char *buffer, gpr_int64 sec) {
   if (sec % 3600 == 0) {
     enc_ext(buffer, sec / 3600, 'H');
   } else if (sec % 60 == 0) {