Loading

Create a rule and observe the alert lifecycle

In this tutorial, you'll use the experimental alerting system to detect a real-world performance problem and watch what happens next. You'll see how the system decides when a condition is serious enough to open an alert, how it tracks that alert over time, and how it closes automatically when things return to normal, without any manual intervention.

Here's what you'll do:

  1. Load sample data - Create an index and populate it with synthetic latency data that moves through healthy, degraded, and recovered phases. This gives you a realistic dataset to work with without needing a live service.
  2. Write a detection query - Use the query sandbox to build and preview an ES|QL query that computes P95 latency and flags breaches. The sandbox lets you verify the logic before the rule ever runs.
  3. Configure the rule - Set the alert condition, schedule, lookback window, and recovery behavior. You'll see how each setting shapes the alert lifecycle.
  4. Confirm the rule is running - Check the Execution history page to see that the rule is evaluating on schedule and its runs are succeeding.
  5. Watch the episode open and recover - Open the alert episode's details page to watch the episode move from pending to active as the breach persists, then close automatically when the degraded data ages out of the lookback window, or immediately if you force recovery.

Before you start, make sure you have the following:

  • One of the following deployment types:

  • The experimental alerting system enabled: The experimental alerting system must be turned on in your space before you can use any of its features. Refer to Set up the experimental alerting system for instructions.

  • The required access: Your role must give you access to:

    Task Required privilege
    Create and manage rules Rules: All (under Alerting)
    View and triage alert episodes Alerts: Read (under Alerting); also automatically grants Elasticsearch read access to .rule-events, no separate index privilege needed
    Review execution history Execution history: Read (under Alerting)
    Create the tutorial index and load sample data create_index and write index privileges on checkout-service-logs

Before creating the rule, set up the index and load the sample data it will query.

  1. Create the index

    Run the following in Dev Tools to create the index that your rule will query. Unlike data streams, this index requires explicit creation because it uses a custom mapping.

    PUT checkout-service-logs
    {
      "mappings": {
        "properties": {
          "@timestamp": { "type": "date" },
          "service.name": { "type": "keyword" },
          "transaction.name": { "type": "keyword" },
          "latency_ms": { "type": "float" }
        }
      }
    }
    		

    Confirm the response shows "acknowledged": true before proceeding.

  2. Load the sample data

    Expand the drop-down below to copy the full bulk request, then run it in Dev Tools. It populates the index with synthetic latency data for a checkout service covering three phases, all within a single hour:

    • Healthy (:00:15): P95 well under 2 seconds
    • Degraded (:16:30): P95 well over 2 seconds across 3 consecutive 5-minute windows
    • Recovered (:31:40): P95 returns to healthy levels

    The response should show errors: false for all documents.

    Note

    The timestamps are fixed to 2026-07-02T21. Before running this request, replace 2026-07-02T21 with today's date and the current UTC hour in YYYY-MM-DDTHH format (for example, 2026-07-14T09), keeping the minutes and seconds unchanged.

    The rule can only see data that's already in the past, so each phase won't appear until real time reaches its minute mark.

You'll build a rule that detects when P95 latency for a service exceeds 2 seconds. The rule queries the synthetic data you just loaded, so you can see the breach and recovery cycle play out in real time.

  1. Open the rule editor

    Go to Alerting v2 preview using the navigation menu or the global search field. From the Rules page, select the option to create an ES|QL rule.

  2. Write and test the detection query

    1. Paste the following ES|QL query into the Query sandbox. It finds the slowest 5% of requests for each service (P95 latency), labels how severe that is, and keeps only the services where that value is above 2 seconds. You don't need to add a time filter yourself: the sandbox and the rule both apply one automatically based on the date range or schedule you choose.

      FROM checkout-service-logs
      | STATS p95_latency_ms = PERCENTILE(latency_ms, 95) BY service.name
      | EVAL severity = CASE(
          p95_latency_ms >= 4000, "critical",
          p95_latency_ms >= 2000, "high",
          "low"
        )
      | WHERE p95_latency_ms > 2000
      		
    2. Set the sandbox date range to the Today preset (from the Commonly used list) and run the query. Today covers the full calendar day, so it finds the sample data no matter what time it is right now.

    3. Confirm the query results. You should see one row for service.name: checkout with p95_latency_ms above 2000 and severity: high or critical.

    4. Select Apply changes to populate the rule form, then select Next.

      Note

      The sandbox time controls set the preview range only. They don't carry over to the rule's schedule or lookback window once the rule is running.

  3. Configure the alert condition

    The query you applied from the sandbox auto-fills Mode, Time field, and Group fields. Set the remaining fields:

    • Set Alert delay to Breaches: 2. The breach must persist across 2 consecutive evaluations before the episode moves to active.
    • Set Schedule to every 5 minutes.
    • Set Lookback Window to the last 45 minutes. This ensures the rule can reach the pre-loaded sample data regardless of when you complete the tutorial. Unlike the sandbox, this is always a relative range; it can't use an absolute range like Today. Go ahead and finish configuring and saving the rule; see Observe the episode lifecycle for when the episode will actually appear.

    Select Next.

  4. Configure the recovery condition

    Confirm the default settings:

    • Recovery: Default recovery
    • Recovery delay: Immediate (no delay, recovers on first non-breach)

    These default settings will produce the automatic recovery behavior this tutorial demonstrates. As soon as a scheduled run returns no breaching rows, the episode will close.

    Select Next.

  5. Name and save the rule

    1. On the Details & Artifacts step, enter the following:

      • Name: Checkout Service Latency
      • Description: Detects when P95 latency for the checkout service exceeds 2 seconds. Groups by service name and assigns severity: critical at 4 seconds, high at 2 seconds.

      Select Next.

    2. On the Actions step, do not create an action policy (rules can run without notifications or an action policy configured). Select Create rule to create and enable the rule.

The sandbox showed that your query can find a breach. This step confirms the rule is actually running on schedule. The Execution history page gives you a real-time log of every rule run and its outcome.

  1. Open Execution history

    Open Execution history using the navigation menu or the global search field.

  2. Select the rule

    On the Rules tab, select Checkout Service Latency.

  3. Wait for an execution

    Wait one schedule interval (5 minutes) after saving the rule, then check the table for a recent entry.

  4. Confirm success

    Confirm the Response column shows success and the Timestamp matches a recent time. If no entries appear, confirm at least one 5-minute interval has elapsed since you saved the rule.

With the rule running, you can watch the full alert lifecycle play out on the Alerts page and in the episode's details page. It stays active until the recovery condition is met.

  1. Open the Alerts page

    Open Alerting v2 preview using the navigation menu or the global search field, then go to the Alerts page.

  2. Find the episode

    The episode won't appear until the current UTC time passes 16 minutes past the hour, which is the start of the degraded window. After the first two evaluations following that point (about 10 minutes), you'll see an episode appear and move from pending to active.

  3. Inspect the episode details

    Select the episode to open its details. Use the metric trend to see how P95 latency compared to the threshold over the episode's lifetime, and confirm the grouping value (checkout) that triggered it.

  4. (Optional) Force recovery immediately

    Rather than waiting about 45 minutes for the degraded data to age out of the lookback window naturally, run the following in Dev Tools to rewrite the degraded documents' latency_ms values to a healthy level:

    POST checkout-service-logs/_update_by_query
    {
      "query": {
        "range": { "latency_ms": { "gt": 2000 } }
      },
      "script": {
        "source": "ctx._source.latency_ms = 300"
      }
    }
    		

    This rewrites the degraded documents to a healthy latency value, so the next scheduled run (within 5 minutes) finds no breaching rows and moves the episode to inactive. Go to the Alerts page and open the episode's details again to confirm.

By completing this tutorial, you learned:

  • Rules - A rule's schedule and lookback window control how often it evaluates and how much history each evaluation considers.
  • Severity tiers - An ES|QL CASE() expression can classify each breach by severity, and those labels are recorded in .rule-events and shown on the episode's details page.
  • Episode lifecycle - Alert delay requires a breach to persist across consecutive evaluations before an episode opens, so transient spikes don't trigger it.
  • Automatic recovery - Default recovery closes an episode as soon as a scheduled run finds no breaching rows, whether the underlying data ages out of the lookback window or the condition itself resolves.