HTTP/2’s multiplexing can dramatically improve performance by allowing multiple requests over a single connection, but most API Gateways default to HTTP/1.1.

Here’s how to configure an AWS API Gateway to serve HTTP/2 traffic, using a REST API as the example.

First, we need to enable HTTP/2 for the API Gateway. This is done at the stage level.

aws apigateway update-stage \
    --rest-api-id abcdef1234 \
    --stage-name prod \
    --patch-operations op=replace,path=/http2Enabled,value=true

This command uses the AWS CLI to update the prod stage of the REST API with ID abcdef1234. The http2Enabled property is set to true, signaling to API Gateway that this stage should now support HTTP/2.

Once enabled, API Gateway automatically handles the HTTP/2 negotiation. When a client initiates a connection to your API Gateway stage endpoint, API Gateway will advertise its support for HTTP/2 via ALPN (Application-Layer Protocol Negotiation) during the TLS handshake. If the client also supports HTTP/2 and agrees, the connection will be established using HTTP/2.

The real magic happens on the backend integration. By default, API Gateway will still communicate with your backend service using HTTP/1.1. To leverage HTTP/2 all the way to your application, you need to configure your integration to use the HTTP_PROXY integration type and specify http2 as the ConnectionType.

Let’s look at an example of how this integration would be defined, typically seen in CloudFormation or Terraform.

Resources:
  MyApiGateway:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: MyHttp2Api

  MyResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref MyApiGateway
      ParentId: !GetAtt MyApiGateway.RootResourceId
      PathPart: myresource

  MyMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      RestApiId: !Ref MyApiGateway
      ResourceId: !Ref MyResource
      HttpMethod: GET
      AuthorizationType: NONE
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: GET # This should match the HttpMethod of the client request
        Uri: !Sub "http://${MyHttp2BackendService.Name}.example.com/path"
        ConnectionType: HTTP2 # This is the key for HTTP/2 to the backend
        PassthroughBehavior: WHEN_NO_MATCH
      MethodResponses:
        - StatusCode: 200
          ResponseModels:
            "application/json": "Empty"

  MyDeployment:
    Type: AWS::ApiGateway::Deployment
    Properties:
      RestApiId: !Ref MyApiGateway
      StageName: prod

  MyStage:
    Type: AWS::ApiGateway::Stage
    Properties:
      RestApiId: !Ref MyApiGateway
      StageName: prod
      AutoDeploy: true
      Http2Enabled: true # Ensure this is set for the stage

In this CloudFormation snippet, the ConnectionType: HTTP2 within the Integration block is crucial. This tells API Gateway to establish an HTTP/2 connection to the specified Uri (http://${MyHttp2BackendService.Name}.example.com/path). The backend service must be capable of receiving and processing HTTP/2 requests.

The IntegrationHttpMethod within the integration also needs to be set correctly. When ConnectionType is HTTP2, API Gateway will forward the original client’s HTTP method to the backend. For a GET request from the client, the IntegrationHttpMethod should also be GET.

You can verify the HTTP/2 connection on the client side using browser developer tools (Network tab, check the Protocol column) or tools like nghttp. For example, using nghttp to test your API Gateway endpoint:

nghttp -H "Host: abcdef1234.execute-api.us-east-1.amazonaws.com" \
https://abcdef1234.execute-api.us-east-1.amazonaws.com/prod/myresource

If the connection is successful, you’ll see output indicating the HTTP/2 protocol is in use.

The PassthroughBehavior: WHEN_NO_MATCH is a common setting for proxy integrations, ensuring that if no specific mapping is found for the request, it’s passed through to the backend.

It’s important to note that not all backend services natively support HTTP/2. If your backend only supports HTTP/1.1, API Gateway will gracefully fall back to using an HTTP/1.1 connection to that backend, even if the client connection to API Gateway is HTTP/2.

The Uri for the integration can point to various AWS services like Lambda, other HTTP endpoints, or even services behind an Application Load Balancer. When pointing to an ALB, ensure the ALB listener is configured for HTTP/2.

The most overlooked aspect of this setup is that while API Gateway can serve HTTP/2 to the client and connect to the backend via HTTP/2, the backend service itself must be configured to accept and process HTTP/2 requests on the specified endpoint. A common mistake is enabling HTTP/2 on API Gateway but having a backend that only speaks HTTP/1.1, which will result in successful connections but no performance gains and potentially subtle compatibility issues.

The next hurdle you’ll likely encounter is managing request and response headers between HTTP/1.1 and HTTP/2, as the header framing and pseudo-headers behave differently.

Want structured learning?

Take the full Http2 course →