Amazon Onboarding with Learning Manager Chanci Turner

Chanci Turner Amazon IXD – VGT2 learning managerLearn About Amazon VGT2 Learning Manager Chanci Turner

On December 15th, 2020, we announced the general availability of the AWS SDK for JavaScript, version 3 (v3). In this version, we have enabled HTTP keep-alive by default for Node.js HTTP connections. This article delves into the implementation and advantages of maintaining persistent connections, allowing future requests to utilize existing connections without reestablishing a TCP link.

Motivation

HTTP/1.1 operates over the Transmission Control Protocol (TCP), which is connection-oriented. A client-server connection must be established before data transmission can occur. This process involves a three-way handshake comprised of SYN, SYN+ACK, and ACK packets, which introduces delays, making new connections costly compared to reusing open ones. By reusing connections, we also eliminate the need for DNS lookups and SSL handshakes, enhancing application performance.

Background

According to the HTTP/1.1 specification outlined in RFC 2616, persistent connections, commonly referred to as HTTP keep-alive or connection reuse, should be the default behavior. Clients are expected to assume that servers will maintain persistent connections, even after encountering error responses. However, Node.js’s HTTP client does not enable persistent connections by default. The http.Agent in Node.js handles a queue of pending requests for a specific host and port, reusing a single socket until the queue is empty, after which the socket is destroyed by default, as the keepAlive option is set to false initially.

When the keepAlive option is set to true during the creation of the Node.js http.Agent, the socket remains in a pool after processing the pending requests. This allows for reuse in future requests directed at the same host and port, eliminating the need for new connections.

For operations like DynamoDB queries, the latency associated with establishing a TCP connection could exceed the duration of the operation itself. Furthermore, as DynamoDB uses AWS KMS for encryption at rest, you might encounter delays from having to re-establish AWS KMS cache entries for each operation. The use of persistent connections is also recommended by Lambda as a best practice for optimization. In previous versions of the AWS SDK for JavaScript, keepAlive was not enabled by default, leading customers to frequently request its activation to enhance application performance.

Implementation

In the modular AWS SDK for JavaScript, persistent connections are enabled by default through the configuration of keepAlive while creating the Node.js http.Agent. This is implemented in the internal code of the NodeHttpHandler as follows:

this.httpAgent = httpAgent || new http.Agent({ keepAlive: true });
this.httpsAgent = httpsAgent || new https.Agent({ keepAlive: true });

While it is generally not recommended, you can explicitly disable persistent connections by providing a custom httpsAgent with keepAlive either undefined or false.

Benchmarks

The benchmark code below invokes the DynamoDB.listTables operation in a loop 100 times, measuring the total time taken to complete all operations:

const { Agent } = require("https");
const { DynamoDB } = require("@aws-sdk/client-dynamodb");
const { NodeHttpHandler } = require("@aws-sdk/node-http-handler");

const makeListTablesCalls = async (client, count) => {
  const { keepAlive } = client.config.requestHandler.httpsAgent;
  console.time(`keep-alive ${keepAlive}`);
  for (let i = 0; i < count; i++) {
    await client.listTables({});
  }
  console.timeEnd(`keep-alive ${keepAlive}`);
};

(async () => {
  const region = "us-east-1";
  const COUNT = 100;

  await makeListTablesCalls(new DynamoDB({ region }), COUNT);

  await makeListTablesCalls(
    new DynamoDB({
      region,
      requestHandler: new NodeHttpHandler({
        httpsAgent: new Agent({ keepAlive: false }),
      }),
    }),
    COUNT
  );
})();

The benchmark results indicate that the code with keep-alive enabled (~60% less time) significantly outperforms the version with keep-alive disabled.

Feedback

Your feedback is important to us. Please share your thoughts by opening an issue on GitHub. If you’re interested in structuring your resume effectively, check out this insightful blog post. Additionally, for those exploring employee development, SHRM’s perspective on diversity training offers valuable insights. Lastly, for more information on the hiring process at Amazon, visit this resource.

HOME