diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index 6c1c87e03584f82060aa7f60fd7202bc5b5ea74f..4ec5bed89e3e29ed55cc08108f25d980d4c5ce1c 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -80,6 +80,7 @@
 
 typedef void (*destroy_user_data_func)(void *user_data);
 
+#define SIZE_IN_DECODER_TABLE_NOT_SET -1
 /* Shadow structure for grpc_mdstr for non-static values */
 typedef struct internal_string {
   /* must be byte compatible with grpc_mdstr */
@@ -94,8 +95,7 @@ typedef struct internal_string {
 
   gpr_slice base64_and_huffman;
 
-  bool has_size_in_decoder_table;
-  size_t size_in_decoder_table;
+  gpr_atm size_in_decoder_table;
 
   struct internal_string *bucket_next;
 } internal_string;
@@ -411,8 +411,7 @@ grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) {
   }
   s->has_base64_and_huffman_encoded = 0;
   s->hash = hash;
-  s->has_size_in_decoder_table = false;
-  s->size_in_decoder_table = 0;
+  s->size_in_decoder_table = SIZE_IN_DECODER_TABLE_NOT_SET;
   s->bucket_next = shard->strs[idx];
   shard->strs[idx] = s;
 
@@ -600,17 +599,18 @@ size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem) {
     }
   } else {
     internal_string *is = (internal_string *)elem->value;
-    if (is->has_size_in_decoder_table == false) {
-      is->has_size_in_decoder_table = true;
+    gpr_atm current_size = gpr_atm_no_barrier_load(&is->size_in_decoder_table);
+    if (current_size == SIZE_IN_DECODER_TABLE_NOT_SET) {
       if (grpc_is_binary_header(
               (const char *)GPR_SLICE_START_PTR(elem->key->slice),
               GPR_SLICE_LENGTH(elem->key->slice))) {
-        is->size_in_decoder_table = get_base64_encoded_size(value_len);
+        current_size = (gpr_atm)get_base64_encoded_size(value_len);
       } else {
-        is->size_in_decoder_table = value_len;
+        current_size = (gpr_atm)value_len;
       }
+      gpr_atm_no_barrier_store(&is->size_in_decoder_table, current_size);
     }
-    return overhead_and_key + is->size_in_decoder_table;
+    return overhead_and_key + (size_t)current_size;
   }
 }
 
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index 45b0fa41e470b8258e16a6be4e1644d86e000f01..262f3ff0340806e34f5552312d5fafae0597c022 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -207,6 +207,7 @@ static void verify_table_size_change_match_elem_size(const char *key,
   grpc_metadata_batch_destroy(&b);
 
   GPR_ASSERT(g_compressor.table_size == elem_size + initial_table_size);
+  gpr_free(e);
 }
 
 static void test_encode_header_size(void) {