1 - Example configurations

Examples of how to configure Schedules

Using basic and nested schedules, it is possible to create almost any configuration of on-call schedule that you require as demonstrated by the examples below.

If none of these examples meet your needs, and you need help creating a schedule to match your requirements, please get in touch.

1.1 - Weekly Shift

Demonstrates a simple schedule changing between members once a week at a specified date and time.

Shift Configuration Entries

Day:Hour:Minute:Primary:Secondary:
Mon1000BEST_MEMBER[Not assigned]

Sample Assignment

2023-07-24 10:00 person2@example.com
2023-07-31 10:00 person3@example.com
2023-08-07 10:00 person1@example.com
2023-08-14 10:00 person3@example.com

Assignment Details

This configuration results in On-Call Optimizer balancing team members using a single shift type covering 7 days.

While this is a common rotation pattern for many teams, the full benefits of On-Call Optimizer will not be experienced in this configuration due to the limited number of shifts available to be matched to team member constraints and preferences.

It is recommended that you consider migrating to one of the later examples in the configuration library which provide more flexibility to schedule around team member constraints and preferences.

Return to the list of other examples

1.2 - Daily Shift

Demonstrates a simple schedule changing between members at 9am every day.

Shift Configuration Entries

Day:Hour:Minute:Primary:Secondary:
Daily0900BEST_MEMBER[Not assigned]

Sample Assignment

2023-07-24 10:00 member2@example.com    # Mon
2023-07-25 10:00 member1@example.com    # Tue
2023-07-26 10:00 member3@example.com    # Wed
2023-07-27 10:00 member4@example.com    # Thu
2023-07-28 10:00 member3@example.com    # Fri
2023-07-29 10:00 member4@example.com    # Sat
2023-07-30 10:00 member1@example.com    # Sun
2023-07-31 10:00 member2@example.com    # Mon

Assignment Details

This configuration results in On-Call Optimizer balancing team members using a single shift type covering each 24 hour period, with no differentiation made between weekdays and weekends in the balancing process.

Typically each member should be assigned similar numbers of shifts for each different day of the week by the default behaviour of On-Call Optimizer’s algorithm, however if team members persistently block or prefer particular days (e.g. weekends) via their availability information, other members may find themselves consistently assigned to particular days of the week without any schedule imbalance arising.

Enforcing Weekday vs Weekend Balance

An alternative configuration that ensures all team members are assigned balanced weekday and weekend day shifts despite individual preferences would be:

Day:Hour:Minute:Primary:Secondary:
Weekdays0900BEST_MEMBER[Not assigned]
Weekends0900BEST_MEMBER[Not assigned]

This configuration results in On-Call Optimizer using two shift types for balancing purposes which contain:

  1. All 24-hour duration shifts starting Mon-Fri.
  2. All 24-hour duration shifts starting on Sat and Sun.

On-Call Optimizer aims for each member to have a balanced share of the shifts within each shift type.

Return to the list of other examples

1.3 - Business hours only shifts (schedule contains gaps)

Demonstrates a schedule assigning members only during business hours with gaps in between the shifts.

In situations where out-of-hours coverage is not required, you can create a schedule which only assigns members during particular time periods, leaving gaps with no assignee(s) scheduled at all other times.

The following example demonstrates a shift configuration that will create shifts covering Mon-Fri 9am-5pm in the schedule’s time zone. No shift or assignee will be available outside those times.

Shift Configuration Entries

Day:Hour:Minute:Primary:Secondary:
Weekdays0900BEST_MEMBER[Not assigned]
Weekdays1700[Not assigned][Not assigned]

Sample Assignment

2023-07-24 09:00 person2@example.com    # Mon
# 2023-07-24 17:00 NO_ASSIGNEE
2023-07-25 09:00 person1@example.com    # Tue
# 2023-07-25 17:00 NO_ASSIGNEE
2023-07-26 09:00 person5@example.com    # Wed
# 2023-07-26 17:00 NO_ASSIGNEE
2023-07-27 09:00 person4@example.com    # Thu
# 2023-07-27 17:00 NO_ASSIGNEE
2023-07-28 09:00 person3@example.com    # Fri
# 2023-07-28 17:00 NO_ASSIGNEE
2023-07-31 09:00 person5@example.com    # Mon
# 2023-07-31 17:00 NO_ASSIGNEE

Assignment Details

This configuration results in On-Call Optimizer balancing team members using a single shift type covering each 8 hour period on Mon-Fri.

Return to the list of other examples

1.4 - Separate business and after-hours shifts (within team)

Demonstrates a schedule with different business and after-hours shifts every day.

A common motivation for using a schedule configuration of this type would be to avoid having any team member scheduled for a consecutive 24hr period.

Shift Configuration Entries

Day:Hour:Minute:Primary:Secondary:
Daily0900BEST_MEMBER[Not assigned]
Daily1700BEST_MEMBER[Not assigned]

Sample Assignment

2023-07-24 09:00 person2@example.com    # Mon
2023-07-24 17:00 person5@example.com
2023-07-25 09:00 person1@example.com    # Tue
2023-07-25 17:00 person4@example.com
2023-07-26 09:00 person5@example.com    # Wed
2023-07-26 17:00 person3@example.com
2023-07-27 09:00 person4@example.com    # Thu
2023-07-27 17:00 person2@example.com
2023-07-28 09:00 person3@example.com    # Fri
2023-07-28 17:00 person1@example.com
2023-07-29 09:00 person5@example.com    # Sat
2023-07-29 17:00 person2@example.com

Assignment Details

This configuration results in On-Call Optimizer balancing team members using two shift types which contain:

  1. All 8-hour duration shifts starting 9am.
  2. All 16-hour duration shifts starting 5pm.

On-Call Optimizer aims for each member to have a balanced share of the shifts within each shift type.

Return to the list of other examples

1.5 - Separate business and after-hours shifts (delegated to a partner team)

Demonstrates a schedule with after-hours shifts handled by a different partner team.

This schedule configuration is commonly used when two teams in different time-zones are able to provide coverage during different hours of the day.

Note how (unlike the basic after hours) example where every day of the week is treated the same, this example also demonstrates the use of the Weekdays wildcard in the shift configuration to achieve the result of having Saturday and Sunday also treated as after-hours and assigned to the partner team for the full 48-hour period.

Shift Configuration Entries

Day:Hour:Minute:Primary:Secondary:
Weekdays0900BEST_MEMBER[Not assigned]
Weekdays1700partner-rotation[Not assigned]

Sample Assignment for the main schedule

2023-07-24 09:00 person2@example.com    # Mon
2023-07-24 17:00 partner-rotation
2023-07-25 09:00 person1@example.com    # Tue
2023-07-25 17:00 partner-rotation
2023-07-26 09:00 person3@example.com    # Wed
2023-07-26 17:00 partner-rotation
2023-07-27 09:00 person2@example.com    # Thu
2023-07-27 17:00 partner-rotation
2023-07-28 09:00 person3@example.com    # Fri
2023-07-28 17:00 partner-rotation
2023-07-31 09:00 person1@example.com    # Mon

Assignment Details

This configuration results in On-Call Optimizer balancing team members in a very similar way to the business hours example, using a single shift type covering each 8 hour period on Mon-Fri.

There are two additional shift types (16-hour overnight shifts, and 64-hour weekend shifts) assigned to the partner team in the main schedule, however as explained below, these shift types are not used for balance and assignment purposes.

Partner Team Schedule

The shifts delegated to the partner team will be assigned in the final output of this schedule by referencing the existing assignments of the referenced partner schedule which are unchanged by the fact that it has been referenced from this schedule. This allows the partner team to use any rotation configuration they like, independently of any scheduling choices made in the the main schedule.

In this example, the partner team is using the Simple Daily Rotation configuration which assigns a single shift per day, and therefore will continue to aim to assign a balanced number of daily shifts to each member.

Fully Rendered Schedule

When viewed in the On-Call Optimizer web UI, or exported to an on-call products the “fully rendered” schedule combining the above two rotations will be as follows:

2023-07-24 09:00 person2@example.com    # Mon
2023-07-24 17:00 member2@example.com    # Mon 10:00 in partner-rotation America/Los_Angeles
2023-07-25 09:00 person1@example.com    # Tue
2023-07-25 17:00 member1@example.com    # Tue 10:00 in partner-rotation America/Los_Angeles
2023-07-26 09:00 person3@example.com    # Wed
2023-07-26 17:00 member3@example.com    # Wed 10:00 in partner-rotation America/Los_Angeles
2023-07-27 09:00 person2@example.com    # Thu
2023-07-27 17:00 member2@example.com    # Thu 10:00 in partner-rotation America/Los_Angeles
2023-07-28 09:00 person3@example.com    # Fri
2023-07-28 17:00 member3@example.com    # Fri 10:00 in partner-rotation America/Los_Angeles
2023-07-29 17:00 member3@example.com    # Sat 10:00 in partner-rotation America/Los_Angeles
2023-07-30 17:00 member1@example.com    # Sun 10:00 in partner-rotation America/Los_Angeles
2023-07-31 09:00 person1@example.com    # Mon
2023-07-31 17:00 member2@example.com    # Mon 10:00 in partner-rotation America/Los_Angeles

Return to the list of other examples

1.6 - Follow the sun (2 locations)

Demonstrates a schedule balancing two 12-hour shifts between a UK and US west coast pair of teams.

This schedule configuration enables each team to have the majority of their on-call hours within typical day/waking hours. It involves 3 separate schedules, one for each of the local teams and a third schedule which is then used to co-ordinate and join the local schedules together.

Main Schedule Shift Configuration Entries

The main schedule is configured in the America/Los_Angeles time zone and uses a simple shift configuration pattern that rotates between a nested schedule for each team at the appropriate time each day.

Day:Hour:Minute:Primary:Secondary:
Weekdays1000sfo-team[Not assigned]
Weekdays2200lon-team[Not assigned]

Sample shifts

2023-07-24 10:00 sfo-team
2023-07-24 22:00 lon-team
2023-07-25 10:00 sfo-team
2023-07-25 22:00 lon-team
2023-07-26 10:00 sfo-team
2023-07-26 22:00 lon-team
2023-07-27 10:00 sfo-team
2023-07-27 22:00 lon-team
2023-07-28 10:00 sfo-team
2023-07-28 22:00 lon-team
2023-07-31 10:00 sfo-team

London Team Shift Configuration Entries

The London team’s schedule is configured in the GMT time zone and the team has chosen to schedule themselves using a 4 day/3 day split across the week.

Day:Hour:Minute:Primary:Secondary:
Mon0600BEST_MEMBER[Not assigned]
Fri0600BEST_MEMBER[Not assigned]

The 06:00 UTC shift start time is selected to match the 22:00 America/Los_Angeles shift start time in the main schedule.

Sample shifts

2023-07-24 06:00 london-member1@example.com    # Mon
2023-07-28 06:00 london-member3@example.com    # Fri
2023-07-31 06:00 london-member2@example.com    # Mon
2023-08-04 06:00 london-member4@example.com    # Fri
2023-08-07 06:00 london-member3@example.com    # Mon
2023-08-11 06:00 london-member1@example.com    # Fri
2023-08-14 06:00 london-member4@example.com    # Mon
2023-08-18 06:00 london-member2@example.com    # Fri

US Team

The US team uses a simple daily rotation (specifically the Simple Daily Rotation example ).

Sample shifts

2023-07-24 10:00 member2@example.com    # Mon
2023-07-25 10:00 member1@example.com    # Tue
2023-07-26 10:00 member3@example.com    # Wed
2023-07-27 10:00 member4@example.com    # Thu
2023-07-28 10:00 member3@example.com    # Fri
2023-07-29 10:00 member4@example.com    # Sat
2023-07-30 10:00 member1@example.com    # Sun
2023-07-31 10:00 member2@example.com    # Mon

Fully Rendered Schedule

When viewed in the On-Call Optimizer web UI, or exported to an on-call products the “fully rendered” schedule combining combining all of the above configuration will result in the following shifts:

# Rendered in UTC
2023-07-24 05:00 london-member1@example.com    # Mon 6am LON / 10pm Sun SFO
2023-07-24 17:00 member2@example.com           # Mon 6pm LON / 10am Mon SFO
2023-07-25 05:00 london-member1@example.com    # Tue 6am LON / 10pm Mon SFO
2023-07-25 17:00 member1@example.com           # Tue 6pm LON / 10am Tue SFO
2023-07-26 05:00 london-member1@example.com    # Wed 6am LON / 10pm Tue SFO
2023-07-26 17:00 member3@example.com           # Wed 6pm LON / 10am Wed SFO
2023-07-27 05:00 london-member1@example.com    # Thu 6am LON / 10pm Wed SFO
2023-07-27 17:00 member4@example.com           # Thu 6pm LON / 10am Thu SFO
2023-07-28 05:00 london-member3@example.com    # Fri 6am LON / 10pm Thu SFO
2023-07-28 17:00 member3@example.com           # Fri 6pm LON / 10am Fri SFO
2023-07-29 05:00 london-member3@example.com    # Sat 6am LON / 10pm Fri SFO
2023-07-29 17:00 member4@example.com           # Sat 6pm LON / 10am Sat SFO
2023-07-30 05:00 london-member3@example.com    # Sun 6am LON / 10pm Sat SFO
2023-07-30 17:00 member1@example.com           # Sun 6pm LON / 10am Sun SFO
2023-07-31 05:00 london-member2@example.com    # Mon 6am LON / 10pm Sun SFO
2023-07-31 17:00 member2@example.com           # Mon 6pm LON / 10am Mon SFO

Return to the list of other examples

1.7 - Follow the sun (multiple locations)

Demonstrates a schedule balancing three 8-hour shifts that follow the sun around the globe.

In this example there are 3 teams, one in London, one in Sydney and one in San Francisco, who work together to provide an overall on-call schedule. The London and San Francisco teams are equally sized and participate every day of the week, while the Sydney team with fewer people only participates during their week days, with the weekend shifts covered only from London and San Francisco.

As with the more basic follow the sun example this example is constructed with one schedule per team, combined with a fourth co-ordinating schedule that is used to provide the overall schedule.

Main Schedule Shift Configuration Entries

The main schedule is configured in the Australia/Sydney time zone in order to easily highlight the shift start times that relate to weekend coverage being provded in London and San Francisco.

The first 3 shift configurations follow a simple repeating pattern for each of the weekdays, while the final 3 shift configuration entries deal with the slightly more complex set of shifts required to implement the different shift lengths for London and San Francisco that are required to provide the desired weekend coverage.

Day:Hour:Minute:Primary:Secondary:
Weekdays1000syd-team[Not assigned]
Weekdays1800lon-team[Not assigned]
Weekdays0200sfo-team[Not assigned]
Sat1002sfo-team[Not assigned]
Sun,Mon0300sfo-team[Not assigned]
Weekends1500lon-team[Not assigned]

Sample shifts

2023-07-24 03:00 sfo-team
2023-07-24 10:00 syd-team
2023-07-24 18:00 lon-team
2023-07-25 02:00 sfo-team
2023-07-25 10:00 syd-team
2023-07-25 18:00 lon-team
2023-07-26 02:00 sfo-team
2023-07-26 10:00 syd-team
2023-07-26 18:00 lon-team
2023-07-27 02:00 sfo-team
2023-07-27 10:00 syd-team
2023-07-27 18:00 lon-team
2023-07-28 02:00 sfo-team
2023-07-28 10:00 syd-team
2023-07-28 18:00 lon-team
2023-07-29 02:00 sfo-team
2023-07-29 15:00 lon-team
2023-07-30 03:00 sfo-team
2023-07-30 15:00 lon-team
2023-07-31 03:00 sfo-team
2023-07-31 10:00 syd-team
2023-07-31 18:00 lon-team

London Team Shift Configuration Entries

The London team schedule (configured in the GMT time zone) uses the same 4 day/3 day split as seen in the previous follow the sun example.

Day:Hour:Minute:Primary:Secondary:
Mon0600BEST_MEMBER[Not assigned]
Fri0600BEST_MEMBER[Not assigned]

The 06:00 UTC shift start time is selected to match the 22:00 America/Los_Angeles shift start time in the main schedule.

Sample shifts

2023-07-24 06:00 london-member1@example.com    # Mon
2023-07-28 06:00 london-member3@example.com    # Fri
2023-07-31 06:00 london-member2@example.com    # Mon
2023-08-04 06:00 london-member4@example.com    # Fri
2023-08-07 06:00 london-member3@example.com    # Mon
2023-08-11 06:00 london-member1@example.com    # Fri
2023-08-14 06:00 london-member4@example.com    # Mon
2023-08-18 06:00 london-member2@example.com    # Fri

US Team

The US team uses a simple daily rotation (specifically the Simple Daily Rotation example ).

Sample shifts

2023-07-24 10:00 member2@example.com    # Mon
2023-07-25 10:00 member1@example.com    # Tue
2023-07-26 10:00 member3@example.com    # Wed
2023-07-27 10:00 member4@example.com    # Thu
2023-07-28 10:00 member3@example.com    # Fri
2023-07-29 10:00 member4@example.com    # Sat
2023-07-30 10:00 member1@example.com    # Sun
2023-07-31 10:00 member2@example.com    # Mon

Sydney Team

The small Sydney team uses basic week long rotations.

2023-07-24 10:00 person2@example.com
2023-07-31 10:00 person3@example.com
2023-08-07 10:00 person1@example.com
2023-08-14 10:00 person3@example.com

Fully Rendered Schedule

When viewed in the On-Call Optimizer web UI, or exported to an on-call products the “fully rendered” schedule combining all the individual shifts will be as follows:

# Rendered in UTC
2023-07-24 00:00 person2@example.com           # Mon 10am SYD / Sun 5pm SFO / Mon 1am LON
2023-07-24 08:00 london-member1@example.com    # Mon 6pm SYD / Mon 1am SFO / Mon 9am LON
2023-07-24 16:00 member2@example.com           # Tue 2am SYD / Mon 9am SFO / Mon 5pm LON
2023-07-25 00:00 person2@example.com           # Tue 10am SYD / Mon 5pm SFO / Tue 1am LON
2023-07-25 08:00 london-member1@example.com    # Tue 6pm SYD / Tue 1am SFO / Tue 9am LON
2023-07-25 16:00 member1@example.com           # Wed 2am SYD / Tue 9am SFO / Tue 5pm LON
2023-07-26 00:00 person2@example.com           # Wed 10am SYD / Tue 5pm SFO / Wed 1am LON
2023-07-26 08:00 london-member1@example.com    # Wed 6pm SYD / Wed 1am SFO / Wed 9am LON
2023-07-26 16:00 member3@example.com           # Thu 2am SYD / Wed 9am SFO / Wed 5pm LON
2023-07-27 00:00 person2@example.com           # Thu 10am SYD / Wed 5pm SFO / Thu 1am LON
2023-07-27 08:00 london-member1@example.com    # Thu 6pm SYD / Thu 1am SFO / Thu 9am LON
2023-07-27 16:00 member4@example.com           # Fri 2am SYD / Thu 9am SFO / Thu 5pm LON
2023-07-28 00:00 person2@example.com           # Fri 10am SYD / Thu 5pm SFO / Fri 1am LON
2023-07-28 08:00 london-member3@example.com    # Fri 6pm SYD / Fri 1am SFO / Fri 9am LON
2023-07-28 16:00 member3@example.com           # Sat 2am SYD / Fri 9am SFO / Fri 5pm LON
2023-07-29 05:00 london-member3@example.com    # Sat 3pm SYD / Fri 10pm SFO / Sat 6am LON
2023-07-29 17:00 member4@example.com           # Sun 3am SYD / Sat 10am SFO / Sat 6pm LON
2023-07-30 05:00 london-member3@example.com    # Sun 3pm SYD / Sat 10pm SFO / Sun 6am LON
2023-07-30 17:00 member1@example.com           # Mon 3am SYD / Sun 10am SFO / Sat 6pm LON
2023-07-31 00:00 person3@example.com           # Mon 10am SYD / Sun 5pm SFO / Mon 1am LON

Return to the list of other examples

2 - Constraint Optimizing Algorithm

Learn how On-Call Optimizer creates balanced schedules using availability information.

On-Call Optimizer uses constraint programming algorithms to solve the challenge of producing an optimal schedule.

Goals

To determine what an optimal schedule looks like, On-Call Optimizer is programmed with a series of goals that are desired for a schedule. A perfect schedule would meet every goal, an optimal schedule comes as close as possible to meeting each goal given the constraints dictated by the shift configuration of the schedule and the availability information for each of the members.

The goals that On-Call Optimizer tries to achieve focus on maximizing the balance of the schedule over the mid to long term, while also maintaining the quality of each individual assignment in the short term. Typical goals that On-Call Optimizer tries to achieve include:

  • A member should not be assigned to a shift blocked in their availability information.
  • Each member should have a fair share of shifts, taking into account weekends, holidays and out-of-business hours shifts as distinct types.
  • A member should be assigned a shift marked as preferred in their availability information.
  • A member should not have consecutive shifts.

High Level Overview

On-Call Optimizer uses a constraint satisfying algorithm to find an solution (aka assignment) that is both feasible and comes closest to meeting each goal.

The input to the algorithm starts with a set of variables referenced by a tuple of (start time, assignee role, member). So for an example assignment for a single primary assignee in a schedule of 5 members for 7 shifts, there will be 35 different shift variables input into the algorithm.

Next hard constraints which determine whether or not a particular assignment is feasible or not are configured. In the simplest case the only hard constraint would be that the sum of all variables matching (start time, assignee type, *) must be equal to 1 - e.g. only solutions that assign a single member to a shift are feasible.

After the hard constraints additional constraints representing each desired goal for the schedule are configured. Goal based constraints utilize a weight factor rather than requiring equality to a fixed value and match against particular combination of shift variables that are set to represent each potential solution, A score is calculated for each constraint in each potential solution by multiplying the value of the matching shift variables against the weight of the constraint. The overall sum of these scored constraints is reported as the “cost” of the assignment solution, and the assignment solution with the lowest overall cost represents the optimal assignment given the set of inputs.

Example weighting factors

Illustrative weighting factors for the typical goals above might look like the following:

  • Any assignment matching a blocked shift: >2.0, ensuring that such assignments are only ever used as a last resort if no other possibilities exist.
  • Any shift assignment above or below the ideal balance are penalized: 1.0
  • Any assignment of a preferred shift: -0.5, the negative weighting results in a favourable score, making any assignment containing this shift preferred over an assignment that does not.
  • Any consecutive shift assignment for a member: 0.3

In practice the specific weighting factors used are much more complex and are selected based on On-Call Optimizer’s accumulated expertise of the ideal weightings for different schedule configuration patterns.

BEST_MEMBER

The “BEST_MEMBER” placeholder is used in the shift configuration for each schedule to denote that the assignee for the specified shift should be chosen from among the members of the schedule based on the output of the above algorithm.

Therefore the “BEST_MEMBER” for a shift will be the member assigned to the shift variable for that shift in the solution that resulted in the lowest overall cost.

Importantly “best” does not mean “perfect”. In situations where there are competing constraints, the best solution may require assigning a member to consecutive shifts or ignoring their preferences in order to achieve an overall optimum assignment.

3 - Extension logic

Learn how On-Call Optimizer generates future shift entries

On-Call Optimizer shifts are defined by the day of the week, hour and minute at which they start (e.g. Mon 10:00) and therefore no shift can ever be longer than 7 calendar days. The following details describe at a high-level how On-Call Optimizer uses this configuration data to generate specific shifts with fully-defined start and end times.

Basic procedure

Given a starting timestamp:

  1. Loop through all defined shift configurations; discard any with a starting day that does not match the weekday.
  2. From the remaining shift configurations; discard any with a starting hour before the hour of the day.
  3. From the remaining shift configurations; discard any with a starting minute before the minute of the hour.
    • Sort any remaining shift configurations by hour, then minute in ascending order and then select the first (earliest hour, minute). The Day, Hour and Minute from this selected configuration is the starting time of the next shift in the schedule.
    • If no matching shift configurations remains, advance the timestamp to the end of the day (00:00 next day) and repeat the process.

Use

The basic procedure can be used directly with an arbitrary timestamp to find the starting time of the next shift in the schedule.

To find the starting time of the shift that will follow an existing shift in the schedule, the procedure must be executed with the starting timestamp set to 1 minute after the starting time of the shift to be followed - any end time for the existing shift should be ignored. See the example below for an illustration of why this is important.

All time and date calculations during the extension process must be performed with respect to the time zone of the schedule itself.

Matching of day wildcards

  • A shift configured with the day set to the Daily wildcard will match any timestamp.
  • A shift configured with the day set to the Weekdays wildcard will match any timestamp, where the abbreviated name of the day of the week (e.g. %a strftime(3) component) in the time zone of the schedule is one of the Mon-Fri set.
  • A shift configured with the day set to the Weekends wildcard will match any timestamp, where the abbreviated name of the day of the week (e.g. %a strftime(3) component) in the time zone of the schedule is one of Sat or Sun.

Examples

For simplicity these examples do not display the time zone, which is not relevant but can be assumed to be UTC.

Basic

Assuming a shift configuration of Mon 10:00, Fri 17:00, when executed for the week starting April 1st 2024, the next 4 returned shifts would be:

  • 2024-04-01 10:00
  • 2024-04-05 10:00
  • 2024-04-08 10:00
  • 2024-04-12 10:00

This provides a schedule with a ~5-day shift covering the working week, and a ~2-day shift covering the weekend.

Daily and Weekends

Assuming a shift configuration of Daily 10:00, Weekends 22:00, when executed on April 4th 2024, the next 7 returned shifts would be:

  • 2024-04-04 10:00
  • 2024-04-05 10:00
  • 2024-04-06 10:00
  • 2024-04-06 22:00
  • 2024-04-07 10:00
  • 2024-04-07 22:00
  • 2024-04-08 10:00

This provides a schedule with 24-hour shifts during weekdays, but adds an additional “overnight” shift on weekends resulting in a split of each weekend day (Sat, Sun) into two 12-hour shifts.

Extension after configuration change

This example explains why it is important to extend from 1 minute after the start of the final existing shift, rather than from the end of the existing shift.

  • Original shift configuration: Mon 10:00
  • Existing shift: Mon 1st Apr 2024 10:00 - Mon 8th Apr 2024 09:59
  • New shift configuration: Mon 09:00
  • Expected next shift: Mon 8th Apr 2024 09:00 - Mon 15th Apr 2024 08:59

Moving the expected start time back by 1 hour creates an ambiguous situation for the schedule, either the next shift needs to start 1 hour prior to the end of the existing last shift, or if the end of the last shift is strictly observed and extension begins from 10am on Monday the 8th, the next starting time is not until 9am the following Monday, creating a 7-day gap in the schedule!

While either scenario will likely require user input to resolve and confirm the desired intention, On-Call Optimizer prefers to generate schedules that provide continuous coverage and therefore adopts the rule describe above - extension starts from the minute after the last existing shift starts, resulting in shifts that overlap the existing schedule by returned.

4 - Schedule Optimization Rules

Understand how optimization rules control the priorities used when generating assignments.

On-Call Optimizer uses a set of configurable optimization rules to determine the best possible assignment for a schedule. Each rule represents a specific scheduling objective, and the relative importance of each rule can be adjusted to match the needs of your team.

Overview

When generating an assignment, On-Call Optimizer evaluates every possible combination of member-to-shift assignments and selects the combination that best satisfies all active rules. Determining what best means for each schedule requires resolving the inherent tensions between rules — for example, achieving perfect balance might require ignoring a member’s availability preferences — On-Call Optimizer uses the relative importance (weight) of each rule as the key input to define how these tensions are resolved.

The available optimization rules are:

RulePurpose
Balance assignment loadDistribute shifts fairly across all members
Shift distributionControl how shifts are spaced or grouped for each member
Respect availability informationHonor member preferences and blocked periods
Target hours in windowLimit working hours within rolling time periods

Rules

Balance assignment load

The balance rule ensures that shifts are distributed fairly across all members of the schedule. It works by calculating a target value for each member which takes into account when they joined the schedule and any configured per-member shift allocation percentages.

The target for each member is tracked at both the shift type and overall levels, to prevent one member being assigned a disproportionate share of less desirable shifts while also keeping the overall share of shifts assigned in balance.

The balance rule penalizes assignments by summing, for each pair of members, the difference in how many shifts from their target each member is (e.g. two members who are both at their target will have a difference of zero, even when their targets differ). The higher the sum, the more imbalanced (distance from target) the members of the schedule are.

For more detail on how balance is calculated and displayed, see Schedule Balance.

Shift distribution

The shift distribution rule controls how each member’s shifts are spaced relative to one another within the schedule.

Distribution modes

Two distribution modes are available:

Spread — shifts are spaced as far apart as possible. This is the default mode and is ideal for teams where members benefit from recovery time between on-call shifts. When spread mode is active, On-Call Optimizer penalizes shifts that are closer together than the expected spacing for the schedule, with a higher penalty for truly consecutive shifts and a progressively lower penalty as the gap increases out to the expected spacing.

Consecutive — shifts are grouped together into blocks. This mode is useful for teams with short shifts (e.g. daily) to allow for assignment flexibility, but which still prefer to concentrate on-call duty into fewer, longer stretches rather than disconnected single days. When consecutive mode is active, On-Call Optimizer favors assigning adjacent shifts to the same member rather than spreading them across the team.

When the consecutive mode is active, a companion target hours rule is added to the schedule to provide an upper-bound on the length of consecutive assignments.

Per-member preferences

When enabled by the schedule administrator, individual members can override the schedule’s default distribution mode with their own preference. This allows a team to accommodate mixed preferences — for example, some members may prefer concentrated blocks of on-call duty while others prefer evenly spaced shifts.

Respect availability information

The availability rule ensures that On-Call Optimizer considers the availability information provided by each member when generating assignments.

Availability information is provided by members through their linked calendars and indicates periods where they are blocked (unavailable) or have a preference to be assigned.

Blocked periods

When a member marks a period as blocked, On-Call Optimizer applies a penalty to any assignment that would place them on-call during that time. The penalty for a block is large relative to the other rule penalties and bonuses to ensure blocked periods are respected as strongly as possible — a member will only be assigned to a blocked shift as a last resort when no other better assignment exists.

Preferred periods

When a member marks a period as preferred, On-Call Optimizer gives a small bonus to assignments that place that member on-call during the preferred time. Preferences are hints rather than requirements and the size of the bonus means they will be honored only when they don’t conflict with more important objectives like balance or blocked periods.

The strength of preference bonuses is also modulated by each member’s current assignments relative to their target. Members who are ahead of their target (assigned more shifts than expected) will have their preference bonuses reduced, while members behind their target will see them strengthened to prevent preferences from undermining balance over time.

Overlap weighting

The size of the penalty or bonus applied to the assignment for each piece of availability information that overlaps with a shift assigned to a member is weighted according to the proportion of the shift that is overlapped.

Target hours in window

The target hours in window rule limits the total on-call hours a member can be assigned within a rolling time period. In addition to providing an upper bound for the consecutive distribution mode, this rule can also be useful for enforcing workload policies, supporting legal requirements around maximum working hours, or managing cross-timezone schedules where different team members have different workload constraints.

The rule is configured with two parameters:

  • Target hours — the maximum number of hours on-call desired within each window (e.g. 40 hours).
  • Window size — the rolling time period over which hours are counted (e.g. 168 hours for a 7-day window).

When a potential assignment would cause a member to exceed the target hours within any rolling window, the optimizer applies a penalty proportional to the excess. This is a soft constraint — On-Call Optimizer will avoid exceeding the target but may do so if no better alternative exists.

Rule Weights

Each rule carries a weight that determines its relative importance during optimization in order to resolve the natural tension that arises between rules when evaluating each assignment — for example, perfectly balanced shifts might require ignoring a member’s availability preferences — the weighting of each rule allows each schedule administrator to independently configure how these tensions are resolved for that schedule, and therefore control which assignments On-Call Optimizer considers best.

Weights are relative, not absolute. What matters is the ratio between weights, not their individual values. Doubling one rule’s weight has the same effect as halving every other rule’s weight: it makes that rule comparatively more important.

Terminology

The implementation of each rule assigns a cost to each relevant situation it encounters when evaluating a potential assignment — for example, an imbalanced shift distribution, a closely-spaced pair of shifts, or a member assigned during a blocked period.

Costs typically reflect undesirable situations and are usally referred to as penalties. However in certain cases costs are implemented with negative values to represent bonuses to encourage the selection of assignments with desirable traits (e.g. a member assigned to a shift they preferred).

The overall penalty for an assignment is the sum of all individual costs, and On-Call Optimizer selects the assignment with the lowest total penalty.

Each type of cost has a base value that reflects its inherent severity. The base values establish a priority ordering between different costs within and across rules that applies even when all rule weights are equal. For example, assigning a member to a blocked period carries a much higher base cost than assigning them to a shift that is slightly closer together than ideal. This means that when all rule weights are equal On-Call Optimizer exhibits opinonated behavior of fairly distributing shifts, while strongly avoiding blocked periods and honouring preferences when possible.

Rule weights act as a multiplier on top of these base costs. Increasing a rule’s weight amplifies all of its costs proportionally, shifting On-Call Optimizer’s attention towards that rule’s objectives relative to others.

Priority presets

Priority presets provide pre-configured weightings that resolve the most common tensions between rules in ways that suit different scheduling philosophies. Presets can be selected from the assignment priority setting on each schedule and offer the recommended way to configure rule weights without needing to adjust individual values.

When a preset is selected, the weights for all rules are set to the values defined by the preset. The active preset is shown in the assignment priority selector and will display Custom if the current weights do not match any available preset.

The following presets are available:

Default — all rules are weighted equally. This provides an even weighting across balance, shift distribution and availability preferences, and is a good starting point for most schedules.

Balance focused — increases the weighting of the balance rule relative to other rules. This is suited to schedules where fair distribution of shifts is the primary concern, and On-Call Optimizer should prioritize minimizing the gap between members even when that means placing a member on-call during a less preferred time or with less ideal shift spacing.

Preference focused — increases the weighting of the availability preference rule relative to other rules. This is suited to schedules where respecting member availability is the primary concern, and On-Call Optimizer should prioritize honoring blocked periods and preferences even at the cost of some temporary imbalance between members.

Distribution focused — emphasizes meeting shift distribution preferences across time for each member. This is suited to schedules where spacing or grouping the shifts for a member based on the schedule and/or their personal preferences is the primary concern.

Custom weights

When the presets do not match your requirements, selecting the Custom option in the assignment priority settings reveals individual sliders for each rule, allowing you to set the relative weighting of each one directly.

Weights use a scale from 0 to 10:

  • 0 — the rule is ignored entirely. On-Call Optimizer will not consider this objective at all.
  • 1 — the default importance. The rule participates in optimization at its baseline level.
  • 2 to 10 — increasing importance. Higher values cause On-Call Optimizer to prioritize this rule more strongly relative to others.

Per-assignment customization

When creating a custom assignment, the priority weights can be adjusted for that specific assignment without changing the schedule’s default settings. This is useful for one-off situations, such as generating an assignment during a period with unusual availability constraints.

In all cases, On-Call Optimizer finds the assignment that achieves the best overall result across all active rules given their configured weights.

5 - Authentication and Authorization

Authentication and authorization with third-party integrations

On-Call Optimizer exclusively uses OAuth and OIDC for authorization and authentication, there is no support for accessing On-Call Optimizer via username/password.

On-Call Optimizer adheres to the principle of least privilege, requesting only the minimum OAuth permissions and scopes required to complete the action requested following the principle of incremental authorization. This allows users to mix and match between different providers without needing to grant an overly wide set of permissions to On-Call Optimizer.

Permissions requested at Login

On-Call Optimizer requests an OIDC login flow from the authentication provider requesting the OIDC standard email and profile grants. On-Call Optimizer stores the email and name returned in the provided ID token.

When logging in with a Google Workspace, or Microsoft organizational account, On-Call Optimizer will also retrieve and store the ID, name and primary domain of the workspace/organization of your account in order to create and associate your On-Call Optimizer account with a corresponding On-Call Optimizer Organization. For Microsoft accounts the User.Read permission is requested in order to retrieve this information as it is not included directly in the ID token.

All other information available to On-Call Optimizer during the login process is discarded. In particular, once the login process has completed, On-Call Optimizer does not retain or store the access or refresh tokens provided by the OIDC login flow.

Permissions requested when connecting a calendar

When connecting to a calendar provider, On-Call Optimizer uses a standard OAuth 2.0 authorization code flow to obtain a read-only access token, along with an offline access (refresh) token to allow continuing access to the users calendar.

Permissions requested when connecting an on-call product

On-Call Optimizer uses API tokens for access to any configured on-call product schedules. A read-only API token is supported when an on-call product is used a a source for On-Call Optimizer schedule configuration. A read-write API token is required when an on-call product is configured as a destination for a schedule.

Permissions requested when connecting to Slack

When the On-Call Optimizer Slack app is installed for a Slack Workspace, On-Call Optimizer receives an OAuth 2.0 access and refresh token which are used to access the Slack API. The following scopes are required for the On-Call Optimizer Slack app:

Permissions Summary

ActionScopes RequestedIncludes Offline AccessNote
Loginemail, profileYes [0]
LoginUser.ReadYes [0]Microsoft accounts only
Connect to Calendarread only [1]Yes
Connect to On-Call ProductAPI KeyYes
Slack App Installapp_mentions:read, channels:read, groups:read,im:read, chat:write, im:history, reactions:read, reactions:writeYes

[0]: The OIDC protocol includes the offline access scope by default, however On-Call Optimizer does not retain the provided refresh (or access) tokens, so no offline access is available to On-Call Optimizer, even though the permissions screen seen by the user indicates it may be.

[1]: Refer to the calendar provider for details on the specific scope name: Google, Outlook

6 - Integration Points

On-Call Optimizer provides numerous integration points to enable interoperation with other software.

Schedule Configuration

On-Call Optimizer supports import of the basic configuration of a schedule from supported on-call products.

Schedule Assignments

On-Call Optimizer supports export of the shift assignments for a schedule to supported on-call products.

Availabilty Information

Notification and Messaging

  • On-Call Optimizer supports email notifications for new assignments and new swap requests.
  • On-Call Optimizer has an integrated Slack App which in addition to providing notification and messaging functionality, also allows interaction with On-Call Optimizer schedules from within the Slack UI.

Additional Integrations

Additional integrations will be added as demand and development capability allow.

Please contact us, if you would like to request integration with a product not yet supported.

API and Event Notifications

On-Call Optimizer functionality can be made available via API or event (e.g. webhook) based methods upon request.

7 - Notifications

Discover available notifications and how to configure when and how On-Call Optimizer will notify you of relevant events.

Notification Philosophy

On-Call Optimizer aims to provide relevant and useful notification of key events and situations to all interested parties while minimizing unnecessary distraction and noise. To achieve this aim On-Call Optimizer provides a highly configurable notification framework which recognizes that what is relevant varies can vary significantly between individuals, teams and schedules!

This page describes the available notifications that On-Call Optimizer can generate, how they can be customized and how they are configured.

Notification Methods

To select your preferred notification method, use the selector on the profile page (also accessible by clicking the user icon in the top right corner of On-Call Optimizer and selecting My profile from the drop-down menu).

By default, all users will be notified via email, to the address associated with the account used to login.

Some users of On-Call Optimizer may also have the option to receive notifications via Slack. Slack notifications are available to members with an organization linked account where the organization in On-Call Optimizer has been linked to a Slack workspace. Details on whether these conditions are met can be found by clicking the Messaging item from the Integrations section of the menu sidebar.

Schedule Assignments

On-Call Optimizer supports export of the shift assignments for a schedule to supported on-call products.

Availabilty Information

Notification and Messaging

  • On-Call Optimizer supports email notifications for new assignments and new swap requests.
  • On-Call Optimizer has an integrated Slack App which in addition to providing notification and messaging functionality, also allows interaction with On-Call Optimizer schedules from within the Slack UI.

Additional Integrations

Additional integrations will be added as demand and development capability allow.

Please contact us, if you would like to request integration with a product not yet supported.

API and Event Notifications

On-Call Optimizer functionality can be made available via API or event (e.g. webhook) based methods upon request.

8 - Organization Support

Providing consistent visibility and management of schedules and users across your organization.

Organization support in On-Call Optimizer provides many benefits for larger teams including the ability for members to view schedules within the organization that they are not directly members of.

Organization Basics

An organization in On-Call Optimizer is inherited from the organizational information provided by the login identify provider. When the identity token resulting from a successful login provides organizational metadata your On-Call Optimizer account will be associated with the corresponding organization entity in On-Call Optimizer.

The supported organizational identity providers are:

  • Google Workspace
  • Microsoft Work accounts with an associated organization.

On-Call Optimizer’s organizational features cannot be used when authenticating from a consumer Gmail or Outlook personal account.

To check whether your On-Call Optimizer account is associated with an organization, click on the profile icon in the top right corner of the app. Organization accounts will show an organization icon and name between your name and email and the ‘My profile’ link. If you do not see this entry, your On-Call Optimizer account is not associated with an organization.

Organizational details can be viewed on the organization profile page which is accessible by clicking on the link in the user profile menu described in the previous paragraph.

Organization Resource Ownership

Most resources (including Schedules, On-Call Product and Messaging integrations) created by an On-Call Optimizer account belonging to an organization will be owned by the organization rather than the individual.

The only exception to this are Calendar integrations, which by their nature are always owned by the individual who created them.

Organization Best Practices

Multiple administrators

We recommend you configure two or more users as Organization Admins to ensure there are no single points of failure.

To change the roles for users in your organization:

  1. Select the organization entry in the profile menu in the top-right corner of the page.
  2. Find the appropriate member in the table under the ‘Members and Roles’ heading.
  3. Change the role of the member to ‘Admin’ using the select box on the corresponding line.

Organization Roles

Each member of an organization in On-Call Optimizer belongs to a role which grants permissions to perform certain actions. The available roles are:

Organization Admin

  • Can participate in the schedules they have been added to according to their assigned schedule role.
  • Can change the organization role of any member of the organization.
  • Are automatically granted all of the organizational permissions available to members described below.

The first user to login to On-Call Optimizer from an organization will be assigned the organization admin role, subsequent users will be assigned as organization members.

Organization Member

Organization members can participate in the schedules they have been added to according to their assigned schedule role.

The organization member role can also be granted any or all of the following permissions on the organization:

  • View all schedules - Defaults to true. Allows members of your organization to view schedules in the organization that they are not members of.
  • Manage schedules - Defaults to false. Allows members of your organization to create schedules, and delete schedules on which they hold the schedule admin role.
  • Manage Integration Connections - Defaults to false. Allows members of your organization to create, update and delete integration connections such as On-Call and Messaging products.