A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://blog.risingstack.com/measuring-http-timings-node-js/ below:

Understanding & Measuring HTTP Timings with Node.js

Understanding and measuring HTTP timings helps us to discover performance bottlenecks in client to server or server to server communication. This article explains timings in an HTTP request and shows how to measure them in Node.jsNode.js is an asynchronous event-driven JavaScript runtime and is the most effective when building scalable network applications. Node.js is free of locks, so there's no chance to dead-lock any process..

Before we jump into HTTP timings, let’s take a look at some basic concepts:

Now let’s take a look at the timeline of a usual HTTP Request:

Timings explained:

How do HTTP timings help to discover bottlenecks?

For example, if your DNS Lookup takes longer time than you expected, the issue might be with your DNS provider or with your DNS caching settings.

When you see longer Time to First Byte durations, you should check out the latency between the endpoints, but you should also check out the current load of the server.

Slow Content Transfer can be caused by inefficient response body like sending back too much data (unused JSON properties, etc.) or by a slow connection as well.

Measuring HTTP timings in Node.js

To measure HTTP timings in Node.js, we need to subscribe to a specific request, response and socket events. Here is a short code snippet how to do this in Node.js, this example focuses only to the timings:

  const timings = {
    // use process.hrtime() as it's not a subject of clock drift
    startAt: process.hrtime(),
    dnsLookupAt: undefined,
    tcpConnectionAt: undefined,
    tlsHandshakeAt: undefined,
    firstByteAt: undefined,
    endAt: undefined
  }

  const req = http.request({ ... }, (res) => {
    res.once('readable', () => {
      timings.firstByteAt = process.hrtime()
    })
    res.on('data', (chunk) => { responseBody += chunk })
    res.on('end', () => {
      timings.endAt = process.hrtime()
    })
  })
  req.on('socket', (socket) => {
    socket.on('lookup', () => {
      timings.dnsLookupAt = process.hrtime()
    })
    socket.on('connect', () => {
      timings.tcpConnectionAt = process.hrtime()
    })
    socket.on('secureConnect', () => {
      timings.tlsHandshakeAt = process.hrtime()
    })
  }) 

DNS Lookup only happens with domain names:

// There is no DNS lookup with IP address
const dnsLookup = dnsLookupAt !== undefined ? 
  getDuration(startAt, dnsLookupAt) : undefined

TCP Connection happens immediately after the host is resolved:

const tcpConnection = getDuration((dnsLookupAt || startAt), tcpConnectionAt)

TLS handshake (SSL) happens only with https protocol:

// There is no TLS handshake without https    
const tlsHandshake = tlsHandshakeAt !== undefined ?
      getDuration(tcpConnectionAt, tlsHandshakeAt) : undefined

We wait for server to start sending First Byte:

const firstByte = getDuration((tlsHandshakeAt || tcpConnectionAt), firstByteAt)

Content Transfer starts with the first byte:

const contentTransfer = getDuration(firstByteAt, endAt)

Total Duration is calculated from start and end dates:

const total = getDuration(startAt, endAt)

Too see the whole example together check out our https://github.com/RisingStack/example-http-timings repository.

Tools to measure timings

Now that we know how to measure HTTP timings with Node, let’s talk about existing tools that you can use to understand your HTTP requests.

request module

The popular request module has a built-in method to measure HTTP timings. You can enable it with the time property.

const request = require('request')

request({
  uri: 'https://risingstack.com',
  method: 'GET',
  time: true
}, (err, resp) => {
  console.log(err || resp.timings)
})
Distributed tracing

It’s possible to collect HTTP timings with distributed tracing tools and visualize them on a timeline. This way, you can have a full picture of what’s happening in the background and how much is the real cost of building distributed systems.

RisingStack’s opentracing-auto library has a built-in flag to collect all the HTTP timings with OpenTracing.

HTTP Request timing with opentracing-auto in Jaeger.

Summary

Measuring HTTP Timings with Node.js can help to discover performance bottlenecks. The Node ecosystem provides great tools to extract these metrics from your application.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4