---
title: "Send custom measurements | Grafana Cloud documentation"
description: "Use Faro Web SDK to send custom measurements"
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# Send custom measurements

Faro Web SDK exposes some performance measurements, but there are cases where you might need to send application-specific data. For example, you might want to report some internals of the JavaScript framework you are using, or the time that it was elapsed before a user completed a form. The SDK comes with a simple API to do so.

## Before you begin

- Ensure you have registered your app in the Frontend Observability plugin
- Set up the Faro Web SDK from the [quickstart](/docs/grafana-cloud/monitor-applications/frontend-observability/quickstart/) or [instrumentation](/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/) documentation.

## Steps

Faro instance is an object that can be accessed, after initialization, by either importing it from the `@grafana/faro-web-sdk` or by referencing it from the `window` global object.

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
// Import the global faro instance
import { faro } from '@grafana/faro-web-sdk';
```

The `faro.api` object is a wrapper of the Faro API and provides a [`pushMeasurement`](https://github.com/grafana/faro-web-sdk/tree/main/packages/core#measurements)method with which you can send any number of number values.

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
// Send custom measurements with Faro SDK.
// This example reports some hypothetical measurements from the JavaScript
// framework the application is using.

// send a single measurement
faro.api.pushMeasurement({
  type: 'internal_framework_measurements',
  values: {
    root_render_ms: 142.3,
    memory_used: 286,
  },
});

// send a single measurement with additional contextual attributes
faro.api.pushMeasurement(
  {
    type: 'internal_framework_measurements',
    values: {
      root_render_ms: 142.3,
      memory_used: 286,
    },
  },
  {
    context: {
      hello: 'world',
    },
  }
);
```

These *measurements* are ingested into a Loki instance *as logs* with a specific label `kind=measurements`. For more information about Loki labels, refer to [Labels](/docs/loki/latest/get-started/labels/). This is done because the corresponding metrics would potentially be of high cardinality, since e.g. each browser session is being recorded. Measurements stored as logs don’t suffer from this as this information is just stored in the log line. To use the measurements as metrics for visualisations and aggregations, use [LogQL metric queries](/docs/loki/latest/query/metric_queries/) and consider using [recording rules](/docs/loki/latest/alert/#recording-rules).

## API

The measurements API allows you to pass the following parameters and options:

typescript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```typescript
pushMeasurement: (payload: MeasurementEvent, options?: PushMeasurementOptions)
```

### Parameters

Expand table

| Name      | Description                                                                                 |
|-----------|---------------------------------------------------------------------------------------------|
| `payload` | Object containing measurements                                                              |
| `options` | Configure the behavior of the push API or inject additional data to change the signal data. |

### Push measurement options

Expand table

| Name                   | Description                                                                                                                                                                                                                        |
|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `context`              | Includes additional attributes as key/value pairs                                                                                                                                                                                  |
| `skipDedupe`           | Pushes the signal even if it is identical to the previous one                                                                                                                                                                      |
| `spanContext`          | Provides a custom `spanContext` to the signal                                                                                                                                                                                      |
| `timestampOverwriteMs` | The timestamp represents the exact moment when the respective API was called. In most cases, this precision is sufficient. The `timestampOverwriteMs` option allows you to pass an adjustment timestamp which can be used instead. |
