[Canonical page](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/focus-overload/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# FocusOverload

Resource overload measured only where one focus task runs. [`Project::evaluate`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#evaluate>) returns one `FocusOverload` per task in [`EvaluateOptions::focus`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/evaluate-options.md>), in that order, as [`Overload::focus`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/overload.md>). It isn't built by hand.

## Declaration

```rust
#[derive(Clone, Debug, PartialEq)]
pub struct FocusOverload {
    pub task: Id,
    pub resources: Option<Vec<ResourceOverload>>,
}
```

With the `serde` feature (`cargo add plen-core --features serde`), `FocusOverload` also implements `Serialize` and `Deserialize`, with field names in camelCase.

## Fields

| Field | Type | Description |
|---|---|---|
| `task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>) | The focus task, as given in [`EvaluateOptions::focus`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/evaluate-options.md>). |
| `resources` | `Option<Vec<`[`ResourceOverload`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/resource-overload.md>)`>>` | Overload per resource, counted only over the buckets that intersect the task's `[start, end)` in this stage. `None` when the task isn't in this stage, for example when the candidate removes it. |

### resources

- Lists every resource with non-zero overload inside the task's span, in this stage or in the baseline. The order matches [`Overload::resources`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/overload.md>).
- The span is the task's span in this stage, so it moves with the task's dates. A zero-span milestone covers no bucket and has no overload.
- In the scheduled stage, the values show the overload around the task. In the leveled stage, they show the overload leveling couldn't remove there.

## Example

Score a candidate that gives task 2 to a resource already busy on task 1, and print the overload inside task 2's span.

```rust
use plen_core::{
    AssignmentData, Candidate, DateTime, EvaluateOptions, Project, ProjectData,
    ProjectOptions, ResourceData, SchedulingChanges, SolveOptions, TaskData,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let monday = DateTime::from_ymd_hm(2026, 8, 10, 8, 0).ok_or("invalid date")?;

    let task = |id: i32| TaskData {
        start_date: Some(monday),
        duration: Some(2.0),
        ..TaskData::new(id)
    };
    let assign = |task: i32| AssignmentData {
        id: None,
        task: task.into(),
        resource: "dev1".into(),
        value: 1.0,
        offset: None,
        duration: None,
    };

    let data = ProjectData {
        tasks: vec![task(1), task(2)],
        resources: vec![ResourceData { id: "dev1".into(), capacity: None, calendar_id: None }],
        assignments: vec![assign(1)],
        ..Default::default()
    };

    let mut project = Project::new(ProjectOptions::default());
    project.solve(Some(data), &SolveOptions::default())?;

    let mut changes = SchedulingChanges::default();
    changes.assignments.add.push(assign(2));
    let candidates = [Candidate { id: "dev1-on-2".into(), changes }];
    let options = EvaluateOptions {
        focus: vec![2.into()],
        ..Default::default()
    };

    let result = project.evaluate(&candidates, &options)?;
    for c in &result.candidates {
        let Some(scheduled) = &c.scheduled else { continue };
        for focus in &scheduled.overload.focus {
            match &focus.resources {
                Some(rows) => {
                    for row in rows {
                        println!(
                            "task {}: {} over by {} ({:+})",
                            focus.task, row.resource, row.overload.value, row.overload.delta
                        );
                    }
                }
                None => println!("task {} isn't in this stage", focus.task),
            }
        }
    }
    Ok(())
}
```

## Related

- [`Overload`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/overload.md>) - the stage overload that contains it
- [`EvaluateOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/evaluate-options.md>) - `focus` selects the tasks it is reported for
- [`TaskFinish`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/task-finish.md>) - the finish of the same focus task
- [Evaluating Alternatives](<https://docs.dhtmlx.com/planning-engine/rust/resources-and-assignment/evaluating-alternatives.md#metrics-and-cost>) - how focus overload is read per candidate
