diff --git a/doc/service_config.md b/doc/service_config.md
index 7318b69f214983ceb3745d797d17f40ef841995e..2dabb83a37f76a3cd41f134159d85327bd637385 100644
--- a/doc/service_config.md
+++ b/doc/service_config.md
@@ -95,10 +95,7 @@ The service config is a JSON string of the following form:
       # will not be sent and the client will see an error.
       # Note that 0 is a valid value, meaning that the request message must
       # be empty.
-      #
-      # The format of the value is that of the 'uint64' type defined here:
-      # https://developers.google.com/protocol-buffers/docs/proto3#json
-      'maxRequestMessageBytes': string,
+      'maxRequestMessageBytes': number,
 
       # The maximum allowed payload size for an individual response or object
       # in a stream (server->client) in bytes. The size which is measured is
@@ -114,10 +111,7 @@ The service config is a JSON string of the following form:
       # will not be sent, and the client will see an error.
       # Note that 0 is a valid value, meaning that the response message must
       # be empty.
-      #
-      # The format of the value is that of the 'uint64' type defined here:
-      # https://developers.google.com/protocol-buffers/docs/proto3#json
-      'maxResponseMessageBytes': string
+      'maxResponseMessageBytes': number
     }
   ]
 }
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index 862090b371cf974456fa4d0ed05c3f55a9cb9b97..90f470139bb7d1210d5d2aacc6627d36a7a9947b 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -68,12 +68,16 @@ static void* message_size_limits_create_from_json(const grpc_json* json) {
     if (field->key == NULL) continue;
     if (strcmp(field->key, "maxRequestMessageBytes") == 0) {
       if (max_request_message_bytes >= 0) return NULL;  // Duplicate.
-      if (field->type != GRPC_JSON_STRING) return NULL;
+      if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) {
+        return NULL;
+      }
       max_request_message_bytes = gpr_parse_nonnegative_int(field->value);
       if (max_request_message_bytes == -1) return NULL;
     } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) {
       if (max_response_message_bytes >= 0) return NULL;  // Duplicate.
-      if (field->type != GRPC_JSON_STRING) return NULL;
+      if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) {
+        return NULL;
+      }
       max_response_message_bytes = gpr_parse_nonnegative_int(field->value);
       if (max_response_message_bytes == -1) return NULL;
     }
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index 57d4f1c19755d1eab70a6c641bbf921911f9c7ed..2f7386335761fe6f80aff99b21388c9bad74e5a2 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -108,9 +108,12 @@ static void end_test(grpc_end2end_test_fixture *f) {
 // recv limit on server.
 static void test_max_message_length_on_request(grpc_end2end_test_config config,
                                                bool send_limit,
-                                               bool use_service_config) {
-  gpr_log(GPR_INFO, "testing request with send_limit=%d use_service_config=%d",
-          send_limit, use_service_config);
+                                               bool use_service_config,
+                                               bool use_string_json_value) {
+  gpr_log(GPR_INFO,
+          "testing request with send_limit=%d use_service_config=%d "
+          "use_string_json_value=%d",
+          send_limit, use_service_config, use_string_json_value);
 
   grpc_end2end_test_fixture f;
   grpc_call *c = NULL;
@@ -142,14 +145,23 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config,
     arg.type = GRPC_ARG_STRING;
     arg.key = GRPC_ARG_SERVICE_CONFIG;
     arg.value.string =
-        "{\n"
-        "  \"methodConfig\": [ {\n"
-        "    \"name\": [\n"
-        "      { \"service\": \"service\", \"method\": \"method\" }\n"
-        "    ],\n"
-        "    \"maxRequestMessageBytes\": \"5\"\n"
-        "  } ]\n"
-        "}";
+        use_string_json_value
+            ? "{\n"
+              "  \"methodConfig\": [ {\n"
+              "    \"name\": [\n"
+              "      { \"service\": \"service\", \"method\": \"method\" }\n"
+              "    ],\n"
+              "    \"maxRequestMessageBytes\": \"5\"\n"
+              "  } ]\n"
+              "}"
+            : "{\n"
+              "  \"methodConfig\": [ {\n"
+              "    \"name\": [\n"
+              "      { \"service\": \"service\", \"method\": \"method\" }\n"
+              "    ],\n"
+              "    \"maxRequestMessageBytes\": 5\n"
+              "  } ]\n"
+              "}";
     client_args = grpc_channel_args_copy_and_add(NULL, &arg, 1);
   } else {
     // Set limit via channel args.
@@ -286,9 +298,12 @@ done:
 // recv limit on client.
 static void test_max_message_length_on_response(grpc_end2end_test_config config,
                                                 bool send_limit,
-                                                bool use_service_config) {
-  gpr_log(GPR_INFO, "testing response with send_limit=%d use_service_config=%d",
-          send_limit, use_service_config);
+                                                bool use_service_config,
+                                                bool use_string_json_value) {
+  gpr_log(GPR_INFO,
+          "testing response with send_limit=%d use_service_config=%d "
+          "use_string_json_value=%d",
+          send_limit, use_service_config, use_string_json_value);
 
   grpc_end2end_test_fixture f;
   grpc_call *c = NULL;
@@ -320,14 +335,23 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
     arg.type = GRPC_ARG_STRING;
     arg.key = GRPC_ARG_SERVICE_CONFIG;
     arg.value.string =
-        "{\n"
-        "  \"methodConfig\": [ {\n"
-        "    \"name\": [\n"
-        "      { \"service\": \"service\", \"method\": \"method\" }\n"
-        "    ],\n"
-        "    \"maxResponseMessageBytes\": \"5\"\n"
-        "  } ]\n"
-        "}";
+        use_string_json_value
+            ? "{\n"
+              "  \"methodConfig\": [ {\n"
+              "    \"name\": [\n"
+              "      { \"service\": \"service\", \"method\": \"method\" }\n"
+              "    ],\n"
+              "    \"maxResponseMessageBytes\": \"5\"\n"
+              "  } ]\n"
+              "}"
+            : "{\n"
+              "  \"methodConfig\": [ {\n"
+              "    \"name\": [\n"
+              "      { \"service\": \"service\", \"method\": \"method\" }\n"
+              "    ],\n"
+              "    \"maxResponseMessageBytes\": 5\n"
+              "  } ]\n"
+              "}";
     client_args = grpc_channel_args_copy_and_add(NULL, &arg, 1);
   } else {
     // Set limit via channel args.
@@ -462,17 +486,29 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
 
 void max_message_length(grpc_end2end_test_config config) {
   test_max_message_length_on_request(config, false /* send_limit */,
-                                     false /* use_service_config */);
+                                     false /* use_service_config */,
+                                     false /* use_string_json_value */);
   test_max_message_length_on_request(config, true /* send_limit */,
-                                     false /* use_service_config */);
+                                     false /* use_service_config */,
+                                     false /* use_string_json_value */);
   test_max_message_length_on_response(config, false /* send_limit */,
-                                      false /* use_service_config */);
+                                      false /* use_service_config */,
+                                      false /* use_string_json_value */);
   test_max_message_length_on_response(config, true /* send_limit */,
-                                      false /* use_service_config */);
+                                      false /* use_service_config */,
+                                      false /* use_string_json_value */);
   test_max_message_length_on_request(config, true /* send_limit */,
-                                     true /* use_service_config */);
+                                     true /* use_service_config */,
+                                     false /* use_string_json_value */);
+  test_max_message_length_on_request(config, true /* send_limit */,
+                                     true /* use_service_config */,
+                                     true /* use_string_json_value */);
+  test_max_message_length_on_response(config, false /* send_limit */,
+                                      true /* use_service_config */,
+                                      false /* use_string_json_value */);
   test_max_message_length_on_response(config, false /* send_limit */,
-                                      true /* use_service_config */);
+                                      true /* use_service_config */,
+                                      true /* use_string_json_value */);
 }
 
 void max_message_length_pre_init(void) {}