# series_multiply



The `series_multiply` function performs element-wise multiplication between two numeric dynamic arrays (series). Each element in the first series is multiplied by the corresponding element at the same position in the second series.

You can use `series_multiply` when you need to scale time-series data, apply weights, or combine multiple metrics through multiplication. This is particularly useful for calculating weighted scores, applying normalization factors, or computing products of related measurements.

## Usage [#usage]

### Syntax [#syntax]

```kusto
series_multiply(series1, series2)
```

### Parameters [#parameters]

| Parameter | Type    | Description                        |
| --------- | ------- | ---------------------------------- |
| `series1` | dynamic | A dynamic array of numeric values. |
| `series2` | dynamic | A dynamic array of numeric values. |

### Returns [#returns]

A dynamic array where each element is the result of multiplying the corresponding elements of `series1` and `series2`. If the arrays have different lengths, the shorter array is extended with `null` values.

## Use case examples [#use-case-examples]

<Tabs>
  <Tab title="Log analysis">
    In log analysis, you can use `series_multiply` to apply weighting factors to request durations, calculating weighted performance metrics.

    **Query**

    ```kusto
    ['sample-http-logs']
    | summarize durations = make_list(req_duration_ms) by ['geo.city']
    | extend weights = dynamic([1.0, 1.2, 0.8, 1.1, 0.9])
    | extend weighted_durations = series_multiply(durations, weights)
    | take 5
    ```

    [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%20durations%20%3D%20make_list\(req_duration_ms\)%20by%20%5B'geo.city'%5D%20%7C%20extend%20weights%20%3D%20dynamic\(%5B1.0%2C%201.2%2C%200.8%2C%201.1%2C%200.9%5D\)%20%7C%20extend%20weighted_durations%20%3D%20series_multiply\(durations%2C%20weights\)%20%7C%20take%205%22%7D)

    **Output**

    | geo.city | durations             | weights                    | weighted\_durations         |
    | -------- | --------------------- | -------------------------- | --------------------------- |
    | Seattle  | \[50, 60, 55, 58, 52] | \[1.0, 1.2, 0.8, 1.1, 0.9] | \[50, 72, 44, 63.8, 46.8]   |
    | Portland | \[45, 50, 48, 52, 47] | \[1.0, 1.2, 0.8, 1.1, 0.9] | \[45, 60, 38.4, 57.2, 42.3] |

    This query applies priority weights to request durations, emphasizing certain time periods or request types in performance analysis.
  </Tab>

  <Tab title="OpenTelemetry traces">
    In OpenTelemetry traces, you can use `series_multiply` to calculate resource cost estimates by multiplying span durations with cost factors.

    **Query**

    ```kusto
    ['otel-demo-traces']
    | extend duration_ms = duration / 1ms
    | summarize durations = make_list(duration_ms) by ['service.name']
    | extend cost_factor = dynamic([0.001, 0.001, 0.001, 0.001, 0.001])
    | extend estimated_cost = series_multiply(durations, cost_factor)
    | take 5
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D%20%7C%20extend%20duration_ms%20%3D%20duration%20%2F%201ms%20%7C%20summarize%20durations%20%3D%20make_list\(duration_ms\)%20by%20%5B'service.name'%5D%20%7C%20extend%20cost_factor%20%3D%20dynamic\(%5B0.001%2C%200.001%2C%200.001%2C%200.001%2C%200.001%5D\)%20%7C%20extend%20estimated_cost%20%3D%20series_multiply\(durations%2C%20cost_factor\)%20%7C%20take%205%22%7D)

    **Output**

    | service.name | durations                  | cost\_factor                         | estimated\_cost                  |
    | ------------ | -------------------------- | ------------------------------------ | -------------------------------- |
    | frontend     | \[100, 120, 95, 110, 105]  | \[0.001, 0.001, 0.001, 0.001, 0.001] | \[0.1, 0.12, 0.095, 0.11, 0.105] |
    | checkout     | \[200, 220, 195, 210, 205] | \[0.001, 0.001, 0.001, 0.001, 0.001] | \[0.2, 0.22, 0.195, 0.21, 0.205] |

    This query multiplies span durations by a cost factor to estimate resource costs, useful for cost optimization analysis.
  </Tab>

  <Tab title="Security logs">
    In security logs, you can use `series_multiply` to calculate risk scores by multiplying request frequencies with severity factors.

    **Query**

    ```kusto
    ['sample-http-logs']
    | summarize request_counts = make_list(req_duration_ms) by status
    | extend severity = dynamic([1.0, 3.0, 2.0, 5.0, 4.0])
    | extend risk_scores = series_multiply(request_counts, severity)
    | take 5
    ```

    [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%20request_counts%20%3D%20make_list\(req_duration_ms\)%20by%20status%20%7C%20extend%20severity%20%3D%20dynamic\(%5B1.0%2C%203.0%2C%202.0%2C%205.0%2C%204.0%5D\)%20%7C%20extend%20risk_scores%20%3D%20series_multiply\(request_counts%2C%20severity\)%20%7C%20take%205%22%7D)

    **Output**

    | status | request\_counts       | severity                   | risk\_scores             |
    | ------ | --------------------- | -------------------------- | ------------------------ |
    | 200    | \[50, 55, 48, 52, 49] | \[1.0, 3.0, 2.0, 5.0, 4.0] | \[50, 165, 96, 260, 196] |
    | 401    | \[10, 12, 8, 15, 11]  | \[1.0, 3.0, 2.0, 5.0, 4.0] | \[10, 36, 16, 75, 44]    |

    This query multiplies request metrics by severity factors to calculate weighted risk scores for security analysis.
  </Tab>
</Tabs>

## List of related functions [#list-of-related-functions]

* [series\_subtract](/apl/scalar-functions/time-series/series-subtract): Performs element-wise subtraction of two series. Use when you need to subtract values instead of multiplying them.
* [series\_pow](/apl/scalar-functions/time-series/series-pow): Raises series elements to a power. Use when you need exponentiation instead of multiplication.
* [series\_sum](/apl/scalar-functions/time-series/series-sum): Returns the sum of all values in a series. Use to aggregate the results after multiplication.
* [series\_abs](/apl/scalar-functions/time-series/series-abs): Returns absolute values of elements. Use when you need magnitude without direction.

## Other query languages [#other-query-languages]

<LanguageComparisons>
  <Accordion title="Splunk SPL users">
    In Splunk SPL, you typically use the `eval` command with the multiplication operator to calculate products between fields. In APL, `series_multiply` operates on entire arrays at once, performing element-wise multiplication efficiently.

    <CodeGroup>
      ```sql Splunk example
      ... | eval product=value1 * value2
      ```

      ```kusto APL equivalent
      datatable(series1: dynamic, series2: dynamic)
      [
        dynamic([10, 20, 30]), dynamic([2, 3, 4])
      ]
      | extend product = series_multiply(series1, series2)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="ANSI SQL users">
    In SQL, you multiply values using the `*` operator on individual columns. In APL, `series_multiply` performs element-wise multiplication across entire arrays stored in single columns.

    <CodeGroup>
      ```sql SQL example
      SELECT value1 * value2 AS product
      FROM measurements;
      ```

      ```kusto APL equivalent
      datatable(series1: dynamic, series2: dynamic)
      [
        dynamic([10, 20, 30]), dynamic([2, 3, 4])
      ]
      | extend product = series_multiply(series1, series2)
      ```
    </CodeGroup>
  </Accordion>
</LanguageComparisons>
