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

# Time Windows

> Control when jobs can be serviced with flexible time window constraints

## Overview

Time windows define when jobs can be serviced, ensuring resources arrive within specified time ranges. This feature enables you to meet customer expectations, comply with delivery agreements, and optimize routes while respecting temporal constraints.

<Info>
  The VRP solver automatically ensures resources arrive at the beginning of time windows, eliminating early arrivals and unnecessary waiting.
</Info>

## Time Window Configuration

### Basic Structure

Each job can have multiple time windows, providing flexibility for service scheduling:

```json theme={null}
{
  "name": "delivery-123",
  "duration": 3600,
  "windows": [
    {
      "from": "2023-01-02T09:00:00",
      "to": "2023-01-02T10:00:00",
      "hard": true,
      "weight": 100
    }
  ]
}
```

### Window Properties

<ParamField body="from" type="string" required>
  Start time of the window in ISO 8601 format. The resource cannot arrive before this time.
</ParamField>

<ParamField body="to" type="string" required>
  End time of the window in ISO 8601 format. The resource must arrive before this time.
</ParamField>

<ParamField body="hard" type="boolean" default="true">
  Whether violating this window makes the solution infeasible. Hard windows must be respected.
</ParamField>

<ParamField body="weight" type="integer" default="1">
  Penalty weight applied when soft windows are violated. Higher values increase violation cost.
</ParamField>

## Complete Example

This example demonstrates time window usage with partial planning enabled, showing how some jobs may remain unassigned due to time constraints.

<Tabs>
  <Tab title="Request">
    ```json theme={null}
    {
      "resources": [
        {
          "name": "R-1",
          "shifts": [
            {
              "from": "2023-01-01T08:00:00",
              "to": "2023-01-01T17:00:00"
            },
            {
              "from": "2023-01-02T08:00:00",
              "to": "2023-01-02T17:00:00"
            }
          ]
        }
      ],
      "jobs": [
        {
          "name": "JOB-1",
          "location": {
            "latitude": 50.54963315022148,
            "longitude": 4.848855475505483
          },
          "duration": 3600,
          "windows": [
            {
              "from": "2023-01-02T09:00:00",
              "to": "2023-01-02T10:00:00",
              "hard": true,
              "weight": 100
            }
          ]
        },
        {
          "name": "JOB-2",
          "location": {
            "latitude": 50.65910297910443600,
            "longitude": 4.007987934186738
          },
          "duration": 3600,
          "windows": [
            {
              "from": "2023-01-02T09:30:00",
              "to": "2023-01-02T10:30:00",
              "hard": true,
              "weight": 100
            }
          ]
        },
        {
          "name": "JOB-3",
          "location": {
            "latitude": 50.324969095932296,
            "longitude": 4.010111317974326
          },
          "duration": 3600
          // No time window - can be scheduled anytime
        },
        // Additional jobs 4-10...
      ],
      "options": {
        "partialPlanning": true
      }
    }
    ```
  </Tab>

  <Tab title="Solution">
    ```json theme={null}
    {
      "score": {
        "hardScore": 0,
        "mediumScore": -3600,
        "softScore": -21334,
        "feasible": true
      },
      "trips": [
        {
          "visits": [
            {
              "arrival": "2023-01-02T08:00:00",
              "job": "JOB-9",
              "location": "50.09960152277046;4.465866983600702"
            },
            {
              "arrival": "2023-01-02T10:18:01",
              "job": "JOB-2",
              "location": "50.65910297910444;4.007987934186738"
            },
            {
              "arrival": "2023-01-02T12:13:45",
              "job": "JOB-6",
              "location": "50.89633806889935;4.45161298168845"
            },
            {
              "arrival": "2023-01-02T13:59:47",
              "job": "JOB-4",
              "location": "50.53457539132416;4.69167867847318"
            }
          ],
          "resource": "R-1",
          "date": "2023-01-02",
          "workTime": 25187,
          "serviceTime": 14400
        },
        {
          "visits": [
            {
              "arrival": "2023-01-01T08:00:00",
              "job": "JOB-8"
            },
            {
              "arrival": "2023-01-01T09:50:38",
              "job": "JOB-3"
            },
            {
              "arrival": "2023-01-01T11:33:03",
              "job": "JOB-7"
            },
            {
              "arrival": "2023-01-01T13:23:15",
              "job": "JOB-10"
            },
            {
              "arrival": "2023-01-01T14:55:42",
              "job": "JOB-5"
            }
          ],
          "resource": "R-1",
          "date": "2023-01-01",
          "workTime": 28542,
          "serviceTime": 18000
        }
      ],
      "unserved": [
        "JOB-1"  // Could not meet time window constraint
      ],
      "status": "SOLVED"
    }
    ```
  </Tab>

  <Tab title="Explanation">
    ```json theme={null}
    {
      "score": {
        "hardScore": 0,
        "mediumScore": -3600,
        "softScore": -21334,
        "feasible": true
      },
      "unresolved": [
        {
          "constraint": "JOB_DAY_INDEX",
          "score": "-5soft"
        },
        {
          "constraint": "TRAVEL_TIME",
          "score": "-21329soft"
        },
        {
          "constraint": "UNUSED_RESOURCES",
          "score": "-3600medium"
        }
      ]
    }
    ```
  </Tab>
</Tabs>

## Key Insights

### Why JOB-1 Was Unassigned

<Warning>
  JOB-1 required service between 09:00-10:00 on 2023-01-02, but the route structure made it impossible to reach this location within the time window while also servicing JOB-2 (09:30-10:30).
</Warning>

The solver prioritized JOB-2 over JOB-1 based on overall route efficiency and the ability to service more total jobs.

### Route Optimization Strategy

The solver:

1. Grouped jobs without time windows on Day 1 for maximum flexibility
2. Scheduled time-windowed jobs on Day 2 where feasible
3. Optimized travel paths to minimize total distance
4. Left JOB-1 unassigned rather than violating hard constraints

## Time Window Patterns

### Single Narrow Window

For strict appointment times:

```json theme={null}
{
  "windows": [{
    "from": "2023-01-15T14:00:00",
    "to": "2023-01-15T14:30:00",
    "hard": true
  }]
}
```

### Multiple Windows

For flexible scheduling options:

```json theme={null}
{
  "windows": [
    {
      "from": "2023-01-15T09:00:00",
      "to": "2023-01-15T12:00:00",
      "hard": true
    },
    {
      "from": "2023-01-15T14:00:00",
      "to": "2023-01-15T17:00:00",
      "hard": true
    }
  ]
}
```

### Soft Windows with Preferences

For preferred but flexible timing:

```json theme={null}
{
  "windows": [
    {
      "from": "2023-01-15T09:00:00",
      "to": "2023-01-15T10:00:00",
      "hard": false,
      "weight": 50  // Moderate preference
    },
    {
      "from": "2023-01-15T08:00:00",
      "to": "2023-01-15T17:00:00",
      "hard": true  // Must be within business hours
    }
  ]
}
```

## Best Practices

<Steps>
  <Step title="Use realistic window sizes">
    Allow sufficient time for travel and service. Overly narrow windows reduce routing flexibility and may lead to unassigned jobs.
  </Step>

  <Step title="Combine hard and soft windows">
    Use soft windows for preferences and hard windows for absolute requirements. This provides flexibility while meeting critical constraints.
  </Step>

  <Step title="Consider travel time">
    Account for realistic travel times between locations when setting consecutive time windows.
  </Step>

  <Step title="Enable partial planning">
    Set `partialPlanning: true` when time windows might make complete assignment impossible. This prevents infeasible solutions.
  </Step>
</Steps>

## Common Pitfalls

<AccordionGroup>
  <Accordion title="Overlapping windows causing conflicts">
    When multiple jobs have overlapping time windows in the same area, ensure there's enough capacity to service them all:

    ```json theme={null}
    // Problematic: Both require 09:00-10:00 slot
    [
      {"name": "job1", "windows": [{"from": "09:00", "to": "10:00"}]},
      {"name": "job2", "windows": [{"from": "09:00", "to": "10:00"}]}
    ]

    // Better: Stagger the windows
    [
      {"name": "job1", "windows": [{"from": "09:00", "to": "10:00"}]},
      {"name": "job2", "windows": [{"from": "10:00", "to": "11:00"}]}
    ]
    ```
  </Accordion>

  <Accordion title="Impossible window sequences">
    Avoid setting windows that are physically impossible to achieve:

    ```json theme={null}
    // Impossible: 30 minutes apart, 60 minutes travel time
    {
      "job1": {
        "location": "cityA",
        "windows": [{"from": "09:00", "to": "09:30"}]
      },
      "job2": {
        "location": "cityB",  // 60 min from cityA
        "windows": [{"from": "09:30", "to": "10:00"}]
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Related Features

<CardGroup cols={2}>
  <Card title="Job Relations" icon="link" href="/guides/vrp/features/job-relations">
    Enforce sequencing between time-windowed jobs
  </Card>

  <Card title="Shift Management" icon="calendar" href="/guides/vrp/features/resource-management">
    Configure resource availability windows
  </Card>

  <Card title="Priority Jobs" icon="star" href="/guides/vrp/features/priority">
    Prioritize time-sensitive deliveries
  </Card>

  <Card title="Partial Planning" icon="chart-pie" href="/guides/vrp/features/advanced-constraints#partial-planning">
    Handle scenarios where not all jobs can be assigned
  </Card>
</CardGroup>
