---
title: "Monitor user actions | Grafana Cloud documentation"
description: "Learn how to monitor application interactions with the Faro Web SDK, create automatic and manual user actions, and configure initial activity timeouts."
---

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

# Monitor user actions

Track your users’ key interactions with your application using Faro’s user action instrumentation. User actions let you follow end-to-end user journeys and attach context to related signals, such as HTTP requests and performance metrics, as users interact with your app.

## Overview

A user action represents an end user’s interaction with your product, for example, activating a button or submitting a form. User actions can start automatically or manually and are linked with signals such as measurements, logs, and errors. This linkage helps you monitor critical paths, identify issues, and measure feature adoption.

## Create a user action

You can create user actions automatically from an HTML element or manually with the Faro API.

### Create actions automatically

Faro starts a user action on `pointerdown`, or on `keydown` when the user presses Space or Enter, if the target HTML element includes the `data-faro-user-action-name` attribute.

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

```html
<button data-faro-user-action-name="save">Save</button>
```

You can override the initial activity timeout for an element with `data-faro-user-action-timeout`:

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

```html
<button data-faro-user-action-name="save" data-faro-user-action-timeout="500">Save</button>
```

You can also customize the action attribute name. Refer to [Customize declarative attributes](#customize-declarative-attributes) for more information.

### Create actions manually

Use the Faro Web SDK `faro.api.startUserAction` method to start a user action programmatically. Refer to [Start a user action manually](#start-a-user-action-manually) for the API parameters and an example.

## Understand the user action lifecycle

When the action completes, Faro adds an `action` field to eligible signals captured while the action is active. Web Vitals measurements and signals excluded by `userActionsInstrumentation.excludeItem` aren’t linked to the action. For example, a performance resource event can look like this:

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

```json
{
  "name": "faro.performance.resource",
  "domain": "browser",
  "attributes": {
    "name": "http://localhost:3000/",
    "duration": "45",
    "tcpHandshakeTime": "1"
  },
  "timestamp": "2025-07-17T08:09:34.051Z",
  "trace": {
    "trace_id": "77ae1ba7a590bb8c085deacb83907e87",
    "span_id": "83e4ec9b0511a4ec"
  },
  "action": {
    "parentId": "CdK96bsFeT",
    "name": "fetch-success"
  }
}
```

When a user action starts, Faro waits for the first qualifying signal. Qualifying signals include a tracked HTTP request start, DOM mutation, or performance entry. If Faro doesn’t receive a qualifying signal within the effective initial activity timeout, it cancels the action.

The configured initial activity timeout applies only while Faro waits for this first signal. After the first signal, Faro uses a fixed 100 ms rolling inactivity window. Each new qualifying signal resets that window, and the action completes after 100 ms without another qualifying signal.

If tracked HTTP requests remain pending when the rolling inactivity window ends, Faro halts the action while those requests drain. The action completes as soon as all pending tracked requests finish, or when the fixed 10-second drain timeout expires. The drain timeout isn’t configurable.

The user action completion event includes timing attributes such as `userActionStartTime`, `userActionEndTime`, and `userActionDuration`.

## Configure user action instrumentation

User action instrumentation is enabled by default in the Faro Web SDK. If you use custom instrumentation, manually include `UserActionInstrumentation`:

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

```javascript
import { UserActionInstrumentation } from '@grafana/faro-web-sdk';

const instrumentations = [
  // ...other instrumentations
  new UserActionInstrumentation(),
];
```

### Set the initial activity timeout

The initial activity timeout defaults to 100 ms. To configure it globally, set `initialActivityTimeout` in `userActionsInstrumentation`:

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

```javascript
initializeFaro({
  // ...other configuration
  userActionsInstrumentation: {
    initialActivityTimeout: 500,
  },
});
```

Faro resolves the effective initial activity timeout in this order:

1. The element override or the `startUserAction` API override
2. The global `userActionsInstrumentation.initialActivityTimeout` setting
3. The default of 100 ms

Timeout values must be finite and greater than zero. Faro handles other values as follows:

- For an invalid element or API override, Faro logs a warning and uses the global setting, or the default if no valid global setting exists.
- For an invalid global setting, Faro logs a warning and uses the default of 100 ms.
- For a value greater than 1,000 ms, Faro logs a warning and clamps the value to 1,000 ms.

The effective timeout controls the user action lifecycle in the browser. Faro doesn’t include it in emitted telemetry.

### Troubleshoot canceled user actions

If Faro cancels a user action because the initial activity timeout expires before a qualifying signal occurs, you can enable verbose internal logging to see the cancellation in the browser console:

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

```javascript
import { initializeFaro, InternalLoggerLevel } from '@grafana/faro-web-sdk';

initializeFaro({
  // ...other configuration
  internalLoggerLevel: InternalLoggerLevel.VERBOSE,
});
```

The SDK writes `User action not sent; no DOM, resource, or HTTP activity: <action-name>` to `console.debug`. This message isn’t sent as telemetry. Verbose logging also enables other internal SDK debug messages, so enable it only while troubleshooting.

### Customize declarative attributes

The `dataAttributeName` option accepts either a complete HTML `data-*` attribute or a camelCase dataset key. Faro normalizes either form to an HTML `data-*` attribute.

Faro derives the timeout attribute from the normalized action attribute. If the action attribute ends in `-name`, Faro replaces that suffix with `-timeout`. Otherwise, Faro appends `-timeout`.

The exported `userActionTimeoutDataAttribute` constant represents only the default `data-faro-user-action-timeout` attribute. When you customize `dataAttributeName`, use the derived timeout attribute instead.

Expand table

| `dataAttributeName` value                         | Action attribute           | Timeout attribute             |
|---------------------------------------------------|----------------------------|-------------------------------|
| `data-product-action-name` or `productActionName` | `data-product-action-name` | `data-product-action-timeout` |
| `data-product-action` or `productAction`          | `data-product-action`      | `data-product-action-timeout` |

For example, configure an action attribute that ends in `-name`:

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

```javascript
initializeFaro({
  // ...other configuration
  userActionsInstrumentation: {
    dataAttributeName: 'productActionName',
  },
});
```

Then use the normalized action attribute and its derived timeout attribute in HTML:

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

```html
<button data-product-action-name="save" data-product-action-timeout="500">Save</button>
```

For an action attribute that doesn’t end in `-name`, configure `dataAttributeName: 'data-product-action'` and use these attributes:

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

```html
<button data-product-action="save" data-product-action-timeout="500">Save</button>
```

## Start a user action manually

Use the `startUserAction` method for programmatic control and customization:

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

```typescript
startUserAction(
  name: string,
  attributes?: Record<string, string>,
  options?: StartUserActionOptions
): UserActionInterface | undefined
```

### Parameters

Expand table

| Name                             | Type                                  | Description                                                                                  |
|----------------------------------|---------------------------------------|----------------------------------------------------------------------------------------------|
| `name`                           | `string`                              | The name of the user action.                                                                 |
| `attributes`                     | `Record<string, string>` *(optional)* | Additional attributes to include in the user action completion event.                        |
| `options.triggerName`            | `string` *(optional)*                 | Describes the action origin. Defaults to `faroApiCall` for manually created actions.         |
| `options.importance`             | `'normal' | 'critical'` *(optional)*  | Sets the importance level. Defaults to `'normal'`.                                           |
| `options.initialActivityTimeout` | `number` *(optional)*                 | Overrides the global initial activity timeout for this action. The value is in milliseconds. |

### Return value

The method returns a `UserActionInterface` when it starts the action. If another user action is already active, Faro logs an error and returns `undefined`.

For example, start an action with custom attributes and a 500 ms initial activity timeout:

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

```javascript
const attributes = {
  cartSize: '3',
  paymentMethod: 'card',
};

faro.api.startUserAction('checkout', attributes, {
  triggerName: 'customEvent',
  initialActivityTimeout: 500,
});
```

## Follow user action best practices

- Use descriptive action names to make filtering and analysis easier.
- Attach relevant attributes to actions for more context, for example, the control name and page context.
- For highly custom interactions, use `startUserAction` to start actions manually.
- In a single-page application (SPA), increase the initial activity timeout only when delayed rendering or asynchronous work can cause the first qualifying signal to occur after 100 ms. Keep the timeout as short as practical.
