> ## Documentation Index
> Fetch the complete documentation index at: https://axiom.co/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# arg_max

> This page explains how to use the arg_max aggregation in APL.

The `arg_max` aggregation in APL helps you identify the row with the maximum value for an expression and return additional fields from that record. Use `arg_max` when you want to determine key details associated with a row where the expression evaluates to the maximum value. If you group your data, `arg_max` finds the row within each group where a particular expression evaluates to the maximum value.

This aggregation is particularly useful in scenarios like the following:

* Pinpoint the slowest HTTP requests in log data and retrieve associated details (like URL, status code, and user agent) for the same row.
* Identify the longest span durations in OpenTelemetry traces with additional context (like span name, trace ID, and attributes) for the same row.
* Highlight the highest severity security alerts in logs along with relevant metadata (such as alert type, source, and timestamp) for the same row.

## For users of other query languages

If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.

<AccordionGroup>
  <Accordion title="Splunk SPL users">
    Splunk SPL doesn’t have an equivalent to `arg_max`. You can use `stats` with a combination of `max` and `by` clauses to evaluate the maximum value of a single numberic field. APL provides a dedicated `arg_max` aggregation that evaluates expressions.

    <CodeGroup>
      ```sql Splunk example theme={null}
      | stats max(req_duration_ms) as max_duration by id, uri
      ```

      ```kusto APL equivalent theme={null}
      ['sample-http-logs']
      | summarize arg_max(req_duration_ms, id, uri)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="ANSI SQL users">
    In ANSI SQL, you typically use a subquery to find the maximum value and then join it back to the original table to retrieve additional fields. APL’s `arg_max` provides a more concise and efficient alternative.

    <CodeGroup>
      ```sql SQL example theme={null}
      WITH MaxValues AS (
          SELECT id, MAX(req_duration_ms) as max_duration
          FROM sample_http_logs
          GROUP BY id
      )
      SELECT logs.id, logs.uri, MaxValues.max_duration
      FROM sample_http_logs logs
      JOIN MaxValues
      ON logs.id = MaxValues.id;
      ```

      ```kusto APL equivalent theme={null}
      ['sample-http-logs']
      | summarize arg_max(req_duration_ms, id, uri)
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Usage

### Syntax

```kusto theme={null}
| summarize arg_max(expression, field1[, field2, ...])
```

### Parameters

| Parameter        | Description                                                                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `expression`     | The expression whose maximum value determines the selected record.                                                                         |
| `field1, field2` | The additional fields to retrieve from the record with the maximum numeric value. Use `*` as a wildcard to return all fields from the row. |

<Note>
  The wildcard `*` is useful to return all fields from the row with the maximum value, but it increases query complexity and decreases performance.
</Note>

### Returns

Returns a row where the expression evaluates to the maximum value for each group (or the entire dataset if no grouping is specified), containing the fields specified in the query.

### Name fields

You can name fields in the parameters of `arg_max` using the syntax `arg_max(name1=expression, name2=field1)`. This specifies the field names that appear in the output.

**Query**

```kusto theme={null}
['otel-demo-traces']
| summarize arg_max(duration, longestSpan=span_id), arg_max(numEvents=array_length(events), spanWithMostEvents=span_id)
```

[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D%20%7C%20summarize%20arg_max\(duration%2C%20longestSpan%3Dspan_id\)%2C%20arg_max\(numEvents%3Darray_length\(events\)%2C%20spanWithMostEvents%3Dspan_id\)%22%7D)

**Output**

| duration       | longestSpan      | numEvents | spanWithMostEvents |
| -------------- | ---------------- | --------- | ------------------ |
| 5m0.004487127s | 1a9f979bb25f6bbd | 408       | db13ffc3394905b5   |

## Use case examples

<Tabs>
  <Tab title="Log analysis">
    Find the slowest path for each HTTP method in the `['sample-http-logs']` dataset.

    **Query**

    ```kusto theme={null}
    ['sample-http-logs']
    | summarize arg_max(req_duration_ms, uri) by method
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20summarize%20arg_max\(req_duration_ms%2C%20uri\)%20by%20method%22%7D)

    **Output**

    | uri           | method | req\_duration\_ms |
    | ------------- | ------ | ----------------- |
    | /home         | GET    | 1200              |
    | /api/products | POST   | 2500              |

    This query identifies the slowest path for each HTTP method.
  </Tab>

  <Tab title="OpenTelemetry traces">
    Identify the span with the longest duration for each service in the `['otel-demo-traces']` dataset.

    **Query**

    ```kusto theme={null}
    ['otel-demo-traces']
    | summarize arg_max(duration, span_id, trace_id) by ['service.name']
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D%20%7C%20summarize%20arg_max\(duration%2C%20span_id%2C%20trace_id\)%20by%20%5B'service.name'%5D%22%7D)

    **Output**

    | service.name    | span\_id | trace\_id | duration |
    | --------------- | -------- | --------- | -------- |
    | frontend        | span123  | trace456  | 3s       |
    | checkoutservice | span789  | trace012  | 5s       |

    This query identifies the span with the longest duration for each service, returning the `span_id`, `trace_id`, and `duration`.
  </Tab>

  <Tab title="Security logs">
    Find the highest status code for each country in the `['sample-http-logs']` dataset.

    **Query**

    ```kusto theme={null}
    ['sample-http-logs']
    | summarize arg_max(toint(status), uri) by ['geo.country']
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20summarize%20arg_max\(toint\(status\)%2C%20uri\)%20by%20%5B'geo.country'%5D%22%7D)

    **Output**

    | geo.country | uri        | status |
    | ----------- | ---------- | ------ |
    | USA         | /admin     | 500    |
    | Canada      | /dashboard | 503    |

    This query identifies the URI with the highest status code for each country.
  </Tab>
</Tabs>

## List of related aggregations

* [arg\_min](/apl/aggregation-function/arg-min): Retrieves the record with the minimum value for a numeric field.
* [max](/apl/aggregation-function/max): Retrieves the maximum value for a numeric field but doesn’t return additional fields.
* [percentile](/apl/aggregation-function/percentile): Provides the value at a specific percentile of a numeric field.
