# Goal & Constraints

Optimization goals and constraints are defined using a YAML manifest with the following structure:

{% code lineNumbers="true" %}

```yaml
goal:
  objective: "minimize"
  function:
    formula: "jvm1.response_time + jvm2.response_time"
  constraints:
    relative:
      - name: memory_used_max
        formula: jvm1.memory_used <= 80%
    absolute:
      - name: heap_used_max
        formula: jvm1.heap_used <= 3221225472
```

{% endcode %}

where:

| Field         | Type            | Value restriction                                                     | Is Required | Default value | Description                                                                                                                                                                                                       |
| ------------- | --------------- | --------------------------------------------------------------------- | ----------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `objective`   | String          | `minimize` `maximize`                                                 | Yes         |               | How Akamas should evaluate the goodness of a generated configuration: if it should consider good a configuration generated that maximizes `function`, or a configuration that minimizes it.                       |
| `function`    | Object          | It should have a structure like the one described in Goal function    | Yes         |               | The specification of the function to be evaluated to assess the goodness of a configuration generated by Akamas. This function is a function of the metrics of the different Components of the System under test. |
| `constraints` | List of objects | It should have a structure like the one described in Goal constraints | No          |               | A list of constraints on aggregated metrics of the Components of the System under test for which a generated configuration should not be considered valid.                                                        |

### Function <a href="#goal-function" id="goal-function"></a>

The `function` field of the Goal of a Study details the characteristics of the function Akamas should minimize or maximize to reach the desired performance objective.

The `function` field has the following structure:

{% code lineNumbers="true" %}

```yaml
function:
  formula: "jvm1.response_time / sqrt(x)"
  variables:
    x:
      metric: "throughput"
      labels:
        componentName: "jvm2"
      aggregation: "MAX"
```

{% endcode %}

Where:

| Field       | Type   | Value restrictions | Is required | Default value | Description                                                                                      |
| ----------- | ------ | ------------------ | ----------- | ------------- | ------------------------------------------------------------------------------------------------ |
| `formula`   | String | See formula        | Yes         |               | The mathematical expression of what to minimize or maximize to reach the objective of the Study. |
| `variables` | Object | See below          | No          |               | The specification of additional variables present in the `formula`.                              |

#### Formula <a href="#formula" id="formula"></a>

The `formula` field represents the mathematical expression of the performance objective for the Study and contains variables and operators with the following characteristics:

* Valid operators are: `+` `-` `*` `/` `^` `sqrt(variable)` `log(variable)` `max(variable1, variable2)` `min(variable1, variable2)`
* Valid variables are in the form:
  * \<component\_name>.\<metric\_name>, which correspond directly to metrics of Components of the System under test
  * \<variable\_name>, which should match variables specified in the `variables` field

Each metric that is directly or indirectly part of the formula of the function of the Goal is aggregated by default by average; more specifically, Akamas computes the average of each metric within the time window specified by the [windowing strategy](https://docs.akamas.io/akamas-docs/3.1.3/akamas-reference/construct-templates/study-template/windowing-strategy) of the Study.

#### Variables <a href="#variables" id="variables"></a>

The `variables` field contains the specification of additional variables present in the formula, variables that can offer more flexibility with respect to directly specifying each metric of each Component in the `formula`.

Notice: each subfield of variables specifies a variable with its characteristics, the name of the subfield is the name of the variable.

The variable subfield has the following structure:

| Field         | Type                     | Value restrictions                                                                    | Is required | Default value | Description                                                                                                                                                                                                               |
| ------------- | ------------------------ | ------------------------------------------------------------------------------------- | ----------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `metric`      | String                   | should match the name of a metric defined for the Components of the System under test | Yes         |               | The name of the metric of the Components of the System under test that maps to the variable.                                                                                                                              |
| `labels`      | A set of key-value pairs |                                                                                       | No          |               | A set of filters based on the values of the labels that are attached to the different data points of the `metric`. One of these labels is *componentName*, which contains the name of the Component the metric refers to. |
| `aggregation` | String                   | `MAX` `MIN` `AVG`                                                                     | No          | `AVG`         | The strategy through which data points of the `metric` should be aggregated within the window produced by the application of the selected windowing strategy. By default, an average is taken.                            |

It is possible to use the notation \<component\_name>.\<metric\_name> in the `metric` field to automatically filter the metric’s data point by that component name is applied.

## Constraints <a href="#constraints" id="constraints"></a>

The `constraints` field specifies constraints on the metrics of the components of the system under test that need to be satisfied for a configuration to be valid with respect to the defined goal.

Constraints always consider the average value of specified metrics within the time window specified by the [windowing strategy](https://docs.akamas.io/akamas-docs/3.1.3/akamas-reference/construct-templates/study-template/windowing-strategy) of the Study.

Constrainst may be absolute or relative. Absolute constraints set a fixed limit that should not be overcome. Relative constraints set a percentage value (calculated from the baseline value after the baseline experiment runs).\
Then each constraint (absolute or relative) has a name and a formula. The formula has the same syntax as the goal formula so refer to "formula" section above.

### Examples <a href="#examples" id="examples"></a>

The following example refers to a study whose goal is to optimize the throughput of a Java service (jpetstore), that is to maximize the throughput (measured as *elements\_per\_second*) while keeping errors (*error\_rate*) and latency (*avg\_duration*, *max\_duration*) under control (absolute values):

{% code lineNumbers="true" %}

```yaml
goal:
    objective: "maximize",
    function:
      formula: "jpetstore.elements_per_second"
    constraints:
      absolute:
        - name: min_elements_per_sec
          formula: jpetstore.elements_per_second > 55    
        - name: max_duration
          formula: jpetstore.max_duration < 800    
        - name: min_elements_per_sec
          formula: jpetstore.elements_per_second > 55    
        - name: error_rate
          formula: jpetstore.error_rate < 0.01
      relative:
        - name: avg_duration
          formula: jpetstore.avg_duration < 5%
```

{% endcode %}

The following example refers to a study whose goal is to optimize the memory consumption of Docker containers in a microservices application, that is to minimize the average memory consumption of Docker containers within the application of *appId*="app1" by observing memory limits, also normalizing by the maximum duration of a benchmark (container\_benchmark\_duration).

{% code lineNumbers="true" %}

```yaml
goal:
  objective: "minimize"
  function:
    formula: "containers_memory_limit/containers_benchmark_duration"
    variables:
      containers_memory_limit:
        metric: "memory_limit"
        labels:
          appId: "app1"
      containers_job_duration:
        metric: "benchmark_duration"
        labels:
          appId: "app1"
        aggregation: "MAX"
```

{% endcode %}
