Your data. Anywhere you go.

New Relic for iOS or Android


Download on the App Store    Android App on Google play


New Relic Insights App for iOS


Download on the App Store


Learn more

Close icon

Browser Dashboard - Time to First Byte (TTFB)

browser
shared-dashboards

#1

Dashboard of the Day - Time to First Byte (TTFB)

Motivation

This dashboard highlights granular page load details set from the Navigation Timing API. Use this space to determine the average time to first byte of a page load and drill into any AJAX and JS Errors that may contribute to slow load times.


Screenshot



Dashboard Details

Required Products: Browser
Level of Effort: Low
This dashboard will work on the standard New Relic data models and does not require any custom attributes or events.

Settings
Use the gear button to edit your dashboard and configure the following settings:

  • Dashboard Filter: Enabled
  • Enabled Event Types: PageView, BrowserInteraction, AjaxRequest, JavaScriptError
  • Enabled Attributes: appName, pageUrl, requestUri, targetUrl

Chart Details

In this section, we’ll go into the details on the purpose of each of the charts. We’ll also show you the query (NRQL) that you can cut/paste into your Insights query bar.

Average Stats

Line Chart

from BrowserInteraction select average(timeToDomComplete), average(timeToDomContentLoadedEventEnd), average(timeToDomInteractive), average(duration) where trigger = 'initialPageLoad' limit 1000 TIMESERIES

Displays the average load times for specific elements of the Navigation Timing API over time

Average Time to Render

Area Chart

SELECT average(timeToDomComplete - timeToDomLoading) AS 'Time to Render' FROM BrowserInteraction SINCE 1 week ago TIMESERIES facet appName

Displays average time until the page renders over time

Time to First Byte

Area Chart

SELECT average(timeToResponseStart) FROM BrowserInteraction since 1 week ago TIMESERIES

Displays average time until the browser receives the first byte response from the web server over time

Average Page Load Details

Line Chart

from BrowserInteraction select average(timeToDomComplete) as 'Dom Complete', average(timeToDomContentLoadedEventEnd) as 'Dom Content Loaded' , average(timeToDomInteractive) as 'Dom Content Interactive', average(duration) as 'Total Duration of Interaction Event', average(timeToDomComplete - timeToDomLoading) AS 'Time to Render', average(timeToResponseStart) as 'Time to First Bite' where trigger = 'initialPageLoad' limit 1000 TIMESERIES

This chart adds to the first chart with more page load statistics

Time to Render + First Byte

Chart Type

SELECT average(timeToDomComplete - timeToDomLoading) AS 'Time to Render', average(timeToResponseStart) as 'Time to First Bite' FROM BrowserInteraction SINCE 1 week ago TIMESERIES 2 hours

This chart combines the 2nd and 3rd queries into a single line chart

Page Views (app filter)

Facet Table

SELECT count(*) FROM PageView facet appName

Counts the total number of page views listed per app (facetable)

Add a Chart Facet for extra functionality!

Chart Facets expands the ability to quickly scope down into data by being able to click on an attribute and have the entire dashboard facet by that data point. Add this to the chart by doing the following:

  1. Run the NRQL query and save the chart to your dashboard.
  2. Open the menu in the newly created chart by clicking the ellipses in the top right corner and select “Edit Chart”.
  3. Click the blue button labeled “Link facets to a dashboard”, select the “current dashboard” option, and click Save.

Throughput & Response Times

Attribute Sheet

from PageView select count(*), average(duration) as 'Avg Pg Load', average(backendDuration) as 'Avg Back End', average(domProcessingDuration) + average(pageRenderingDuration) as 'Avg Front End'

Provides the total number of page views, average page load duration, average backend duration (web app time), and front end duration (page load timing)

Slow Load Interactions

Facet Table

from BrowserInteraction select average(duration) facet targetUrl

Highlights the slowest browser interactions faceted by the URL

Add a Chart Facet for extra functionality!

Chart Facets expands the ability to quickly scope down into data by being able to click on an attribute and have the entire dashboard facet by that data point. Add this to the chart by doing the following:

  1. Run the NRQL query and save the chart to your dashboard.
  2. Open the menu in the newly created chart by clicking the ellipses in the top right corner and select “Edit Chart”.
  3. Click the blue button labeled “Link facets to a dashboard”, select the “current dashboard” option, and click Save.

AJAX Error Rate

Gauge Chart

select filter(count(*), WHERE httpResponseCode >= 300) / count(*) * 100 as 'Error Rate (%)' FROM AjaxRequest

Provides a percentage of AJAX errors

AJAX App/Page Issues

Table

SELECT count(*) from AjaxRequest where httpResponseCode >= 300 facet appName, pageUrl, httpResponseCode limit 100

Highlights where the AJAX errors are occurring in your app faceted by appName and pageUrl

AJAX Errors

Facet Table

SELECT count(*) from AjaxRequest facet cases(WHERE httpResponseCode >= 200 and httpResponseCode < 300 as '200s', WHERE httpResponseCode >= 300 and httpResponseCode < 400 as '300s', WHERE httpResponseCode >= 400 and httpResponseCode < 500 as '400s', WHERE httpResponseCode >= 500 and httpResponseCode < 600 as '500s')

Counts the number of AJAX Errors faceted out by httpResponseCode

Add a Chart Facet for extra functionality!

Chart Facets expands the ability to quickly scope down into data by being able to click on an attribute and have the entire dashboard facet by that data point. Add this to the chart by doing the following:

  1. Run the NRQL query and save the chart to your dashboard.
  2. Open the menu in the newly created chart by clicking the ellipses in the top right corner and select “Edit Chart”.
  3. Click the blue button labeled “Link facets to a dashboard”, select the “current dashboard” option, and click Save.

AJAX Errors Over Time

Area Chart

select filter(count(*), WHERE httpResponseCode >= 300) / filter(count(*),WHERE httpResponseCode < 300) as 'Error Rate' FROM AjaxRequest TIMESERIES

Displays the number of AJAX Errors over time

Top 5 AJAX Errors by Page URL

Facet Table

from AjaxRequest select count(*) where httpResponseCode > 300 facet pageUrl limit 5

Highlights the top 5 pageURLs with the highest number of AJAX errors

Add a Chart Facet for extra functionality!

Chart Facets expands the ability to quickly scope down into data by being able to click on an attribute and have the entire dashboard facet by that data point. Add this to the chart by doing the following:

  1. Run the NRQL query and save the chart to your dashboard.
  2. Open the menu in the newly created chart by clicking the ellipses in the top right corner and select “Edit Chart”.
  3. Click the blue button labeled “Link facets to a dashboard”, select the “current dashboard” option, and click Save.

JS Error Details

Facet Table

FROM JavaScriptError select count(*) facet errorClass, errorMessage

Provides the top JS errors and the error message and class associated with them

JS Errors by Request URI

Facet Table

FROM JavaScriptError select count(*) facet requestUri

Highlights the number of JS Errors faceted by requestUri

Add a Chart Facet for extra functionality!

Chart Facets expands the ability to quickly scope down into data by being able to click on an attribute and have the entire dashboard facet by that data point. Add this to the chart by doing the following:

  1. Run the NRQL query and save the chart to your dashboard.
  2. Open the menu in the newly created chart by clicking the ellipses in the top right corner and select “Edit Chart”.
  3. Click the blue button labeled “Link facets to a dashboard”, select the “current dashboard” option, and click Save.

Extra Credit - Share your dashboard with the community!

Want to be a super “NeRD” (New Relic Developer)?
Use the API Explorer (or our Postman collection) to load the dashboard definition below into Insights or share the definition of your dashboard and increase your international NeRD cred! (And you’ll earn a cool badge for your community profile!)
Here’s some quick tips on how to do this.

Dashboard Definition

{
  "dashboard": {
    "title": "SRE & DevOps Browser Stats",
    "description": null,
    "icon": "bar-chart",
    "visibility": "all",
    "editable": "editable_by_all",
    "metadata": {
      "version": 1
    },
    "widgets": [
{
        "visualization": "markdown",
        "layout": {
          "width": 3,
          "height": 1,
          "row": 1,
          "column": 1
        },
        "data": [
          {
            "source": "# Motivation\n---\nThis dashboard highlights granular page load details set from the [Navigation Timing API](https://www.w3.org/TR/navigation-timing/). Use this space to determine the average time to first byte of a page load and drill into any AJAX and JS Errors that may contribute to slow load times.\n\nhttps://discuss.newrelic.com/t/browser-dashboard-time-to-first-byte-ttfb/61579"
          }
        ],
        "presentation": {
          "title": "",
          "notes": null
        }
      },
      {
        "visualization": "line_chart",
        "layout": {
          "width": 1,
          "height": 1,
          "row": 1,
          "column": 1
        },
        "data": [
          {
            "nrql": "from BrowserInteraction select average(timeToDomComplete), average(timeToDomContentLoadedEventEnd), average(timeToDomInteractive), average(duration)  where trigger = 'initialPageLoad' limit 1000 TIMESERIES"
          }
        ],
        "presentation": {
          "title": "Average Stats",
          "notes": "Displays the average load times for specific elements of the Navigation Timing API over time"
        }
      },
      {
        "visualization": "faceted_line_chart",
        "layout": {
          "width": 1,
          "height": 1,
          "row": 1,
          "column": 2
        },
        "data": [
          {
            "nrql": "SELECT average(timeToDomComplete - timeToDomLoading) AS 'Time to Render' FROM BrowserInteraction SINCE 1 week ago TIMESERIES facet appName"
          }
        ],
        "presentation": {
          "title": "Average Time to Render",
          "notes": "Displays average time until the page renders over time"
        }
      },
      {
        "visualization": "line_chart",
        "layout": {
          "width": 1,
          "height": 1,
          "row": 1,
          "column": 3
        },
        "data": [
          {
            "nrql": "SELECT average(timeToResponseStart) FROM BrowserInteraction since 1 week ago TIMESERIES"
          }
        ],
        "presentation": {
          "title": "TTFB",
          "notes": "Displays average time until the browser receives the first byte response from the web server over time"
        }
      },
      {
        "visualization": "line_chart",
        "layout": {
          "width": 2,
          "height": 1,
          "row": 2,
          "column": 1
        },
        "data": [
          {
            "nrql": "from BrowserInteraction select average(timeToDomComplete) as 'Dom Complete', average(timeToDomContentLoadedEventEnd) as 'Dom Content Loaded' , average(timeToDomInteractive) as 'Dom Content Interactive', average(duration) as 'Total Duration of Interaction Event', average(timeToDomComplete - timeToDomLoading) AS 'Time to Render', average(timeToResponseStart) as 'Time to First Bite'  where trigger = 'initialPageLoad' limit 1000 TIMESERIES"
          }
        ],
        "presentation": {
          "title": "Average Page Load Details",
          "notes": "This chart adds to the first chart with more page load statistics"
        }
      },
      {
        "visualization": "line_chart",
        "layout": {
          "width": 1,
          "height": 1,
          "row": 2,
          "column": 3
        },
        "data": [
          {
            "nrql": "SELECT average(timeToDomComplete - timeToDomLoading) AS 'Time to Render', average(timeToResponseStart) as 'Time to First Bite' FROM BrowserInteraction SINCE 1 week ago TIMESERIES 2 hours"
          }
        ],
        "presentation": {
          "title": "Time to Render + First Byte",
          "notes": "This chart combines the 2nd and 3rd queries into a single line chart"
        }
      },
      {
        "visualization": "facet_table",
        "layout": {
          "width": 1,
          "height": 1,
          "row": 3,
          "column": 1
        },
        "data": [
          {
            "nrql": "SELECT count(*) FROM PageView facet appName"
          }
        ],
        "presentation": {
          "title": "Page Views (App Filter)",
          "notes": "Counts the total number of page views listed per app (facetable)"
        }
      },
      {
        "visualization": "attribute_sheet",
        "layout": {
          "width": 2,
          "height": 1,
          "row": 3,
          "column": 2
        },
        "data": [
          {
            "nrql": "from PageView select count(*), average(duration) as 'Avg Pg Load', average(backendDuration) as 'Avg Back End', average(domProcessingDuration) + average(pageRenderingDuration) as 'Avg Front End'"
          }
        ],
        "presentation": {
          "title": "Throughput & Response Times",
          "notes": "Provides the total number of page views, average page load duration, average backend duration (web app time), and front end duration (page load timing)"
        }
      },
      {
        "visualization": "facet_table",
        "layout": {
          "width": 3,
          "height": 1,
          "row": 4,
          "column": 1
        },
        "data": [
          {
            "nrql": "from BrowserInteraction select average(duration) facet targetUrl"
          }
        ],
        "presentation": {
          "title": "Slow Load Interactions",
          "notes": "Highlights the slowest browser interactions faceted by the URL"
        }
      },
      {
        "visualization": "gauge",
        "layout": {
          "width": 1,
          "height": 1,
          "row": 5,
          "column": 1
        },
        "data": [
          {
            "nrql": "select filter(count(*), WHERE httpResponseCode >= 300) / count(*) * 100 as 'Error Rate (%)' FROM AjaxRequest"
          }
        ],
        "presentation": {
          "title": "AJAX Error Rate",
          "notes": "Provides a percentage of AJAX errors",
          "threshold": {
            "red": 133
          }
        }
      },
      {
        "visualization": "facet_table",
        "layout": {
          "width": 1,
          "height": 1,
          "row": 5,
          "column": 2
        },
        "data": [
          {
            "nrql": "SELECT count(*) from AjaxRequest where httpResponseCode >= 300 facet appName, pageUrl, httpResponseCode limit 100"
          }
        ],
        "presentation": {
          "title": "AJAX App/Page Issues",
          "notes": "Highlights where the AJAX errors are occurring in your app faceted by appName and pageUrl"
        }
      },
      {
        "visualization": "facet_table",
        "layout": {
          "width": 1,
          "height": 1,
          "row": 5,
          "column": 3
        },
        "data": [
          {
            "nrql": "SELECT count(*) from AjaxRequest facet cases(WHERE httpResponseCode >= 200 and httpResponseCode < 300 as '200s', WHERE httpResponseCode >= 300 and httpResponseCode < 400 as '300s', WHERE httpResponseCode >= 400 and httpResponseCode < 500 as '400s', WHERE httpResponseCode >= 500 and httpResponseCode < 600 as '500s')"
          }
        ],
        "presentation": {
          "title": "AJAX Errors",
          "notes": "Counts the number of AJAX Errors faceted out by httpResponseCode"
        }
      },
      {
        "visualization": "line_chart",
        "layout": {
          "width": 1,
          "height": 1,
          "row": 6,
          "column": 1
        },
        "data": [
          {
            "nrql": "select filter(count(*), WHERE httpResponseCode >= 300) / filter(count(*),WHERE httpResponseCode < 300) as 'Error Rate' FROM AjaxRequest TIMESERIES"
          }
        ],
        "presentation": {
          "title": "AJAX Errors Over Time",
          "notes": "Displays the number of AJAX Errors over time"
        }
      },
      {
        "visualization": "facet_table",
        "layout": {
          "width": 2,
          "height": 1,
          "row": 6,
          "column": 2
        },
        "data": [
          {
            "nrql": "from AjaxRequest select count(*) where httpResponseCode > 300 facet pageUrl  limit 5"
          }
        ],
        "presentation": {
          "title": "Top 5 AJAX Errors by Page URL",
          "notes": "Highlights the top 5 pageURLs with the highest number of AJAX errors"
        }
      },
      {
        "visualization": "facet_table",
        "layout": {
          "width": 3,
          "height": 1,
          "row": 7,
          "column": 1
        },
        "data": [
          {
            "nrql": "FROM JavaScriptError select count(*) facet errorClass, errorMessage"
          }
        ],
        "presentation": {
          "title": "JS Error Details",
          "notes": "Provides the top JS errors and the error message and class associated with them"
        }
      },
      {
        "visualization": "facet_table",
        "layout": {
          "width": 3,
          "height": 1,
          "row": 8,
          "column": 1
        },
        "data": [
          {
            "nrql": "FROM JavaScriptError select count(*) facet requestUri"
          }
        ],
        "presentation": {
          "title": "JS Errors by Request URI",
          "notes": "Highlights the number of JS Errors faceted by requestUri"
        }
      }
    ],
    "filter": {
      "event_types": [
        "PageView",
        "BrowserInteraction",
        "AjaxRequest",
        "JavaScriptError"
      ],
      "attributes": []
    }
  }
}