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

# Cooldown

> Define minimum rest periods between shifts for employees.

export const CooldownMetricRows = () => <>
    <tr>
      <td><code className="whitespace-nowrap">COOLDOWN.MISSING_DAYS</code></td>
      <td>Total number of required cooldown days that are missing.</td>
    </tr>
    <tr>
      <td><code className="whitespace-nowrap">COOLDOWN.MISSING_MINUTES</code></td>
      <td>Total number of required cooldown minutes that are missing.</td>
    </tr>
    <tr>
      <td><code className="whitespace-nowrap">COOLDOWN.VIOLATIONS</code></td>
      <td>Number of cooldowns that are shorter than required.</td>
    </tr>
  </>;

This rule allows you to enforce minimum rest periods between different types of work. It works by defining what triggers a cooldown (`starts`) and what should be avoided during that cooldown period (`ends`). This is useful for ensuring employees have adequate rest between demanding shifts, preventing burnout, and complying with labor regulations.

<Card title="Rule schema">
  <ResponseField name="cooldownRule" type="object">
    Used to define required or desired rest between working shifts.

    <Expandable title="properties">
      <ResponseField name="id" type="string" required>
        Unique identifier for the rule.
      </ResponseField>

      <ResponseField name="labels" type="array of string">
        Labels for the rule. Labels can be used to group rules together. For example, if multiple rules are related to the same shift type, they can all be labeled with the same label.
      </ResponseField>

      <ResponseField name="importance" type="string (enum: NONE | VERY_LOW | LOW | MEDIUM | HIGH | ...)" required>
        The importance of the rule. The higher the importance, the more it will be taking the rule into account. Under strict importance, the rule may never be violated.
      </ResponseField>

      <ResponseField name="filters" type="object">
        Filters to determine the scope of the rule. Used to decide which employees and which work the rule should be applied to.
      </ResponseField>

      <Expandable title="filters – properties">
        <ResponseField name="employees" type="object">
          Used to filter which employees the rule should be applied to. If not specified, the rule applies to all employees.
        </ResponseField>

        <Expandable title="employees – properties">
          <ResponseField name="ids" type="array of string">
            List of employee ids that the rule should be applied to.
          </ResponseField>

          <ResponseField name="labels" type="array of string">
            List of employee labels that the rule should be applied to.
          </ResponseField>

          <ResponseField name="matchTypes" type="object" />

          <Expandable title="matchTypes – properties">
            <ResponseField name="ids" type="string (enum: NONE | ANY | ALL)">
              Used to indicate how to apply the id filters. For example, if set to NONE, entities with the specified ids will be excluded. Default: "ANY".
            </ResponseField>

            <ResponseField name="labels" type="string (enum: NONE | ANY | ALL)">
              Used to indicate how to apply the label filters. For example, if set to ANY, entities that have any of the specified labels will be included. Default: "ANY".
            </ResponseField>
          </Expandable>
        </Expandable>

        <ResponseField name="work" type="object">
          Defines filtering for specific work that the rule should be applied to. For example, it can be used to apply the rule only to work carried out in specific roles.
        </ResponseField>

        <Expandable title="work – properties">
          <ResponseField name="roles" type="object">
            Used to apply the rule only to work carried out in specific roles.
          </ResponseField>

          <Expandable title="roles – properties">
            <ResponseField name="ids" type="array of string">
              List of relevant role ids.
            </ResponseField>
          </Expandable>

          <ResponseField name="workloads" type="object">
            Used to apply the rule only to work carried out with specific workload categories.
          </ResponseField>

          <Expandable title="workloads – properties">
            <ResponseField name="categories" type="array of string">
              If specified, the shift must have at least one of the workload categories specified in this list.
            </ResponseField>
          </Expandable>
        </Expandable>
      </Expandable>

      <ResponseField name="targets" type="object" required>
        Defines the desired minimum duration of the cooldown. Can be defined in either hours or days.
      </ResponseField>

      <Expandable title="targets – properties">
        <ResponseField name="minHours" type="number">
          Minimum number of hours that the cooldown should last.
        </ResponseField>

        <ResponseField name="minDays" type="integer">
          Minimum number of days that the cooldown should last.
        </ResponseField>
      </Expandable>

      <ResponseField name="periods" type="object">
        List of periods in the schedule. Periods can be defined explicitly or through a recurrent definition (for example, to generate weeks).
      </ResponseField>

      <Expandable title="periods – properties">
        <ResponseField name="days" type="object">
          List of days in the schedule. Each day will become one period. By default, each period will last the entire day. If a startTime and/or endTime are specified, these will apply to each period.
        </ResponseField>

        <Expandable title="days – properties">
          <ResponseField name="dates" type="array of date (date)">
            List of dates in the schedule. Only allowed in CALENDAR payloads.
          </ResponseField>

          <ResponseField name="dayIndices" type="array of dayIndex">
            List of day indices in the schedule. Only allowed in RECURRING payloads.
          </ResponseField>

          <ResponseField name="daysOfWeek" type="array of dayOfWeek">
            List of days of the week. Will apply to all days in the schedule that match any of the specified weekdays.
          </ResponseField>

          <ResponseField name="startTime" type="string (time)">
            TIME ISO 8601 format hh:mm. Equivalent to the 24h format of a single day. Use 00:00 to represent midnight.
          </ResponseField>

          <ResponseField name="endTime" type="string (time)">
            TIME ISO 8601 format hh:mm. Equivalent to the 24h format of a single day. Use 00:00 to represent midnight.
          </ResponseField>
        </Expandable>

        <ResponseField name="customDefinitions" type="array of object">
          List of custom period definitions. Each custom period definition defines one period in the schedule.
        </ResponseField>

        <Expandable title="customDefinitions – item structure">
          <ResponseField name="startDay" type="object">
            Describes one day in the schedule.
          </ResponseField>

          <Expandable title="startDay – properties">
            <ResponseField name="date" type="string (date)">
              Date specified in ISO8601 format (YYYY-MM-DD). Only available in CALENDAR schedules.
            </ResponseField>

            <ResponseField name="dayIndex" type="integer">
              Day index relative to the horizon start day (starts at 0). Only available in RECURRING schedules.
            </ResponseField>
          </Expandable>

          <ResponseField name="endDay" type="object">
            Describes one day in the schedule.
          </ResponseField>

          <Expandable title="endDay – properties">
            <ResponseField name="date" type="string (date)">
              Date specified in ISO8601 format (YYYY-MM-DD). Only available in CALENDAR schedules.
            </ResponseField>

            <ResponseField name="dayIndex" type="integer">
              Day index relative to the horizon start day (starts at 0). Only available in RECURRING schedules.
            </ResponseField>
          </Expandable>

          <ResponseField name="startTime" type="string (time)">
            TIME ISO 8601 format hh:mm. Equivalent to the 24h format of a single day. Use 00:00 to represent midnight.
          </ResponseField>

          <ResponseField name="endTime" type="string (time)">
            TIME ISO 8601 format hh:mm. Equivalent to the 24h format of a single day. Use 00:00 to represent midnight.
          </ResponseField>

          <ResponseField name="applyTimeToAllDays" type="boolean">
            If true, the startTime and endTime will be applied to each individual day in the period. If false, the startTime will apply to the first day and the endTime will apply to the last day. Default: false.
          </ResponseField>
        </Expandable>

        <ResponseField name="recurrentDefinition" type="object">
          A recurrent definition to easily create a set of similar periods.
        </ResponseField>

        <Expandable title="recurrentDefinition – properties">
          <ResponseField name="daysPerPeriod" type="integer" required>
            The number of days in each period.
          </ResponseField>

          <ResponseField name="daysBetweenStarts" type="integer">
            The number of days between the start of each period. If not specified, this defaults to the value of daysPerPeriod, creating non-overlapping consecutive periods. Setting daysBetweenStarts to 1 will create a sliding window of periods.
          </ResponseField>

          <ResponseField name="startDay" type="object">
            Describes one day in the schedule.
          </ResponseField>

          <Expandable title="startDay – properties">
            <ResponseField name="date" type="string (date)">
              Date specified in ISO8601 format (YYYY-MM-DD). Only available in CALENDAR schedules.
            </ResponseField>

            <ResponseField name="dayIndex" type="integer">
              Day index relative to the horizon start day (starts at 0). Only available in RECURRING schedules.
            </ResponseField>
          </Expandable>

          <ResponseField name="endDay" type="object">
            Describes one day in the schedule.
          </ResponseField>

          <Expandable title="endDay – properties">
            <ResponseField name="date" type="string (date)">
              Date specified in ISO8601 format (YYYY-MM-DD). Only available in CALENDAR schedules.
            </ResponseField>

            <ResponseField name="dayIndex" type="integer">
              Day index relative to the horizon start day (starts at 0). Only available in RECURRING schedules.
            </ResponseField>
          </Expandable>

          <ResponseField name="startTime" type="string (time)">
            TIME ISO 8601 format hh:mm. Equivalent to the 24h format of a single day. Use 00:00 to represent midnight.
          </ResponseField>

          <ResponseField name="endTime" type="string (time)">
            TIME ISO 8601 format hh:mm. Equivalent to the 24h format of a single day. Use 00:00 to represent midnight.
          </ResponseField>

          <ResponseField name="applyTimeToAllDays" type="boolean">
            If true, the startTime and endTime will be applied to each individual day in the period. If false, the startTime will apply to the first day and the endTime will apply to the last day. Default: false.
          </ResponseField>
        </Expandable>

        <ResponseField name="labels" type="array of string">
          Provide labels to re-use periods that were defined in the configuration.
        </ResponseField>
      </Expandable>

      <ResponseField name="starts" type="object">
        Defines the types of work that will trigger a cooldown. Currently, only filters on shifts are supported as starts.
      </ResponseField>

      <Expandable title="starts – properties">
        <ResponseField name="shifts" type="object">
          Used to filter which shifts the rule should be applied to. If not specified, the rule applies to all shifts.
        </ResponseField>

        <Expandable title="shifts – properties">
          <ResponseField name="ids" type="array of string">
            List of shift ids that the rule should be applied to.
          </ResponseField>

          <ResponseField name="labels" type="array of string">
            List of shift labels that the rule should be applied to.
          </ResponseField>

          <ResponseField name="matchTypes" type="object" />

          <Expandable title="matchTypes – properties">
            <ResponseField name="ids" type="string (enum: NONE | ANY | ALL)">
              Used to indicate how to apply the id filters. For example, if set to NONE, entities with the specified ids will be excluded. Default: "ANY".
            </ResponseField>

            <ResponseField name="labels" type="string (enum: NONE | ANY | ALL)">
              Used to indicate how to apply the label filters. For example, if set to ANY, entities that have any of the specified labels will be included. Default: "ANY".
            </ResponseField>
          </Expandable>
        </Expandable>
      </Expandable>

      <ResponseField name="ends" type="object">
        Defines the types of work that should be avoided during a cooldown. Currently, only filters on shifts are supported as ends.
      </ResponseField>

      <Expandable title="ends – properties">
        <ResponseField name="shifts" type="object">
          Used to filter which shifts the rule should be applied to. If not specified, the rule applies to all shifts.
        </ResponseField>

        <Expandable title="shifts – properties">
          <ResponseField name="ids" type="array of string">
            List of shift ids that the rule should be applied to.
          </ResponseField>

          <ResponseField name="labels" type="array of string">
            List of shift labels that the rule should be applied to.
          </ResponseField>

          <ResponseField name="matchTypes" type="object" />

          <Expandable title="matchTypes – properties">
            <ResponseField name="ids" type="string (enum: NONE | ANY | ALL)">
              Used to indicate how to apply the id filters. For example, if set to NONE, entities with the specified ids will be excluded. Default: "ANY".
            </ResponseField>

            <ResponseField name="labels" type="string (enum: NONE | ANY | ALL)">
              Used to indicate how to apply the label filters. For example, if set to ANY, entities that have any of the specified labels will be included. Default: "ANY".
            </ResponseField>
          </Expandable>
        </Expandable>
      </Expandable>
    </Expandable>
  </ResponseField>
</Card>

## Basic cooldown between shifts

The simplest use case is to require a minimum rest period between any two shifts. This ensures employees have adequate time to recover between work periods. When you omit the `starts` and `ends` sections, the rule applies to all shifts.

<Tip>
  The rule below requires a minimum of 12 hours of rest between any two shifts. After an employee finishes any shift, they cannot start another shift until at least 12 hours have passed.

  ```json theme={null}
  {
    "id": "cd-min-12h-rest",
    "importance": "STRICT",
    "targets": {
      "minHours": 12
    }
  }
  ```
</Tip>

## Cooldown between specific shift types

You can define cooldowns that only apply between specific types of shifts. For example, you might want a longer cooldown after night shifts before morning shifts.

<Tip>
  The rule below requires at least 16 hours of rest after a night shift before an employee can work a morning shift. This helps ensure employees have adequate time to adjust their sleep schedule.

  ```json theme={null}
  {
    "id": "cd-night-to-morning",
    "importance": "STRICT",
    "targets": {
      "minHours": 16
    },
    "starts": {
      "shifts": {
        "labels": ["night"]
      }
    },
    "ends": {
      "shifts": {
        "labels": ["morning"]
      }
    }
  }
  ```
</Tip>

## Cooldown measured in days

Instead of specifying the cooldown in hours, you can specify it in days. This is useful for ensuring employees have full days off between certain types of work.

<Tip>
  The rule below requires at least 2 days without a shift after working a weekend shift before an employee can work another weekend shift. This helps distribute weekend work more evenly among employees.

  ```json theme={null}
  {
    "id": "cd-weekend-2-days",
    "importance": "STRICT",
    "targets": {
      "minDays": 2
    },
    "starts": {
      "shifts": {
        "labels": ["weekend"]
      }
    },
    "ends": {
      "shifts": {
        "labels": ["weekend"]
      }
    }
  }
  ```
</Tip>

## Complex cooldown scenarios

You can create more complex cooldown rules by combining different shift types in the `starts` and `ends` sections. This allows you to model sophisticated rest requirements.

<Tip>
  The rule below requires at least 48 hours of rest after working any intensive shift (like emergency shifts or long shifts) before an employee can work another intensive shift. This helps prevent employee burnout from demanding work.

  ```json theme={null}
  {
    "id": "cd-intensive-48h",
    "importance": "STRICT",
    "targets": {
      "minHours": 48
    },
    "starts": {
      "shifts": {
        "labels": ["intensive"]
      }
    },
    "ends": {
      "shifts": {
        "labels": ["intensive"]
      }
    }
  }
  ```
</Tip>

## Soft cooldown rules

While cooldown rules are often used with [`STRICT` importance](/v2/rules/index#rule-importance) to enforce mandatory rest periods, you can also use them with other [importance levels](/v2/rules/index#rule-importance) to encourage, but not strictly require, rest periods.

<Tip>
  The rule below encourages, but doesn't strictly require, at least 10 hours of rest after a night shift before an employee can work a morning shift. The solver will try to achieve this, but may violate it if necessary to satisfy other rules.

  ```json theme={null}
  {
    "id": "cd-soft-night-to-morning",
    "importance": "MEDIUM",
    "targets": {
      "minHours": 10
    },
    "starts": {
      "shifts": {
        "labels": ["night"]
      }
    },
    "ends": {
      "shifts": {
        "labels": ["morning"]
      }
    }
  }
  ```
</Tip>

## Cooldown with specific shift IDs

You can also target specific shifts by their IDs, giving you fine-grained control over which shifts trigger cooldowns and which shifts are restricted during cooldown periods.

<Tip>
  The rule below requires at least 8 hours of rest after a specific early morning shift (`shift-1`) before an employee can work a specific evening shift (`shift-2`). This is useful when you have specific shift pairs that should not be scheduled too close together.

  ```json theme={null}
  {
    "id": "cd-specific-shifts",
    "importance": "STRICT",
    "targets": {
      "minHours": 8
    },
    "starts": {
      "shifts": {
        "ids": ["shift-1"]
      }
    },
    "ends": {
      "shifts": {
        "ids": ["shift-2"]
      }
    }
  }
  ```
</Tip>

## Cooldown with filters

You can also limit a cooldown rule to apply only to work carried out in specific roles.

<Tip>
  The rule below requires a minimum of 16 hours of rest between any two shifts worked in role `role-1`. Shifts worked in other roles are not considered by this rule.

  ```json theme={null}
  {
    "id": "cd-min-16h-rest-role-1",
    "importance": "STRICT",
    "filters": {
      "work": {
        "roles": {
          "ids": ["role-1"]
        }
      }
    },
    "targets": {
      "minHours": 16
    }
  }
  ```
</Tip>

## Metrics

The following [status metrics](/v2/concepts/metrics) are available for tracking on Cooldown rules:

<table>
  <thead><tr><th>Metric key</th><th>Description</th></tr></thead>

  <tbody>
    <CooldownMetricRows />
  </tbody>
</table>
