---
title: Best Practices for Creating SLOs for RUM Operations
description: Learn how to create availability and latency SLOs from RUM operation metrics.
breadcrumbs: >-
  Docs > RUM & Session Replay > Real User Monitoring & Session Replay Guides >
  Best Practices for Creating SLOs for RUM Operations
---

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# Best Practices for Creating SLOs for RUM Operations

## Overview{% #overview %}

[RUM operations](https://docs.datadoghq.com/real_user_monitoring/operations_monitoring.md?tab=browser) measure the availability and latency of technical steps in a [user journey](https://docs.datadoghq.com/journey_monitoring.md). For example, an operation can track whether a checkout request succeeds and how long the request takes to complete.

Use two operation metrics to create [metric-based SLOs](https://docs.datadoghq.com/service_level_objectives/metric.md):

- Use `rum.measure.operation` to create an **availability SLO** based on the operation's success rate.
- Use `rum.measure.operation.duration` to create a **latency SLO** based on the operation's time to completion.

Both metrics include `operation.name`, `operation.status`, `operation.failure_reason`, and `application.id` tags, which you use to define the SLO queries.

Create separate availability and latency SLOs to measure these distinct aspects of operation health.

## Prerequisites{% #prerequisites %}

- [RUM without Limits](https://docs.datadoghq.com/real_user_monitoring/rum_without_limits.md) is enabled for your organization.
- You have [configured at least one RUM operation](https://docs.datadoghq.com/real_user_monitoring/guide/best-practices-for-operations-setup.md).

## Understand operation outcomes{% #understand-operation-outcomes %}

How you handle each operation outcome depends on what the SLO measures:

| Outcome                | Availability SLO | Latency SLO                                  |
| ---------------------- | ---------------- | -------------------------------------------- |
| Success                | Good event       | Good at or below the threshold; bad above it |
| Error or other failure | Bad event        | Excluded                                     |
| Abandonment            | Excluded         | Bad above the threshold; otherwise excluded  |
| Timeout                | Bad event        | Excluded                                     |

**Availability SLOs exclude abandonments** because a user who leaves before an operation finishes has not necessarily experienced a technical failure. **Latency SLOs include abandonments** only when their duration exceeds the threshold. This treatment also prevents an abandonment from counting against both SLOs.

**Availability SLOs include timeouts** as failed events to maintain parity with other operation failures and avoid hiding potential problems in paths that do not record an operation end. **Latency SLOs exclude timeouts** because RUM records the operation start but not its end, so the duration does not reliably measure application performance.

## Navigate to SLO creation{% #navigate-to-slo-creation %}

You can open the SLO creation workflow from RUM or from the SLO page.

### Navigate from RUM{% #navigate-from-rum %}

Starting from the operation report is more convenient because Datadog uses the selected operation to initialize the SLO query. Starting from the SLO page requires you to build the operation query from scratch.

1. Go to **RUM > Performance Monitoring > Operations**.
1. Select an operation from the catalog.
1. In the SLOs section at the top of the operation report, click Create.
1. Select the type of SLO to create.

### Navigate from the SLO page{% #navigate-from-the-slo-page %}

1. In the left navigation, select **Monitoring > SLOs**.
1. Click 
   - New SLO
, then select By Count.

After you open the SLO creation workflow, configure the SLO query for an availability or latency SLO.

## Configure the SLO query{% #configure-the-slo-query %}

Choose the query that corresponds to the type of SLO you want to create. Replace `<OPERATION_NAME>` with the operation name and `<APPLICATION_ID>` with the RUM application ID.

### Availability SLO{% #availability-slo %}

An availability SLO measures whether the operation completes successfully:

- **Good events** include successful operations.
- **Bad events** include failed operations other than abandonments.

{% image
   source="https://docs.dd-static.net/images/real_user_monitoring/guide/operations-monitoring/operations-monitoring-availability-slo-example.8a028ff9f4869326d31a686bfcbf5196.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/real_user_monitoring/guide/operations-monitoring/operations-monitoring-availability-slo-example.8a028ff9f4869326d31a686bfcbf5196.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="Create SLO page showing a count-based availability SLO with good and bad event queries and preview graphs" /%}

Use this raw query for good events:

```text
sum:rum.measure.operation{operation.name:<OPERATION_NAME> AND application.id:<APPLICATION_ID> AND operation.status:success}.as_count()
```

Use this raw query for bad events:

```text
sum:rum.measure.operation{operation.name:<OPERATION_NAME> AND application.id:<APPLICATION_ID> AND operation.status:failure AND NOT operation.failure_reason:abandoned}.as_count()
```

The SLO calculates availability as `successful operations / (successful operations + non-abandoned failures)`.

### Latency SLO{% #latency-slo %}

A latency SLO measures whether the operation completes within an acceptable duration. Choose a threshold based on the expected user experience and the operation's observed duration. For example, if users expect a checkout submission to complete within three seconds, use a three-second threshold.

{% image
   source="https://docs.dd-static.net/images/real_user_monitoring/guide/operations-monitoring/operations-monitoring-latency-slo-example.ea08d6d429a074af9d8cfcf1dc337f98.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/real_user_monitoring/guide/operations-monitoring/operations-monitoring-latency-slo-example.ea08d6d429a074af9d8cfcf1dc337f98.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="Create SLO page showing a count-based latency SLO with good and bad event queries and preview graphs" /%}

The `rum.measure.operation.duration` metric uses nanoseconds. Multiply seconds by `1,000,000,000` to convert the threshold to nanoseconds. For example, three seconds equals `3,000,000,000` nanoseconds.

Replace `<LATENCY_THRESHOLD_NS>` with the threshold in nanoseconds, then configure the following events:

- **Good events** include successful operations at or below the threshold.
- **Bad events** include successful and abandoned operations above the threshold.

Use this raw query for good events:

```text
count(v: v<=<LATENCY_THRESHOLD_NS>):rum.measure.operation.duration{operation.name:<OPERATION_NAME> AND application.id:<APPLICATION_ID> AND operation.status:success}.as_count()
```

Define bad events as the sum of these two raw queries:

```text
count(v: v><LATENCY_THRESHOLD_NS>):rum.measure.operation.duration{operation.name:<OPERATION_NAME> AND application.id:<APPLICATION_ID> AND operation.status:success}.as_count()
```

```text
count(v: v><LATENCY_THRESHOLD_NS>):rum.measure.operation.duration{operation.name:<OPERATION_NAME> AND application.id:<APPLICATION_ID> AND operation.status:failure AND operation.failure_reason:abandoned}.as_count()
```

The SLO calculates latency as `fast successful operations / (all successful operations + slow abandoned operations)`.

### Complete the SLO{% #complete-the-slo %}

After you configure the availability or latency query:

1. Start with a target of 99% over a 30-day rolling window for a critical user journey. Adjust the target based on the journey's reliability requirements and historical performance.
1. Apply the same scope, filters, and groups to every query.
1. Add a descriptive name and optional tags.
1. Save the SLO.

## Validate the SLOs{% #validate-the-slos %}

Validate the SLOs after you create them:

1. Confirm that the good and bad event queries do not overlap.
1. Verify that all queries use the same operation scope, filters, and groups.
1. Compare SLO event counts with the operation volume on the Operations page.
1. Review [timed-out operations](https://docs.datadoghq.com/real_user_monitoring/operations_monitoring.md?tab=browser#parallelization) (see the note under **Parallelization**). A high timeout rate can indicate that some application paths start an operation without recording its end.
1. Confirm that the latency threshold uses nanoseconds and represents an acceptable completion time for the operation.

## Further reading{% #further-reading %}

Additional helpful documentation, links, and articles:

- [Best practices for setting up RUM operations](https://docs.datadoghq.com/real_user_monitoring/guide/best-practices-for-operations-setup.md)
- [Learn about Operations Monitoring](https://docs.datadoghq.com/real_user_monitoring/operations_monitoring.md?tab=browser)
- [Create metric-based SLOs](https://docs.datadoghq.com/service_level_objectives/metric.md)
- [Learn about Journey Monitoring](https://docs.datadoghq.com/journey_monitoring.md)
