Skip to content

Planner

The Planner prepares capacity for recurring or known future demand. It learns how many application instances an application normally needs in each calendar window, presents the evidence as forecasts and suggestions, and turns operator-approved actions into temporary minimum instance counts.

The Planner is available only with the Predictive scaler:

Terminal window
PLT_SCALER_ALGORITHM_VERSION=v2

The Planner does not replace live scaling.

ComponentQuestionHorizonOutput
Predictive scalerHow many instances will be needed when another instance becomes ready?SecondsLive target replica count
PlannerHow many instances are normally needed in this calendar window?Days and weeksForecasts and suggested minimum instance counts
Custom scheduleWhat capacity does an operator already know will be needed?A known future eventOperator-defined minimum instance count

A scheduled value is a minimum, not a fixed replica count. V2 can always scale above it when live demand requires more capacity.

The Planner tab combines recent history, future forecasts, and active schedules in one calendar. Weeks run horizontally, time windows run vertically, and each cell contains the instance count for that window.

Planner calendar showing historical instance counts, forecasts, and scheduled capacity

Cell treatmentMeaning
SolidCapacity observed in a historical window
Translucent with a dashed borderForecast capacity
PurpleFloor created by an accepted suggestion or custom schedule
Diagonal splitPrevious forecast compared with the capacity later observed

The five color bands are calculated from the application’s own capacity distribution. The legend always shows the actual instance ranges, so a high-capacity window stands out whether an application normally runs 3 instances or 100.

Enable Show Previous Forecasted to compare historical forecasts with later observations. This makes repeated under- or over-prediction visible instead of replacing old forecasts with a newly calculated history.

TermMeaningDefault size or horizon
Time slotSmall interval in which ICC collects live instance targets5 minutes
Time windowPlanning unit built from several time slots60 minutes
PredictionForecast instance requirement for one future windowUp to 60 days
SuggestionRecurring rule proposed by the pattern predictorRequires operator acceptance
Custom scheduleOne-time or recurring rule created by an operatorOperator-defined
Scheduled slotConcrete occurrence produced from an active scheduleOne planning window
Minimum instance countTemporary minimum applied while a scheduled slot is activeClamped by hard limits

The end-to-end flow is:

StageInputResult
1. CollectV2’s raw required count and actual replicasTime-slot samples
2. AggregateTime-weighted slot percentilesHistorical planning windows
3. ModelWindows for the same local time across daysBaseline and recurring calendar patterns
4. ForecastBaseline plus matching patternsFuture instance predictions
5. ReviewRecurring patterns and their evidenceOperator suggestions
6. ScheduleAccepted suggestions and custom eventsConcrete scheduled slots
7. ApplyActive scheduled slot plus hard limitsTemporary minimum for V2

The Planner learns capacity rather than request count. The same request rate could represent cache hits, database work, or expensive server-side rendering; each has a different effect on a Node.js process.

For every live decision, V2 provides two values:

  • required instances (unclamped): the scaler’s raw target before hard limits, per-decision step limits, and cooldowns;
  • actual instances: replicas running at that moment.

The unclamped value preserves unmet demand. For example, if a hard maximum holds an application at 20 instances while the workload needs 27, the Planner records 27 as required and 20 as actual.

ICC first calculates time-weighted percentiles for required and actual instances in each time slot. Time weighting prevents a brief target from having the same influence as a value that lasted for most of the slot.

At the end of a time window, ICC selects the configured percentile from every included slot, averages those values, and stores one historical record. The default p50 reflects typical capacity; a higher percentile produces a more conservative plan.

3. Separate baseline from calendar patterns

Section titled “3. Separate baseline from calendar patterns”

Each time of day is modeled independently using up to one year of its history. The predictor establishes a robust rolling baseline, then looks for recurring deviations associated with calendar scopes, such as a particular weekday. It repeatedly separates baseline and pattern contributions so a Friday peak does not inflate the everyday baseline.

This produces two useful kinds of behavior:

Model resultMeaningExample
BaselineCapacity normally needed in this windowEvery day, 17:00–18:00: 13 instances
Scoped patternRecurring exception to the baselineEvery Friday, 17:00–18:00: 21 instances

The forecast for a future window combines its projected baseline with the patterns matching that date. Suggested instance counts are kept within the application’s configured hard range.

By default, the Planner writes predictions for the next 60 days. They are regenerated:

  • when the scaler leader starts;
  • after midnight in the configured cluster timezone;
  • after application scaling limits change;
  • when POST /applications/:applicationId/predictions requests an application refresh.

Forecasts remain informational. They do not change scaling until an operator accepts a suggestion or creates a custom schedule.

Open Suggestions & Scheduled Actions to review detected recurring demand. Each card describes the recurrence, proposed minimum instance count, applicable timezone, and confidence derived from its historical consistency.

Suggestions panel next to the Planner calendar

The complete floor is shown, not a delta that must be combined manually. If the everyday baseline is 13 instances and Friday needs 8 additional instances, the Friday suggestion says 21 instances.

Selecting a suggestion highlights its historical occurrences and affected future windows while dimming unrelated cells.

Calendar cells affected by one selected suggestion

The details view breaks past occurrences into the baseline, the selected pattern’s contribution, and contributions from other simultaneous patterns. This explains why some historical totals can exceed the floor proposed by the selected suggestion.

Historical evidence and contributions behind a recurring suggestion

Timezone handling is explicit: the recurrence remains anchored to the cluster calendar, while the UI also displays the equivalent time for the current operator.

StateEffect on scalingWhat happens on the next model update
SuggestedNoneCandidate may be replaced by new analysis
AcceptedCreates an active recurring scheduleAccepted value remains unchanged
CancelledSchedule becomes inactiveRecord remains as history; a current candidate may appear again
ExpiredNo longer activeOld record remains as history

Acceptance is intentionally a snapshot. Nightly forecasting may change the candidate, but it cannot silently change a production floor an operator already approved.

Use a custom schedule when upcoming demand is known but absent from history, such as a promotion, broadcast, migration, or planned batch job.

Form for a custom Friday promotion schedule

A custom schedule contains:

  • a name;
  • start time and duration;
  • IANA timezone;
  • minimum instance count;
  • an optional iCalendar RRULE recurrence.

Start time, duration, and schedule windows

Section titled “Start time, duration, and schedule windows”

Custom schedules use the window configured by PLT_SCALER_TIME_WINDOW_MINUTES (60 minutes by default):

  • startsAt must fall on a time-window boundary in timezone, with zero seconds and milliseconds.
  • durationMinutes must be at least one time window, a whole multiple of the time-window size, and no more than 1,440 minutes.
  • Each occurrence is expanded into one scheduled slot per covered time window.

With the default 60-minute window, a start at 17:00 and a duration of 240 minutes produce four scheduled windows: 17:00–18:00, 18:00–19:00, 19:00–20:00, and 20:00–21:00. A 17:30 start is invalid. If the window is configured to 30 minutes, 17:30 is valid and a 90-minute duration covers three windows.

The timezone’s UTC offsets must also be divisible by the configured time-window size. Recurring occurrences retain their local time across daylight-saving changes.

Omit rrule to create exactly one occurrence. This request keeps at least 35 instances running from 17:00 until 21:00 UTC on August 21, 2026:

Terminal window
curl -X POST "$ICC_URL/scaler/user-schedules" \
-H "authorization: Bearer $DEPLOY_TOKEN" \
-H "content-type: application/json" \
-d '{
"name": "Product launch",
"startsAt": "2026-08-21T17:00:00.000Z",
"durationMinutes": 240,
"timezone": "UTC",
"minPods": 35
}'

Setting "rrule": null has the same effect as omitting it.

Add rrule to repeat the event. startsAt supplies the recurrence’s earliest date and local start time; durationMinutes applies independently to every occurrence.

ScheduleRRULE
Every dayFREQ=DAILY
Every weekdayFREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
Every FridayFREQ=WEEKLY;BYDAY=FR
Every second FridayFREQ=WEEKLY;INTERVAL=2;BYDAY=FR
The 15th of every monthFREQ=MONTHLY;BYMONTHDAY=15
The last day of every monthFREQ=MONTHLY;BYMONTHDAY=-1
Every Friday, stopping after eight occurrencesFREQ=WEEKLY;BYDAY=FR;COUNT=8

For example, add this field to the previous request to repeat the four-hour floor every Friday:

"rrule": "FREQ=WEEKLY;BYDAY=FR"

Use startsAt, rather than BYHOUR, BYMINUTE, or BYSECOND, to set the occurrence time. RRULEs that override the time or produce intervals that do not align with the configured time-window size are rejected.

Cancel it without deleting its history:

Terminal window
curl -X DELETE "$ICC_URL/scaler/user-schedules/$SCHEDULE_ID" \
-H "authorization: Bearer $DEPLOY_TOKEN"

The application-specific Scaler API used by ICC also exposes Planner history, forecasts, suggestion details, acceptance, and cancellation under /scaler/applications/:applicationId/.

The Planner turns accepted suggestions and custom events into one schedule format. The scheduler expands every recurrence into concrete planning windows and chooses one floor for each window.

PrioritySchedule typeExample
1Custom scheduleOne-time promotion or operator-defined recurrence
2Scoped learned patternFriday 17:00–18:00
3Daily learned baselineEvery day 17:00–18:00

At the same priority, the more specific calendar rule wins. If specificity is equal, the higher minimum wins.

For example:

Matching schedulesWinning floor
Daily 13 + Friday 2121 on Friday; 13 on other days
Daily 13 + Friday 21 + promotion 3535 during the promotion
Promotion ends while Friday rule remainsFalls back to 21

The winning value is always clamped to the application’s hard scaling limits.

The scheduler maintains a concrete plan for the configured forecast horizon. On each scheduler tick, ICC:

  1. finds the scheduled slot active for the application;
  2. writes its minimum as a temporary soft limit in Valkey;
  3. combines the soft floor with the application’s hard range;
  4. asks the application controller to scale immediately when replicas are below the effective minimum.

The resulting behavior is:

Hard rangeScheduled floorLive V2 demandEffective target
3–40None88
3–4021821
3–40212525
3–25352025

When the window ends, the soft floor is removed and V2 can scale down according to live demand. Temporary limits expire automatically if scheduler updates stop, preventing a stale floor from remaining active indefinitely.

See Scaling Configuration for collection intervals, window size, percentile, prediction horizon, timezone, and scheduler settings.