Changelog
Follow up on the latest improvements and updates.
RSS
new
improved
fixed
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Pickup & Delivery Routing
Disrupted employees KPI in ESS, all-or-nothing co-located visits in FSR, notifications as the one place for webhooks, and more

- Set up webhooks and read their logs in one place: Notifications: Notifications is now the only place to set up webhooks, with a webhook channel, and to read their logs. The retention period for the logs of the old webhooks has ended, so we removed the read-onlyWebhookspages fromManage tenant. See webhook channel and logs for more details.
- Email when someone declines your tenant invite: You now get an email when someone declines your invite to join a tenant. See Invite a new member to a tenant for more details.
- Failed notification emails include the error and tenant name: When a notification channel fails after all its retries, the email to the tenant administrators now includes the error and the tenant name. See Retry strategy for more details.
- Ask Claude or ChatGPT about any documentation page: Every documentation page now hasAsk ClaudeandAsk ChatGPTbuttons above the table of contents. Each opens that assistant in a new tab with a prompt to summarize the page.
- The secrets list shows all your secrets: The secrets list now shows every secret, 50 per page, instead of only the first 100. Search and the secret pickers in the notification settings cover every secret too. If loading fails, the list shows an error instead of appearing empty.
- Patch plan works without overrides: ThePatch plandialog no longer fails with "$.config: must have at least 1 properties" when you patch a plan without overrides.
- Configuration profiles save after changing a parameter without a constraint weight: A configuration profile no longer fails to save after you change a model parameter that has no constraint weight.
- Dates and times always show in your time zone: Dates and times, for example in the plans list and the configuration profiles list, now always show in your time zone, including after you reload a page.
- See how many employees replanning disrupts: ThedisruptionPercentageKPI shows how many shifts replanning changes. Managers also need to know how many people replanning affects. Thekpisobject now includes thedisruptedEmployeesPercentageKPI, with the title "Disrupted employees", to show this. An employee is disrupted when they lose a shift that was originally assigned to them. An employee is also disrupted when they get a shift that was originally assigned to someone else, or that was not assigned. The KPI is the percentage of disrupted employees among the employees with at least one shift in either the existing schedule or in the new schedule. The "Disrupted employees" KPI replaces the "Disruption percentage" KPI in the default KPI view. The "Disruption percentage" KPI is still available underShow all. See Key performance indicators and Real-time planning for more details.
- New lessons: apply rules to some shifts and plan around absences: Some rules don't apply to every shift, for example at most five night shifts worked in four weeks. Lesson 6: Treating shifts differently continues the lesson series and shows how to use tags and tag types to apply rules to a subset of shifts withincludeShiftTagsandexcludeShiftTags, followed by a practical example. Employees aren't always available to work, for example during a vacation or parental leave. Lesson 7: Planning around absences shows how to plan around required absences with unavailable or available time spans, and how to combine them with shift tags, followed by a practical example. See Lesson 6: Treating shifts differently and Lesson 7: Planning around absences for more details.
- Visualization keeps your view while the model solves: You can now inspect part of a schedule while the model solves, without the view jumping back each time a new solution arrives. This release also includes smaller visualization improvements, for example employees with a shift in the selected dates now appear first in theBy employeeview, and pinned shifts show the pin icon even when the shift block is narrow. See Visualization for more details.
- Consistent matching for empty tag lists in daily shift pairings and rotation groups: In daily shift pairings and shift rotation groups, an empty tag list withshiftTagMatchesset toANYmatched no shifts. It now matches every shift, the same as withALL. This can change the score of existing schedules. AWEEKLYrotation group withANYand noincludeShiftTagsthat the model accepted before can now fail validation withSHIFT_MATCHES_MULTIPLE_ROTATION_GROUPS. See daily shift pairings and shift rotation groups for more details.
- Incomplete or duplicate cost details no longer stop the dataset from solving: In costs rules, anemployeeShiftCostDetailsitem withoutemployeeCostGroupor withoutcostcaused an error before solving started. Two items with the sameemployeeCostGroupandshiftCostGroupcaused the same error. The model now ignores items withoutemployeeCostGrouporcost, and uses only the first item for a repeated pair of cost groups. Validation reports each case with a warning:COSTS_RULE_COST_DETAIL_MISSING_EMPLOYEE_COST_GROUP,COSTS_RULE_COST_DETAIL_MISSING_COST, andCOSTS_RULE_COST_DETAIL_DUPLICATE_COST_GROUP_PAIR. See costs rules for more details.
- Global period and costs limits now respect shifts already worked: GlobalminimumMaximumShiftsPerPeriodrules and globalcostsRulesnow take into account the shifts already worked earlier in the same period, so the plan no longer exceeds limits such as a maximum number of shifts per week or a maximum cost per pay period. TheshiftsWorkedMin,shiftsWorkedMax, anduniqueTagsLimitfields of global rules, and thetotalCostsMinandtotalCostsMaxfields of globalcostsRules, now count every assigned shift in each period that overlaps the planning window, including when the shift ends before the planning windowstart(a historic shift) or starts after itsend. This matches how contract period rules already count these shifts. See Historic shifts and the upgrade guide for more details.
- Stricter checks for overlapping shifts of a vehicle: A vehicle can work only one shift at a time. Validation now gives the warningVEHICLE_SHIFTS_OVERLAP_ISSUEwhen two shifts of the same vehicle overlap. The issue detail gives the vehicle ID, the IDs of the two shifts, the end time of the first shift, and the start time of the second shift. Previously, the model checked overlaps only for shifts in the same linked shift, and only when both shifts setmaxEndTimeandminStartTime. Other overlaps were accepted without a warning, so the model could plan the same vehicle in two places at the same time. A shift starts atminStartTime(orminFirstVisitArrivalTime) and ends atmaxEndTime(ormaxLastVisitDepartureTime). If it sets no end time, it ends at midnight at the end of its start day, the same default the model uses when solving. TheLINKED_SHIFTS_OVERLAP_ISSUEcheck for shifts in a linked shift now uses the same rules and stays an error. Input with linked shifts that the model accepted before can now fail validation. For example, two shifts in the same linked shift on the same day with no end time now fail, because the first shift ends at midnight, after the second shift starts. To fix this, setmaxEndTimeormaxLastVisitDepartureTimeon each shift so that it ends before the next shift of the vehicle starts. See Upgrade from 1.38.0 to 1.39.0 and Input validation for more details.
- Assign co-located visits all together or not at all (preview): When several visits at the same location must be completed in a single trip, partially serving the location isn't helpful. Previously, you had to link such co-located visits with visit dependencies yourself, usingSAME_SHIFT_ENFORCEcoordination and a restricted pooling type. The newmodelInput.allOrNothingScopesetting, set toCOLOCATED_VISITS, now makes the model create these visit dependencies for you. Visits at the same location, or withinpreferGroupingColocatedVisitsRadiusMetersof each other, are then either all assigned to the same vehicle shift, one right after another, or none of them is assigned. A visit can be excluded withexcludeFromAllOrNothing. This feature is in an early preview state and may have limitations or be subject to change. See All-or-nothing for co-located visits (preview) for more details.
new
improved
fixed
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Pickup & Delivery Routing
Redesigned visualizations and improved service time limits in FSR, improved replanning in ESS replanning, and more
- A tidier token list, with expired and revoked tokens removed after 30 days: The platform now deletes personal access tokens 30 days after they expire or are revoked. Active tokens are never deleted. Tokens you revoked before this release are deleted 30 days after this release. See personal access tokens for more details.
- Log in to Timefold's Feature Requests Board from the United States region: You can now log in to Timefold's Feature Requests Board with a Timefold Platform user account from the United States region. When you log in, you first choose your region, Europe or United States, and then log in with your user account for that region. See Timefold's Feature Requests Board for more details.
- Get tenant notifications in a Microsoft Teams channel: The Email channel section now explains how to get notifications in a Microsoft Teams channel: forward a tenant member's notification emails to the Teams channel's email address. See Email channel for more details.
- Your self-hosted license covers the platform's Timefold Solver (self-hosted only): The License section now explains that your self-hosted Timefold Platform license also covers the Timefold Solver instance running within the platform, so you don't need a separate Timefold Solver Enterprise Edition license (self-hosted only). See License for more details.
- Toggle every optional model parameter in configuration profiles: In a configuration profile, every optional parameter a model declares now has a toggle to turn it on or off. Turn a parameter off to let the model use its own default value for it. The platform reads which parameters are optional from the model itself, instead of from a fixed list, so the toggle works for every model, including your own custom models. TheImport profiledialog also shows its file drop area at full width. See configuration profile and Export and import profiles for more details.
- Minimize employee disruption during replanning with kept shift tags (preview): When replanning takes a shift away from an employee, some replacement shifts disrupt them less than others. For example, an employee who loses a shift at Location 1 would rather get another shift at Location 1 than one at Location 2, so their commute stays the same. Contract disruptionRules now support a keptShiftTags field. It rewards replacement shifts that have the same tags as the shift the employee lost. You set which tags count, whether a shift must match any or all of them, and a weight.keptShiftTagsis a preview feature and subject to change. See Reward disruptions that keep shift tags for more details.
- Catch missing or misspelled tags with a tag type validation warning: A tag type in the top-leveltagTypescollection is only useful if at least one tag in the top-leveltagscollection belongs to it. If none does, every employee group and rule that references the tag type never matches. For example, the members of an employee group with that tag type ascommonTagTypecan never share a tag of that type, so the employee group can never be satisfied. Validation now reports this as a warning that names the tag type, so you catch a missing or misspelled tag at validation time. The warning does not block solving, so existing schedules keep running unchanged. See Tags and tag types for more details.
- Clearer, faster visualization: The ESS visualization is easier to read and work with. Hover cards now stay open, so you can select and copy their text, and shift cards show the shift’s priority and have a button to copy the shift ID. A new date control shows up to seven days per timeline, and the view opens on the first day that has a shift. Each filter value shows how many items match it, the Filter button shows how many values you selected, and Reset filter keeps your selected dates. The By employee timeline responds faster to filter changes and shows each employee’s worked hours as a bar in the row header. The timelines now follow the model’s own rules for skill validity, preferences, permitted overlaps and availability, and they use the model’s terms. A time zone readout shows the UTC offset, overtime is no longer drawn in red, and durations read as “7h 30m”. See Visualization for more details.
- New lesson: set limits over rolling time windows: Some limits don't follow calendar periods, for example at most five days worked in any ten-day period, or an average of four days worked per week over any four-week period. Lesson 5: Rules over different periods continues the lesson series and shows how to set these limits with rolling window rules in contracts. It explains how a rolling window moves across the schedule, how to add a limit and satisfiability to a rolling window rule, and when a rolling window rule is equivalent to a period rule, followed by a practical example. See Lesson 5: Rules over different periods for more details.

- Redesigned visualizations for improved filtering: We have redesigned the visualizations to make filtering easier for quicker access to subsets of the data. The Map, By vehicle, and By visit views are now tabs of one Visualization page, and Timefold Platform shows that page in its sidebar. Every view now supports filtering: clickFilterto drill down into a subset of the data, for example by vehicle, skill, or tag. A date control after the tabs sets the dates to show: one day on the map, and up to seven days on the timelines. The dates open on the first day with a planned visit. TheMaptab shows theBy vehicletimeline under the map, and hovering a row highlights its route. The map shows its stops right away, even on large datasets, and it stays responsive when you switch days or tabs. While the model solves, the map and the timelines keep your zoom and selected page, so you can follow the solve without losing your place. The new Efficiency X-Ray page shows how your fleet uses its time, distance, and overtime across the whole dataset. Use it to find vehicles with much more or much less work than the rest of the fleet, and to compare groups of vehicles by skill or tag. Efficiency X-Ray is a preview feature and subject to change. To request early access, contact us. See Map, By vehicle, and By visit and Efficiency X-Ray for more details.
- Fewer unnecessary overnight stays with linked shifts: A technician's local area is the area they can travel to and return from within their working day, based on their start and end locations. Previously, Timefold could use a linked shift for visits in technicians' local areas. The technician then stayed away overnight only to get more working time, and did not return to the local area at the end of the day. Now, Timefold uses a linked shift to reach visits that are far from the shift's start or end location. A visit is far from the technician's local area if the technician cannot travel to it, complete the visit, and travel back in one shift. A new medium constraintAvoid overnight stay in local areapenalizes each night of a linked shift between two visits in technicians' local areas. One such night has the same penalty as ten unassigned mandatory visits with the highest priority. The constraint is enabled by default when any linked shifts are defined. If a linked shift has no visits far from the local area, Timefold removes it before it starts to solve. The output still shows the linked shift, with no visits in its itinerary. See Avoid overnight stays in technicians' local areas for more details.
- Routes can start furthest from the end location: A new soft constraintPrefer moving towards end locationlets technicians drive to the visit furthest from their end location first and then work their way back. The long drive happens at the start of the shift, and the technician finishes the day close to the end location, for example, their home. The constraint penalizes every visit that is further from the shift'sendLocationthan the previous visit. By default, this constraint is disabled. To enable it, setpreferMovingTowardsEndLocationWeightin the model configuration. See Prefer moving towards end location for more details.
- Limit the total service time per shift: You can now limit the total time a technician spends working on visits during a vehicle shift or a linked shift, for example, to comply with labor law limits. The service duration of a shift is the effective service duration of all visits assigned to the shift. Travel time, waiting time, and breaks don't count toward the service duration. SetmaxServiceDurationon a shift for a hard limit. The newMax shift service duration (hard)constraint leaves visits unassigned rather than exceed max service duration. SetmaxSoftServiceDurationon a shift for a preferred limit. The newMax shift service duration (soft)constraint penalizes each second above the specified duration. To change the constraint weight, setmaxSoftShiftServiceDurationWeightin the model configuration. If the soft limit is higher than the hard limit, the model returns theVEHICLE_SHIFT_MAX_SOFT_SERVICE_DURATION_GREATER_THAN_MAX_SERVICE_DURATIONvalidation warning. See labor law limits, Required maximum service duration per shift, and Preferred maximum service duration per shift for more details.
- Visits no longer wait for temporary skills or tags they don't need: When a vehicle shift had temporary skills or temporary tags, a visit that did not need them could start later than necessary. The visit waited until the first temporary skill set or temporary tag set started. This happened when the visit had no required skills or tags, or when the shift's static skills or tags already covered them. Now, such a visit no longer waits for temporary skills or tags, which removes the idle time before it starts. Visits that need temporary skills or tags still wait until those skills or tags are available. See Temporary skills and Temporary tags for more details.
- Floating breaks can have a location: A floating break can now have alocation, for example, a restaurant or a canteen where the technician must take their lunch break. Previously, the model ignored thelocationof a floating break and always scheduled the break wherever the technician was on their route. When a floating break has a location, the technician travels to that location, takes the break there, and then travels to their next visit. The travel time to and from the break location is included in the schedule, and the break still starts no earlier than itsminStartTime. A floating break without a location works as before. See Floating breaks with a location for more details.
- Floating breaks fit between fixed breaks and no longer end later than necessary: Timefold can now schedule a floating break between two fixed breaks when the floating break fits in the time between them. Previously, a floating break was always scheduled after all fixed breaks that occurred in the same gap between visits, which could push the floating break past itsmaxEndTimethan necessary. TheBREAKitems in the itinerary now also reporttravelTimeFromPreviousStandstillandtravelDistanceMetersFromPreviousStandstillfor floating breaks. When a technician travels to their next visit before they take a floating break there, this travel is now reported on the break, and the visit after the break reports no travel. See Upgrade from 1.37.0 to 1.38.0 for an example. See Lunch breaks and personal appointments for more details.
- New hard constraint stops fixed breaks from starting late: A fixed break can start later than itsstartTime, for example, when the technician cannot travel to the location of the break in time. The newFixed break not delayed (hard)constraint penalizes each second that a fixed break starts after itsstartTime. The newRequireFixedBreakNotDelayedJustificationjustification shows the actual start time and the original start time of the break. The itinerary now shows the actual start and end times of a fixed break. If the break starts late, it keeps its full duration, so it also ends late. Previously, the itinerary always showed thestartTimeandendTimefrom the input, even if the technician could not start the break on time. See Personal appointments for more details.
- Floating breaks no longer push visits past their time windows: Previously, Timefold could schedule a floating break before a visit even if the break pushed the end of the visit past themaxEndTimeof its time window. Timefold now schedules the floating break after the visit instead, if the break can still end before its ownmaxEndTime. If both options break a time window, Timefold chooses the option with the smaller overrun. See Floating lunch breaks for more details.
- Pinning requested for a visit that is not in an itinerary is rejected: The model now rejects input that setspinningRequestedtotrueon a visit that is not in theitineraryof any shift. Validation fails with the errorPINNING_REQUESTED_VISIT_NOT_IN_ITINERARY. Previously, the model ignoredpinningRequestedon such a visit. When you sent the output back as the input of the next dataset, the model could then reject it, because a pinned visit cannot come after an unpinned visit. Validation now gives the same result for the first dataset and for every dataset after it.Important:Input that the model accepted before can now fail validation. See Upgrade from 1.37.0 to 1.38.0 for how to migrate. See Real-time planning: pinning visits for more details.
- Shifts without visits are penalized when their breaks make them end late: A vehicle shift without visits still takes its fixed and floating breaks. These breaks can make the shift end late, for example when the technician cannot travel to a fixed break with a location before the break starts, or when a floating break must wait for itsminStartTime. Previously, theMax shift end time (hard)andMax shift end time (soft)constraints did not penalize such a shift. The penalty appeared only when the first visit was assigned to the shift. That made the first visit look much more expensive than it was, so Timefold often left those shifts empty even when using them would improve the plan. Both constraints now also penalize shifts without visits when their breaks make them arrive at the end location aftermaxEndTimeormaxSoftEndTime. The metrics of shifts without visits do not change. See Breaks can make a shift end late for more details.
- Faster bulk visit recommendations: Bulk visit recommendations are now returned faster. Previously, a request could take 10 to 30 seconds, and the recommendations often differed only in where the last few visits were placed. See Bulk visit recommendations for more details.
- Performance improvements: The algorithm for the initial solving phase has been changed and finishes now in a fraction of the time it took before. Benchmarks show a runtime reduction of about 86% for a small dataset of up to 96% for large datasets. Apart from faster solves, this can lead to more time being available for later solving phases and thus improved solution quality.
- Reduced driver idle time before time windows open: A driver can arrive at a stop before its time window opens and then has to wait before starting the service. The new soft constraintMinimize waiting timeminimizes the total waiting time in the schedule. By default, this constraint is disabled. To enable it, setminimizeWaitingTimeWeightin the model configuration. See Minimize waiting time for more details.
new
improved
fixed
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Pickup & Delivery Routing
Comparison CSV export, imperial units, employee groups and demand coverage KPIs (ESS), and more
- Take comparison results into your own tools with CSV export: You can now export a comparison to CSV from itsSharemenu. The file contains the visible comparison rows, with a value, difference, and difference-as-percentage column per dataset. The KPI aggregation popover of a comparison now also shows the sum, next to the minimum, maximum, average, and median. The saved comparisons list now also shows which model each comparison was built on. See comparison and saved comparisons for more details.
- See distances in miles and feet: You can now choose how the platform shows distances. Open the profile menu by clicking the cogwheel in the top-right corner of the header, then selectUnitsand choose one of these options: the system default, metric, or imperial. With imperial units, the platform shows distances in miles and feet. By default, the platform follows your browser's locale, and it remembers your choice in the browser, just like the theme setting.
- Pick or upload datasets faster when adding a new plan: We've redesigned the first step of the New plan dialog. You now pick a dataset from a dropdown that shows each dataset's short description, and the selected demo dataset's description and constraints appear below it. To use your own data, drag and drop your file, or browse for it, directly inside theCustomoption, which takes two steps instead of three. The dialog also has a newCancelbutton. TheImportprofile dialog uses the same drop zone, so you can drop an exported profile in as well as browse for it. See New plan and Export and import profiles for more details.
- More reliable server-sent events: The events stream (GET …/{id}/events) now closes after it sends the event for the dataset's final status (for datasets submitted without solving, that'sDATASET_COMPUTED). We also fixed an issue where events for a dataset could stop arriving when another dataset finished. A heartbeat comment every 30 seconds now keeps proxies from closing idle connections. If your client reconnects automatically, treat a close after the final status as the expected end of the stream. See events stream and Connection lifecycle for more details.
- Filter notification logs by trigger: You can now filter the notification logs by trigger, and open a trigger's edit dialog directly from a log's details. The log details now also show the execution duration. See notification logs for more details.
- Delete experiments and compare model versions on identical settings: You can now delete an experiment (preview) from the Experiments list, which also deletes the datasets its scenarios created. You can now leave out the configuration profile of an experiment scenario. The scenario then uses the settings it was originally solved with, which makes it easier to compare model versions on identical settings. See experiment for more details.
- Find datasets by ID and filter by profile name: Paste a full dataset ID into the search bar on the Plans overview to find that dataset directly. The configuration profile filter now offers your existing profile names in a dropdown. See Searching and filtering datasets for more details.
- See API versions in the model version picker: The model version picker now labels each version with its API version, such as v1 or v2, next to the build version. It also warns you when a model approaches the limit of ten parallel versions. See Semantic versioning for more details.
- A more compact model catalog: The model catalog is now a compact tile grid, with each model's maturity badge on its tile. See model catalog for more details.
- One consistent layout for lists and tables: Every list and data table in the platform now uses the same layout, with a toolbar for search and filters, striped rows, and a footer with pagination.
- Screen readers announce toasts: Screen readers now announce toasts, and each toast's dismiss button has an accessible name.
- Keyboard access to selected notification channels: When you select channels for a notification trigger, each selected channel's remove button is now reachable with the keyboard.
- Expandable sections report their state to assistive technology: Expandable sections, such as the advanced termination settings and validation issue groups, now tell assistive technology whether they're expanded.
- Expired items consistently highlighted: The platform now consistently highlights expired API keys, members, invites, and personal access tokens in red.
- Balance rules count only the shifts that match their shift tags: If you use more than one balance rule, each rule now balances only the shifts that match its shift tags, and counts each shift once. This lets the solver find schedules that are more balanced for each rule. We have fixed a bug where a shift was counted in every balance rule of its employee, also in rules whose shift tags do not match the shift. A shift that matched more than one rule was also counted once for each matching rule. The soft score of the balance shift count and balance time worked constraints changes for datasets with more than one balance rule. See Balance shift count and Balance time worked for more details.
- Tutorials to discover modeling concepts step by step: We have created a series of lessons designed to help you understand the concepts behind Timefold's Employee Shift Scheduling model, and how to use them to create a schedule that meets your business needs. They are aimed at new users of Timefold, but may also be useful for experienced users who want to deepen their understanding of modeling concepts. They are intended to complement the extensive technical documentation that already exists. Lessons can be viewed by navigating to the Lessons overview. More lessons will follow. See Lessons overview for more details.
- Choose which kinds of absence count toward absence-aware rules (preview): You can now limit absence awareness to specific kinds of absence, for example only sick leave, by tagging availability and unavailability time spans. Important: this is a breaking change to the previewabsenceModefield.absenceModewas a plain string ("ABSENCE_AWARE"or"ABSENCE_UNAWARE") and is now an object, for example"absenceMode": { "type": "ABSENCE_AWARE" }. Requests that still send the string value must be updated. OmittingabsenceModestill defaults toABSENCE_UNAWARE.absenceModenow also accepts anincludeDateTimeSpanTagsfield. WhenincludeDateTimeSpanTagsis non-empty, onlyunavailableTimeSpans/availableTimeSpansthat share at least one tag withincludeDateTimeSpanTagscount toward absence awareness. Spans without a matching tag are treated as if the employee were fully available during them. This lets you scope absence awareness to a specific kind of absence, for example only bridging gaps or scaling limits forsickleave, while avacation-tagged absence still breaks a consecutive-days streak or counts fully against a rolling-window limit. WhenincludeDateTimeSpanTagsis empty or omitted, every span counts, matching the previous behavior. Time spans also get a newtagsfield, matched againstabsenceMode.includeDateTimeSpanTags, that describes what a span represents, for example, the reason for an absence.includeDateTimeSpanTagsrequiresabsenceMode.typeto beABSENCE_AWARE. Absence-aware rules are a preview feature and subject to change. See Upgrade from 1.35.0 to 1.36.0, Consecutive days worked, Minutes between shifts, Minutes worked in a rolling window, Consecutive days off in a rolling window, Consecutive minutes off in a rolling window, and the Employee Shift Scheduling changelog for more details.
- See how well your hourly demand is staffed with new demand coverage KPIs: Schedules driven by hourly demand rules now report how well the demand curve was actually staffed, using three new demand coverage KPIs. All three are measured in person-time, soPT2Hmeans one employee for two hours, or two employees for one hour:hourlyDemandCoveragePercentage, the share of the required staffing that was met;uncoveredHourlyDemandPersonDuration, how much staffing is missing; andexcessHourlyDemandPersonDuration, how much staffing exceeds the maximum demand. Coverage is measured against each demand interval'sminDemand, and excess against itsmaxDemand. A KPI that cannot be measured is left out of thekpisobject rather than reported as zero, so a value of0always means "measured, and nothing is missing". All three are omitted when the dataset defines no hourly demand rules, and the two coverage figures are omitted when no demand interval defines aminDemand. These are distinct fromtotalDemandPersonSlots,coveredDemandPersonSlots, anduncoveredDemandPersonSlots, which describe how well automatically generated shifts blanket the demand curve, before any employee is assigned. See hourly demand rules, demand coverage KPIs, generated shifts, and the Employee Shift Scheduling changelog for more details.
- Limit the unique shift tags worked per period across the whole schedule (preview): GlobalminimumMaximumShiftsPerPeriodrules now support theuniqueTagsLimitfield, which caps how many distinct tags of the given tag types may be worked across all shifts in a period. Until nowuniqueTagsLimitwas only available on a contract'speriodRules, where the cap applies per employee, so there was no way to keep a whole operation on a single kind of task for a period. This is for operations that switch every shift over to one variant at a time, rather than limiting the variety any one employee sees. Any number of shifts can be staffed in the period, as long as they all carry the same tag. All the tag types listed inincludeTagTypesshare one budget, so listing two tag types with atagsMaxof 1 permits one distinct tag in total, not one distinct tag of each type. WhensatisfiabilityisREQUIRED, theUnique tags per period not in required rangehard constraint leaves shifts unassigned rather than exceedtagsMax. When it isPREFERRED, theUnique tags per period not in preferred rangesoft constraint penalizes each distinct tag abovetagsMaxinstead, and all shifts can still be assigned.uniqueTagsLimiton global rules is a preview feature and subject to change. See Limit unique shift tags worked per period and the Employee Shift Scheduling changelog for more details.
- Better schedules when limiting unique shift tags per period across the schedule: The model now uses a new custom move to better satisfy globalminimumMaximumShiftsPerPeriodrules that define auniqueTagsLimit. Previously, the model reached the allowed set of tags one shift at a time, so a period that had settled on the wrong tag could only be corrected by unassigning every shift carrying it first, which has a very low likelihood of happening. A new move now switches a whole period over to a different tag in one step, reassigning all the affected shifts together. The move is used automatically when any global rule also defines auniqueTagsLimit. See uniqueTagsLimit for more details.
- Employee groups on shifts (preview):employeeGroupsis a new top-level API that replaces grouping employees throughcommonTagType,groupByEmployeeTagandgroupShiftsPerDayLimiton employee pairings. Those fields have been removed from employee pairings. We have added a top-levelemployeeGroupscollection for cases where a set of employees must be considered together as a group rather than individually or as a pair. Each group declares explicit membership, split intorequiredEmployeesandpreferredEmployees: preferred members require at least one required member to be present, while required members can work alone but prefer other members of the group to also be present. Employee groups also supportcommonTagType, so that all working members of a group must share a concurrent shift with the same tag of that type, andgroupShiftsPerDayMax, capping how many different shift hours the group's members may work on the same day.employeeGroupsis a preview feature and subject to change. See Migrating from 1.35.0 to 1.36.0, Employee groups, and the Employee Shift Scheduling changelog for more details.
- Shifts ending at midnight no longer count toward the next day in global period rules: Global period rules now count a shift ending exactly at midnight only toward the periods it covers, so your period counts match the days your employees actually work. Previously, global period rules withperiodShiftOverlapKindset toSTART_AND_ENDalso counted that shift toward the following day's period. For example, a shift from 16:00 to 00:00 counted toward both the period containing its start and the period starting at 00:00. Global period rules now treat a shift's end time as exclusive, consistent with employee period rules, costs rules, and rolling window rules. This applies to global period rules both with and without a specified zone offset. See Global Period Rule and time zones for more details.
- More reliable server-sent events: This model's events stream also gets the improvements described under "More reliable server-sent events" in the Platform section above.
- Visit dependencies can now be enforced to be scheduled together: Previously, even when a visit dependency'scoordinationwas set toSAME_SHIFTorSAME_VEHICLE, the preceding visit could still be scheduled on its own while its dependent visit remained unassigned. The FSR model now allows requiring that the preceding and following visits of a dependency are scheduled together, or not at all, by specifying"coordination": "SAME_SHIFT_ENFORCE". When the preceding visit is scheduled, the following visit must be scheduled too, in the same vehicle shift. See Visit dependency coordination for more details.

- Understand how invalid coverage area geometries are repaired: When a vehicle's coverage area has invalid geometry, the model repairs it automatically. The documentation now explains how this repair works, including which library performs it. See Repairing invalid coverage area geometries for more details.
- Configurable proximity radius for grouping co-located visits: ThePrefer grouping co-located visitsconstraint previously only considered two itinerary items co-located if they shared the exact same location. A newpreferGroupingColocatedVisitsRadiusMetersoverride now lets you configure a proximity radius (in meters) instead, so that nearby-but-not-identical locations (for example, different geocoded units within the same building) are also considered co-located. The default is0, which preserves the original exact-location behavior, and the radius is capped at a maximum of200meters. It can be set globally, and overridden per vehicle shift or linked shift via their ownpreferGroupingColocatedVisitsRadiusMeters. See Prefer grouping co-located visits for more details.
- More reliable server-sent events: This model's events stream also gets the improvements described under "More reliable server-sent events" in the Platform section above.
- Require tags justification now names the missing tags: TheRequireTagsJustificationrecord has a new field:missingTagNames. This field lists the names of the tags a visit needs but the assigned vehicle shift does not have. Previously, the justification only showed the count of missing tags, not their names. See upgrade to the latest version page for more details.
- More reliable server-sent events: This model's events stream also gets the improvements described under "More reliable server-sent events" in the Platform section above.
- End location visualization: The end location of a shift was not being properly visualized in the visualization. This is now fixed with a hollow ring in the same color as the rest of the driver's route at the end location. The start location remains a solid circle in the same color as the rest of the driver's route. See visualization for more details.
new
improved
fixed
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Pickup & Delivery Routing
Notifications, per-rule contract weights and absence-aware rolling windows (ESS), and more
- Introducing Notifications: get notified when a dataset or experiment changes status: Notifications replace the previous Webhooks feature as the way to stay informed about dataset and experiment activity. A trigger watches for a dataset or experiment status change and sends a message to one or more channels (a Slack channel, a webhook, or an email address) whenever a matching event occurs. Create a channel once and reuse it across as many triggers as you like. Beyond adding Slack and email as delivery channels alongside webhooks, Notifications also let you trigger on experiment status changes, filter by dataset or experiment name and tags, and review every delivery in a dedicated Logs tab. The Logs tab shows each delivery's status and any error message, and lets you retry a failed delivery. We've automatically migrated your existing webhooks into webhook channels and triggers, so you don't need to set them up again. The Webhooks pages stay available as read-only, so you can still see your original configuration and past logs. See Notifications for more details.
- More consistent number formatting in comparisons: Number formatting in dataset comparisons is more consistent: numbers without a metric type, such as calculation metrics and configuration values, are now formatted and aligned as numbers instead of as plain text. See Comparisons for more details.
- Solve queue memory limit covers all solving and queued datasets: The solve queue's memory limit now works like its thread limit: it covers the combined memory of all solving and queued datasets, not only the dataset you're submitting. See Queue limits for more details.
- Accept invites to another tenant: If you already belong to a tenant, you can now accept an invite to join a different one.
- Customizable weight for each contract rule: Timefold already lets you tune how much a violation counts at two levels: a global constraint weight (configured underconfig.model.overrides) scales an entire constraint type across the whole model, and a contract'spriorityscales every rule in that contract uniformly, relative to other contracts. Contract rules can now add a third, more granular level underneath both: aweighton the rule itself, which scales only that one rule's penalty relative to the other rules in the same contract, without changing the contract's priority or the constraint's global weight. This makes it possible to express, for example, that pulling an employee away from a booked vacation is far worse than any other preference violation for that employee. Theweightis supported on several types of rules. See the Employee Shift Scheduling changelog for more details.
- Absence-aware consecutive days off in a rolling window (preview): Rolling window rules with aconsecutiveDaysOffLimitnow support theabsenceModefield. When set toABSENCE_AWARE, the effectiveconsecutiveDaysOffMinis scaled down for each employee based on the fraction of the rolling window for which the employee is available, then rounded up to the nearest whole minute, the same wayconsecutiveMinutesOffMinis scaled. Days the employee is fully unavailable are also excluded from counting as days off, so an absence is never itself counted as satisfying the (now-scaled) limit. See Consecutive days off in a rolling window and the Employee Shift Scheduling changelog for more details.
- Absence-aware consecutive minutes off in a rolling window (preview): Rolling window rules with aconsecutiveMinutesOffLimitnow support theabsenceModefield. When set toABSENCE_AWARE, the effectiveconsecutiveMinutesOffMin(includingconsecutiveMinutesOffMinIntervalsandtotalConsecutiveMinutesOffMin) is scaled down for each employee based on the fraction of the rolling window for which the employee is available, then rounded up, so employees who are partly unavailable during a rolling window aren't held to the full configured minimum for the hours they weren't scheduled to work anyway. See Consecutive minutes off in a rolling window and the Employee Shift Scheduling changelog for more details.
- Scope shift sequences to a continuation tag:sequenceDefinitioninconsecutiveShiftsWorkedRulesnow supports an optionalcontinuationTag. When set, only shifts carrying this tag extend a sequence's reach. A shift without the tag is still included if it already falls within a preceding shift's reach, but it doesn't extend that reach any further. This lets you build sequences that keep chaining through untagged shifts without letting those shifts stretch the sequence indefinitely. See Scope sequence continuation with a tag and the Employee Shift Scheduling changelog for more details.
- Accurate day-counting for shifts ending exactly at midnight: Shifts ending exactly at midnight were sometimes counted as covering an extra day the employee never worked, causing period rules, consecutive-days-worked rules, and days-worked rolling-window rules to disagree on how many days a shift counted toward. See period rules, consecutive-days-worked rules, and days-worked rolling-window rules for more details.
- Catch visits that can never be assigned due to impossible time windows: Input validation now raises aVISIT_TIME_WINDOWS_OUTSIDE_ALL_VEHICLE_SHIFTSwarning when none of a visit's time windows overlaps any vehicle shift. Such a visit can never be assigned, whatever else the input says, so it silently ends up unassigned and adds an unexplained penalty to the score. This most often happens when a visit's time window closed before the planning window opened, or when a visit falls on a day that no vehicle works. The check only asks whether some vehicle shift is open during the visit's time windows. It does not look at skills, tags, areas, or travel time, because the other reasons a visit cannot be assigned have their own warnings. A time window that touches a shift boundary counts as covered. See Input validation for more details.
- Minor visualization fixes: A few minor visualization issues have been fixed, including incorrect handling of special characters in identifiers, which caused the visualization to crash on such datasets.
- Fixed swapped IDs in the required coverage area justification: The justification for theNo visits outside coverage areaconstraint previously swapped the visit ID and the vehicle shift ID, so its description named the wrong visit and shift. The justification now reports both IDs correctly. See [No visits outside coverage area](https://docs.timefold.ai/field-service-routing/latest/vehicle-resource-constraints/coverage-area) for more details.
- Fixed a crash in visit group recommendations for visits with dependencies: Requesting visit group recommendations could throw aNullPointerExceptionwhen a candidate placement's neighboring visit had an unresolved schedule, for example when visit dependencies formed a cycle mid-search. Such a placement is now rejected instead of crashing the request. See visit group recommendations for more details.
- Added missing justification types to the API specification: The OpenAPI schema forVehicleRouteJustificationpreviously omitted several justification types that the model already returned, including the preferred area, preferred time window, mutually exclusive shifts, visit dependency pooling type, and SLA end time justifications. These are now included in the schema, so generated client code and other tooling that reads the API specification can discover and parse them. See API specification for more details.
- Mandatory and optional job input metrics: The input metrics now includemandatoryJobsandoptionalJobs, breaking down the total number of jobs by whether they are mandatory or optional. This makes it easier to verify that the input dataset contains the expected mix of mandatory and optional jobs. See input metrics for more details.
- Minor visualization fixes: We fixed a few minor issues in the visualization, mainly related to incorrect handling of special characters in identifiers. The visualization no longer crashes on such datasets, nor when running embedded in Timefold Platform. See visualization for more details.
- Clearer maximum time burden violation messages: We updated the justification for the maximum time burden to show a clearer message for a constraint violation, stating the actual time burden and by how much it exceeds the allowed maximum. See maximum time burden for more details.
new
improved
fixed
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Pickup & Delivery Routing
Assignability Analysis, redesigned visualizations and limit shifts per day within a paired employee group in ESS
- Stop solving after a set number of moves, not just a time limit: A new termination setting, move count limit, is now available in configuration profiles, as a dataset override when submitting a dataset, and in the comparison table. It stops solving once a fixed number of moves have been evaluated, instead of only supporting time-based limits. See Termination settings for more details.
- Clearer response when a tenant can't access a model: Calling a model administration endpoint for a model your tenant isn't allowed to use now returns404 Not Found, instead of400 Bad Request. This more accurately reflects that the model isn't available to your tenant, rather than suggesting the request itself was malformed.
- Several other smaller improvements: This release also includes several other smaller improvements and bug fixes.
- Redesigned visualizations and Efficiency X-Rays: The visualization views have been redesigned, and the low-level validation views (By shift and By employee) now live separately from the high-level Efficiency X-Ray views in the sidebar. Every view now supports filtering: clickFilterin the view's toolbar to drill down into a subset of the data, for example by skill, tag, priority, or contract type. See By shift, By employee, and Efficiency X-Ray for more details.
- Assignability Analysis (preview): Assignability analysis gives you an immediate picture of how fillable your shifts are, before any optimization runs. For each unassigned shift, it calculates what share of your employees could be assigned based on hard constraints alone, treating the rest of the schedule as empty. Shifts with 0% assignability are structurally impossible to fill and will never be assigned, no matter how the Timefold model optimizes. Shifts with a low but non-zero percentage are at risk of going unassigned due to limited options. Use it to catch impossible shifts early, understand why specific shifts go unfilled, and explore what-if changes to your workforce. This is a preview feature subject to change. See Assignability analysis for more details.
- New validation warning for employees defining both available and unavailable time spans: Employees can now trigger aWARNINGwhen bothavailableTimeSpansandunavailableTimeSpansare defined. Only one of the two should be provided, since one assumes the employee is available by default and the other assumes the employee is unavailable by default. The two cannot be reconciled into a single availability model for the same employee. See Employee availability and Input validation for more details.
- Improved solve quality for alternative shifts: Timefold can now better assign alternative shifts. Previously, moving the group's single assignment to a different alternative shift only worked if the same employee was eligible for both shifts. A new move now allows the solver to reassign a different eligible employee when relocating the assignment within the group. See alternative shifts for more details.
- Support built-in period YEAR for period rules: Period rules now support a built-inYEARperiod type, which defines a calendar year from January 1 to December 31, with leap years automatically accounted for. This allows you to define rules that apply on a yearly basis, providing greater flexibility in scheduling and planning. All period rules now support by default: DAY, WEEK, MONTH, YEAR, SCHEDULE, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, and SUNDAY. See Minutes worked per period for more details.
- Limit shifts per day within a paired employee group (preview): Employee pairings withgroupByEmployeeTagandcommonTagTypenow supportgroupShiftsPerDayLimit.groupShiftsPerDayMax, capping how many different shift hours an employee group may work on the same day. SettinggroupShiftsPerDayMax: 1requires the group to work identical shift hours whenever they share a day together, while higher values allow the group to split across that many different shift hours.groupShiftsPerDayLimitrequires bothgroupByEmployeeTagandcommonTagTypeto be set. This is a preview feature subject to change. See Limiting how many different shift hours a group can work per day for more details.
- Maintenance release updating dependencies to deliver security updates and minor performance improvements.
- Maintenance release updating dependencies to deliver security updates and minor performance improvements.
new
improved
fixed
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Pickup & Delivery Routing
Full constraint lists, region-aware login, and smarter FSR replanning
- See a model's full constraint list: A model's information page now shows its complete, always-current list of constraints, grouped by category and sorted alphabetically, so you can quickly see which constraints a model supports. See information page for more details.
- Select the right region from the login screen: The login screen now includes a region switcher, so if you land on the wrong Timefold environment you can jump straight to the Europe or United States login without knowing its URL. See Timefold environment for more details.
- Optionally stop rest periods from being broken by absences (preview): Minutes between shifts rules now support theabsenceModefield. When set toABSENCE_AWARE, the rule excludes minutes during which the employee is fully unavailable within the gap between two shifts before comparing the gap againstminimumMinutesBetweenShiftsormaximumMinutesBetweenShifts. This means an employee can't use time off to satisfy a required rest period, and the rule doesn't treat a long absence between shifts as an excessive gap.absenceModedefaults toABSENCE_UNAWARE. This is a preview feature subject to change. See Minutes between shifts for more details.
- Temporarily change a vehicle's coverage area for a single shift: A vehicle shift'srequiredAreaandpreferredAreacan now be overridden perVehicleShift, in addition to the existing vehicle-level fields. This is useful when a technician's coverage area changes only temporarily, for example when they cover a colleague's region for a single shift, without having to change the vehicle's default area for all its other shifts. When a shift defines its ownrequiredAreaorpreferredArea, that value fully replaces the vehicle-level value for that shift only; other shifts of the same vehicle keep using the vehicle-level value. The two fields are overridden independently. If both the vehicle and one of its shifts define an area for the same field, the shift-level value is used and a validation warning is raised. See Overriding the coverage area per vehicle shift for more details.
- Faster replanning for high-priority visits when capacity is tight: In over-constrained replanning scenarios where all shifts are already at full capacity and many visits are still unassigned, finding free space for newly added visits of higher priority is challenging. By default, the initial phase of solving tries to assign every unassigned visit, including lower-priority visits that a previous planning run left unassigned. Attempting to place these lower-priority visits takes a substantial amount of time and leaves less time for more promising optimizations. Timefold now allows specifying what visits should be considered the focus of replanning to overcome these challenges. Timefold will consider visits specified as the replanning focus to be swapped with already assigned, but less important visits. Visits not matching the replanning focus will not be considered during this initial phase to save time. See Real-time planning: focused replanning for more details.
- Avoid unnecessary changes to already-communicated schedules when replanning: Route optimization now includes theMinimize disruption on replanningconstraint, disabled by default, which discourages Timefold from moving an already-assigned visit to a different vehicle or a differentstartServiceTimewhen replanning, unless there is a good enough reason to do so. Unlike pinning, which hard-blocks any change to specific visits, this is a soft preference that applies automatically to every visit that already has an assignment when a solve operation starts. Timefold is still free to move a visit when needed, but a small optimization gain is no longer enough on its own to disrupt an already-communicated schedule. Activate it by settingminimizeDisruptionOnReplanningWeightinconfig.model.overrides. See pinning for more details. See Minimizing disruption on replanning for more details.
- Maintenance release: Maintenance release updating dependencies to deliver security updates and minor performance improvements.
new
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Pickup & Delivery Routing
Easier dataset management, absence-aware shift scheduling, and SLA-aware visit prioritization

- Clearer navigation and faster access to documentation in the new header: The header shown across every page has been redesigned with a clearer two-band layout. It includes a helpful description and a documentation link that adjusts to the page you're currently viewing.
- Manage queued datasets more easily: You can now manually delete a queued dataset instead of waiting for it to start automatically or expire. The solve queue table also has a new Attempts column, showing how many times a dataset has been attempted. See solve queue for more details.
- Re-solve an invalid dataset without resubmitting it: When a dataset ends up in an invalid state, you can now re-solve it directly from a button, instead of submitting a new dataset from scratch. See invalid state for more details.
- See each plan's latest revision on the Plans overview: A plan's row on the Plans overview now shows the scores and metrics of its latest revision, instead of its original submission. This keeps the overview accurate once a plan has been re-solved or patched, without needing to switch to the Revisions tab. See Plans overview for more details.
- Faster solving by pausing automatic score analysis refresh in the UI: The Platform UI no longer automatically re-fetches score analysis while a dataset is still solving. Doing so repeatedly competed for compute resources with solving itself, which could slow it down. You can still follow how scores and output metrics evolve in real time on the dataset's solve graphs, and if you're calling the score analysis endpoint directly, you can still request it as often as you like while a dataset solves. See score analysis for more details.
- Default priority for visits without an explicit priority: Previously, a visit that did not specify its own priority always fell back to the built-in priority 6. A newdefaultPriorityfield inconfig.model.overrideslets you change this fallback for the entire dataset, without having to setpriorityon every visit individually.defaultPriorityaccepts any built-in priority (1-10,opt-1-opt-10) or, when custom priorities are configured, one of your custom priority names. See Default priority for more details.
- New constraints to penalize unassigned visits based on their SLA deadline: Route optimization now includes two new constraints, disabled by default, that penalize visits left unassigned according to how tight theirlatestSlaEndTimeis relative to the other visits in the dataset:Require scheduling mandatory visits with tighter SLA(medium) penalizes unassigned mandatory visits, more so the tighter their SLA deadline is compared to the rest of the dataset, andPrefer scheduling optional visits with tighter SLA(soft) does the same for optional visits. These give you an alternative to the existing priority-basedRequire scheduling mandatory visitsandPrefer scheduling optional visitsconstraints for deciding which visits to leave unassigned when there is not enough capacity to schedule them all. See Penalize unassigned visits based on SLA deadline for more details.
- Maintenance release: This release also updates dependencies to deliver security updates.
- Absence-aware consecutive days worked (preview): Consecutive days worked rules now support theabsenceModefield, which bridges over days an employee is fully unavailable instead of letting them break the consecutive-days streak. When set toABSENCE_AWARE, two worked days separated only by fully-absent days are treated as consecutive: for example, an employee who works Monday and Tuesday, is fully unavailable Wednesday, and works again Thursday, is treated as having worked four consecutive days, not two separate streaks.absenceModedefaults toABSENCE_UNAWARE. This is a preview feature subject to change. See Consecutive days worked for more details.
- More reliable constraint matching for shifts across time zones: Fixed inconsistent tie-breaking for shift-related constraints when shifts spanning different UTC offsets represented the same time instant.
- Maintenance release: This release updates dependencies to deliver security updates and minor performance improvements.
new
improved
fixed
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Pickup & Delivery Routing
Richer dataset comparisons, CSV exports, and smarter visit dependency controls in FSR

- Richer, more readable dataset comparisons: The comparison table now includes a Model info section showing each dataset's model version, solver version, SDK version, build time, build commit, and branch, so you can compare across model versions when benchmarking or debugging. You can now compare constraint scores across sets of datasets, not just individual ones, and the comparison view has several slight UI improvements: columns are easier to read, and tooltips are clearer.
- Export the plans overview to CSV: The plans overview table now has an Export CSV button that downloads the latest 100 plans matching your current search and filters.
- Manually trigger a queued solve: The solve queue now has a "Run now" action that lets you manually trigger a queued execution instead of waiting for it to start automatically.
- Clearer validation for traffic-aware routing: Configuring traffic-aware routing for a map without traffic data now returns a clear validation error instead of an unclear or unexpected failure.
- Consistent tenant switching: Switching tenants now keeps you on the equivalent section of the new tenant, for example a webhook detail page lands on the new tenant's webhooks overview, instead of always redirecting you to the homepage.
- Persisted table column settings: Column visibility and order selections are now persisted across tenant management tables.
- Visit dependencies can now restrict pooling with other visits: By default, other visits can be freely scheduled between the preceding and following visit of a dependency, and multiple dependency pairs can be interleaved with one another. A new poolingTypeattribute onvisitDependencylets you restrict this per dependency, and a newconfig.model.overrides.defaultDependencyPoolingTypesetting lets you change the default for the entire dataset. Setting"poolingType": "DISALLOW_POOLING"prevents any other visit from being scheduled directly between the preceding and following visit.ALLOW_POOLING_VISITSandALLOW_POOLING_DEPENDENCIESallow pooling with only one of ordinary visits or other dependency pairs, respectively. This is useful when, for example, a technician must go straight from an equipment delivery to its installation without an unrelated job in between.
- Visit dependencies can be restricted to the same shift: Previously, the preceding and following visits of a dependency could be scheduled in any vehicle shifts or restricted to vehicle shifts of the same vehicle by "coordination": "SAME_VEHICLE". Timefold now allows restricting the preceding and following visits to the same vehicle shift by specifying"coordination": "SAME_SHIFT".
- Fixed next visit incorrectly pinned when fixed-location breaks precede it: With the default pinNextVisitDuringFreezesetting (ALWAYS), Timefold pins the visit a vehicle is already traveling to whenfreezeTimeis applied. When one or more fixed-location breaks were scheduled before a visit, Timefold could pin that visit as soon as the time of traveling to those fixed breaks was beforefreezeTime, even though the technician had only committed to traveling to (or taking) the fixed break(s), not to the visit itself. Timefold now accounts for fixed-location breaks preceding visits and only pins the visit once the vehicle has actually departed toward it, that is, after the last such break ends.
- Improved solution quality for grouping co-located visits: The Prefer grouping co-located visits constraint encourages assigning visits that share the same location consecutively in a vehicle shift's itinerary, so the vehicle can perform them without traveling in between. Timefold now uses a dedicated move that specifically targets visits sharing the same location and moves them next to each other, either within the same vehicle shift or across vehicle shifts. This results in higher quality solutions when the constraint is enabled.
- More accurate route lines on the map when breaks have a fixed location: The Map view's route lines previously only followed a vehicle shift's start location, visits, and end location, so a fixed-location break in between was not reflected in the drawn road path. Breaks with a location are now included when computing route lines, so the map more accurately traces the road path a vehicle actually takes. Adjacent duplicate locations are also no longer included, so back-to-back stops at the same location no longer produce redundant segments on the map.
- Group employee pairings by employee tag: We have added groupByEmployeeTagto employee pairings to ensure that employee pairings can be grouped based on a tag. This prevents Timefold from assigning employees to shifts at the same time but with different tags of the common tag type. WhencommonTagTypeis used withoutgroupByEmployeeTag, employee pairings are valid if two employees work shifts at the same time with an identical tag of the common tag type. WithgroupByEmployeeTagdefined, all pairings grouped by that tag will be valid only if all shifts worked at the same time have that identical tag of the common tag type. Certain employees may need to work at the same time (employee pairing), work the same type of shift (commonTagType), but also need to be grouped (groupByEmployeeTag). This feature makes it easier to define groups of employees with employee pairings.
- Improved solution quality: Timefold now favors nearby jobs both in construction heuristics and local search, producing better solutions with lower total travel time. In addition, jobs are more frequently pooled (if they allow it), leading to more efficient routes. However, if you do not want jobs to be pooled, be sure to set prohibitJobPoolingtotruefor your jobs, as it will increase the construction heuristic speed.
- Better visibility into travel efficiency and job pooling: The key performance indicators now include the average travel time per stop, as well as the percentage and absolute number of pooled jobs.
new
improved
fixed
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Pickup & Delivery Routing
Read-only Viewer role, Scenario experiments, and monthly and absence-aware rolling window rules in ESS
- Give stakeholders and auditors safe, read-only tenant access: Tenants can now add members with a new Viewer role. Viewers can see everything in a tenant, models, datasets, configuration profiles, and saved comparisons shared with tenant members, but can’t start, edit, or delete datasets, or manage comparisons. This is useful for stakeholders or auditors who only need read access. See Viewer role for details.
- Experiments (preview): Experiments let you compare how your Timefold model performs across different scenarios and datasets in a single run, instead of manually submitting and comparing individual datasets. You define the variables up front, and the platform runs all combinations automatically, producing a comparison report where each column represents a scenario. This saves time compared to submitting each combination by hand, and experiments run on a separate solve queue, so they don’t affect or slow down your production solves. Experiments are available in preview starting with this release. See Experiments for more information and to request access.

- More accurate score analysis and recommendations with configuration profile overrides: Overrides specified in a configuration profile are now applied when calling the score analysis and recommendations endpoints. Previously, these endpoints reflected the dataset’s original configuration even when overrides had been applied. Results now accurately reflect the profile you configured, giving more accurate score analysis and recommendations.
- Interpret and share dataset comparisons more easily: Comparisons can now show diffs as a percentage instead of only an absolute value, making it easier to judge the relative impact of a change. The radar diagram in dataset comparisons can also be exported as an SVG file, making it easier to include in reports and presentations. See Comparing datasets for more details.
- Back up and share configuration profiles as JSON files: Configuration profiles can now be exported and imported as JSON files. This makes it easy to back up a profile before making risky changes, or to share a profile configuration between team members or environments. See Export and import profiles for more details.
- Improved documentation search: The documentation site now has a dedicated search page, in addition to the in-page search modal. From the search modal, click "See all results" to open the full search results page, which supports paging and filtering by book and product.
- See your most-used destinations first in the command palette: Opening the command palette without typing a query now shows your recently used entries first, topped up with the highest-priority entries, instead of an empty dialog. See Using the Command Palette for more details.
- Fixed next visit incorrectly pinned when fixed-location breaks precede it: With the defaultpinNextVisitDuringFreezesetting (ALWAYS), Timefold pins the visit a vehicle is already travelling to when freezeTime is applied. When one or more fixed-location breaks were scheduled before a visit, Timefold could pin that visit as soon as the time of travelling to those fixed breaks was before freezeTime, even though the technician had only committed to travelling to (or taking) the fixed break(s), not to the visit itself. Timefold now accounts for fixed-location breaks preceding visits and only pins the visit once the vehicle has actually departed towards it, that is, after the last such break ends. See Finer control over pinning with freezeTime for more details.
- Fewer unnecessary visit delays when travel times are asymmetric: With asymmetric travel times between locations (the travel time from A to B different from the travel time from B to A), Timefold could wrongly apply a fixed break between two visits instead of being deferred past both of them, even though the vehicle could not actually reach the break in time from the earlier visit. This means a fixed break could delay a visit that could have been scheduled earlier, resulting in a worse solution than necessary.
- No more infeasible solutions from inconsistent fixed-visit start times: When a visit was pinned to a specificstartServiceTimeand vehicle shift, but the input was inconsistent (for example, because the technician could not actually start at the specified time given the travel distances involved) Timefold would introduce hard score violations when trying to enforce the exact fixed start service time. Timefold now handles this gracefully by computing the feasible start service time for each fixed visit during preprocessing. See Changelog for more details and upgrade instructions.
- No more solver hangs when a break overlaps a visit with actuals: When a visit with anactualStartServiceTimeoverlapped with a fixed break, Timefold could get stuck in an infinite loop while repeatedly trying to apply the break. This means Timefold should no longer get stuck on such inputs.
- Account for holidays when calculating delays between dependent visits: ThedateAdjusterConfigurationobject in the model input now has a holidays field to modify the behavior of theNEXT_WORKING_DAYadjuster specification to be used for delays between dependent visits. It takes an array of ISO 8601 dates which are exceptions to the regular working days as stated in workingDays. For example, this allows accounting for bank holidays correctly. For further information, consult the documentation on visit dependencies with delay and the adjuster functions.
- No more overlapping fixed and floating breaks in the schedule: Timefold could fail to apply a fixed break that should have applied, when the visit preceding it was delayed by a floating break. This could result in a fixed break overlapping with a floating break in the schedule. Timefold now correctly applies the fixed break in this scenario.
- Recommendations for shifts with no eligible employees: The recommendations API now returns employee suggestions even when no employee meets all hard constraints for a shift. Previously, the solver didn’t return recommendations that broke hard constraints. Now, the solver returns the top recommendations, even if those recommendations break hard constraints. For more information, see Recommendations.
- Monthly rolling window rules for more flexible scheduling: Rolling window rules now supportMONTHLYrolling window type. This allows you to define rules that apply on a calendar month basis, providing greater flexibility in scheduling and planning. See Minutes worked in a rolling window for more details on rolling window rules.
- Deprecated confusing recommendation endpoint: We have deprecated the following endpoint to avoid confusion with other recommendation endpoints.POST /v1/schedules/{id}/recommendations/recommend-employeesPlease use this endpoint instead:POST /v1/schedules/recommendations/recommend-employeesFor more information, see Recommendations.
- Absence-aware rolling window rules (preview): Rolling window rules now support theabsenceModefield, which scales the effective limit proportionally based on each employee’s availability within the rolling window. See Changelog for use cases and details.
- Be warned when a shift references an unknown employee: A shift, or a shift’s preferred, unpreferred, or prohibited employee list, that references an employee ID not present in the schedule was previously not validated at all. This is now reported as aSHIFT_UNKNOWN_EMPLOYEEwarning. The schedule is accepted and solved normally, with the unknown employee reference surfaced so you can review and correct it.
- Evaluate patient transport scenarios with a new NEMT demo dataset: The list of demo datasets has been extended with a new use case based demo dataset for Non-Emergency Medical Transportation (NEMT). The NEMT demo dataset includes a set of jobs and driver shifts that represent a typical Non-Emergency Medical Transportation scenario, including multiple stops for pick-up and drop-off of patients. It contains multiple legs for patients (home to medical facility and back) as well as time windows and skill requirements.
- More realistic location distribution in demo datasets: The location generator for the demo datasets has been improved to generate more realistic locations. Locations will now be generated with more density around the city center and less density in the outskirts, which better reflects real-world scenarios.
new
improved
fixed
Timefold Platform
Employee Shift Scheduling
Field Service Routing
Task Scheduling
Pickup & Delivery Routing
Task Scheduling launches, batch recommendations for ESS, and smarter comparison tools
- Constraint scores in run comparison: The comparison table now includes a "Constraint scores" group that shows the per-constraint score breakdown for each dataset. Scores are color-coded and sorted using the score analysis sort order. This is available when comparing single datasets; support for grouped dataset columns is planned for a future release. This is e.g. useful to see the impact on specific constraint score during goal alignment experiments See Comparing datasets for details.

- Sort constraints in score analysis: The constraint table in score analysis now supports sorting by name (useful to get started with a model), number of matches (useful to explore justifications), or constraint weight, in addition to the default sort by score. Each sort option orders constraints within their group first, then orders the groups themselves by the same criterion. See Score analysis for more details.
- Power-tune the default smart termination: Solving on the platform stops automatically once score improvements diminish; this is the default termination strategy, and for most datasets the defaults work well out of the box and is the best balance between time, cost and solution quality. For specific datasets where you want more control, "Advanced configuration" in a configuration profile now exposes two parameters: sliding window duration and minimum improvement ratio. Use the Configuration Profiles UI to learn about the parameters and tweak them.
- Several additional bug fixes, security fixes, and stability and UI improvements.
- Next working day date adjuster for visit dependencies: When a multi-day job is split across two visits, you can now specify that the follow-up visit must start on the next working day, without having to hardcode a specific weekday. SetminStartDateAdjusterormaxStartDateAdjustertoNEXT_WORKING_DAYonminDelayToormaxDelayToin the visit dependency, and the model will always push the second visit to the next business day, regardless of which day the first visit falls on. Working days default to Monday–Friday and can be customized via the newworkingDaysfield indateAdjusterConfiguration. See Visit dependencies for details.
- Bulk visit recommendations now include infeasible results: Bulk visit recommendations now always return a result, even when no fully feasible assignment exists. Infeasible recommendations are ranked below feasible ones and include hard score violations, so you can see why an assignment doesn't work rather than receiving an empty response.
- durationAddedForFirstVisitOnLocation now configurable in configuration profiles: This field is now available in the model configuration section of configuration profiles for FSR. This lets you set a default overhead duration added to the first visit at any location, eg. to account for parking or building access, without having to pass it in every API call. See this changelog update for more details.
- Vehicles can travel during waiting time before a fixed break: When a vehicle shift defines multiple fixed breaks, the vehicle can utilize waiting time before a fixed break to travel to the next visit or the next location break, which will result in more efficient schedules. See upgrade to the latest version for more details.
- Several additional bug fixes and performance improvements.
- Batch recommendations: When multiple shifts need to be filled at once, you can now get recommendations for all of them in a single API call. Two modes are available, each as its own endpoint:recommend-employees-batch-per-shift: returns a ranked list of recommended employees per shift. Use this to fill shifts independently, without making a separate API call for each one.recommend-employees-batch-global: returns a single ranked list across all shifts, answering "which shift should I assign next?". Use this when you want to fill shifts one by one in the optimal order. For more information see Batch recommendations.
- Historic shift and shift group counts available in input metrics: Input metrics now report the number of historic shifts and shift groups (historicShifts, historicShiftGroups) in the input dataset. This makes it easy to verify the right amount of historical data is attached, especially when using rolling-window constraints. See Input metrics for details.
- maximumTimeBurden now configurable in configuration profiles: This field is now available in the model configuration section of configuration profiles for PDR. This lets you set the maximum extra time burden imposed on an ongoing job when a new job is added to the same vehicle, without having to pass it in every API call.
- This release includes security fixes and stability improvements.
