[Canonical page](<https://docs.dhtmlx.com/planning-engine/js/api/types/scheduling-config/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# SchedulingConfig

Project-wide scheduling settings. It's the `config` field of [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/js/api/types/project-data.md>), so it travels with every snapshot passed to [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/js/api/project-solve.md>), [`Project#analyze`](<https://docs.dhtmlx.com/planning-engine/js/api/project-analyze.md>) or [`schedule`](<https://docs.dhtmlx.com/planning-engine/js/api/schedule.md>). Every field is optional; an omitted field takes its default.

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `apply_constraints` | `boolean` | `false` | Enables task constraints ([`ConstraintType`](<https://docs.dhtmlx.com/planning-engine/js/api/types/common.md#constrainttype>)) as hard bounds. With `false`, constraints are ignored. |
| `schedule_from_end` | `boolean` | `false` | Plans the project backward (ALAP) from its end instead of forward (ASAP) from its start. [`Project#level`](<https://docs.dhtmlx.com/planning-engine/js/api/project-level.md>) rejects a project with this set. |
| `gap_behavior` | `"preserve"` \| `"compress"` | `"preserve"` | `"preserve"`: tasks keep their current dates where links allow. `"compress"`: tasks move to the earliest position. |
| `move_projects` | `boolean` | `true` | `true` moves a summary and its descendants as one block. `false` schedules the summary's leaves one by one, keeping their offsets within the summary. |
| `project_constraint` | `boolean` | `false` | A child task without its own constraint inherits its parent's constraint. No effect while `group_mode` is `true`. |
| `group_mode` | `boolean` | `false` | Turns off the constraint inheritance of `project_constraint`. It has no other effect. |
| `use_progress` | `boolean` | `false` | Treats a task with `progress` equal to `1` as completed: it keeps its dates. |
| `descendant_links` | `boolean` | `false` | Allows links between a summary and its own descendant. With `false`, such a link is dropped and reported in the result's `notes`. |
| `calendar_mode` | `"resource"` \| `"task"` \| `"task-inherited"` | `"resource"` | Which calendars place the work. `"resource"`: each assignment works on its resource's calendar. `"task"`: task calendars only. `"task-inherited"`: task calendars, and a task without one uses the nearest ancestor's. |
| `strict_calendar` | `boolean` | `false` | Reports a `calendar-non-working` [conflict](<https://docs.dhtmlx.com/planning-engine/js/api/types/schedule-result.md>) when a moving summary block lands a task on non-working time. |
| `max_iterations` | `number` | `8` | Upper limit on scheduling passes. An integer, at least `1`. |
| `project_start` | [`DateValue`](<https://docs.dhtmlx.com/planning-engine/js/api/types/common.md#datevalue>) \| `null` | none | Earliest date of the project: no task starts before it. Also the date source for tasks that have no dates of their own. |
| `project_end` | [`DateValue`](<https://docs.dhtmlx.com/planning-engine/js/api/types/common.md#datevalue>) \| `null` | none | Upper bound of the project, used by backward (`schedule_from_end`) plans. |
| `duration_unit` | [`TimeUnit`](<https://docs.dhtmlx.com/planning-engine/js/api/types/common.md#timeunit>) | `"day"` | Unit of task `duration` and link `lag`. A task can override it with its own [`duration_unit`](<https://docs.dhtmlx.com/planning-engine/js/api/types/task-data.md>). |
| `use_calendars` | `boolean` | `true` | `true` schedules on working calendars. `false` treats every calendar as working time around the clock. |
| `default_resource_capacity` | `number` | `1` | Capacity of a resource that doesn't set its own, in assignment `value` units (`1` = 100 %). Must be finite and non-negative. |
| `root_id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/js/api/types/common.md#id>) | `0` | A task `parent` equal to this id (or `""`) means the task has no parent. Ids compare as normalized keys, so the default matches both `0` and `"0"`. Such a parent is stored as no parent. Set it when the data uses another root id, such as `-1` or `"root"`; a task with id `0` is then an ordinary parent. |

`null` in any field reads as omitted and gives the default. Unknown keys are ignored.

The config is checked when the snapshot is imported. In both `validation` modes, these values throw an [`InputError`](<https://docs.dhtmlx.com/planning-engine/js/api/types/errors.md>) with `kind: "validation"` at the field path:

| Path | When |
|---|---|
| `config.max_iterations` | `max_iterations` is `0` |
| `config.default_resource_capacity` | the value is negative, `NaN` or infinite |

## Used by

- [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/js/api/project-solve.md>): read from `data.config` when `data` is loaded
- [`Project#analyze`](<https://docs.dhtmlx.com/planning-engine/js/api/project-analyze.md>): read from `data.config` when `data` is passed
- [`schedule`](<https://docs.dhtmlx.com/planning-engine/js/api/schedule.md>): read from `data.config`

## Example

```js
const config = {
  duration_unit: "hour",
  apply_constraints: true,
  project_start: "2026-08-14 08:00",
  calendar_mode: "task",
};
```

## Related

- [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/js/api/types/project-data.md>) - the plan that carries `config`
- [`CalendarData`](<https://docs.dhtmlx.com/planning-engine/js/api/types/calendar-data.md>) - the calendars that `calendar_mode` combines
- [Project data](<https://docs.dhtmlx.com/planning-engine/js/scheduling/project-data.md#scheduling-config>) - the config switches in context
- [Scheduling a Project](<https://docs.dhtmlx.com/planning-engine/js/scheduling/scheduling-a-project.md>) - forward and backward planning
- [Links, constraints and summaries](<https://docs.dhtmlx.com/planning-engine/js/scheduling/links-constraints-summaries.md>) - constraints, gap behaviour and summary movement
