Periods & targets
How Pulsaria derives the start and end of a KPI period, what happens at rollover, and how the target is read for cumulative and recurring KPIs.
Every KPI carries a target and a period. Together they produce the ideal line, the traffic-light status and the gap badge you see on the dashboard. This page covers exactly how the two period boundaries are derived, what happens when a month or quarter ends, and how the same target number means two different things depending on the KPI type.
The four period types
You pick the period in the KPI dialog, in the Goal section, from the Period dropdown. There are four options and no others.
| Option | Start | End | Length |
|---|---|---|---|
| Year | 1 January of the current year | 31 December of the current year | 365 or 366 days |
| Month | The 1st of the current calendar month | The last day of that month | 28–31 days |
| Quarter | The 1st day of the current calendar quarter | The last day of that quarter | 90–92 days |
| Custom range | The Start date you enter | The End date you enter | Whatever you set |
The quarter is derived from the current month number: months 1–3 give 1 January – 31 March, months 4–6 give 1 April – 30 June, and so on. Calendar quarters only.
Year, Month and Quarter always resolve against today’s date on your Mac. There is no way to point one of them at last month, at the previous year, or at a fiscal year that does not start on 1 January. Custom range is the only way out.
Custom range
Choosing Custom range reveals two extra fields, Start date and End date. Both are date pickers and both are required. The start field’s maximum is bound to the end date and the end field’s minimum to the start date, so the pickers cannot cross.
Two error messages can block the save:
- Pick both a start and an end date — one of the two fields is still empty.
- End date must be on or after the start date — the range runs backwards. A one-day range (same date in both fields) is allowed.
If you later switch the KPI back to Year, Month or Quarter, the two stored dates are cleared on save. Switching back to Custom range means entering them again.
An incomplete custom range
The form will not let you save a custom range with only one date filled in. A definition that still ends up in that state — from an import, or from editing kpi-definitions.json by hand — falls back to the current calendar year without any warning: 1 January to 31 December, and the period suffix on the card prints /yr rather than a date range. If a KPI shows /yr where you expected a range, that is what happened.
An end date that precedes its start date (same route: import or hand-edited file, never the form) collapses the period to a single day.
The first-KPI form in the welcome wizard offers only Year, Quarter and Month. To use a custom range, create the KPI there and edit it afterwards, or create it from the dashboard.
How the length of a period is counted
The period length — totalDays — is the number of whole calendar days from the start date to the end date, counting both ends. A period is never shorter than one day.
- 2026 is not a leap year, so Year is 365 days: 1 January to 31 December.
- Month in July is 31 days; in February 2026 it is 28.
- Quarter Q1 2026 is 90 days (1 January – 31 March), Q3 is 92 days (1 July – 30 September).
- A Custom range from 1 March to 30 June is 122 days. From 1 March to 1 March it is 1 day, not 0.
The count is taken from the local year/month/day of each date, not from elapsed milliseconds. That is deliberate: a period spanning a daylight-saving change contains one 23-hour and one 25-hour day, and a millisecond-based count would be off by one at the boundary. In Pulsaria, the clock changes in March and October neither add nor drop a day.
Dates are local throughout. A bare YYYY-MM-DD is read as local midnight, so a period never shifts by a day depending on your timezone.
What happens when a period rolls over
Period boundaries are not stored. They are recomputed from today’s date every time a screen renders. Nothing is scheduled, nothing is migrated, and there is no rollover job that could fail.
At your local midnight on the 1st, a Month KPI’s window becomes the new month. Concretely:
- Start, end and
totalDaysare the new month’s. - For a Cumulative goal, the ideal drops back to
0for the first day and starts climbing again. - The small chart on the dashboard card spans the whole period, start to end — so last month’s points are no longer drawn on it.
- The large chart on the KPI detail page never reaches back past the period start, whichever of 7D / 30D / 90D you select.
What does not happen at rollover:
- Your recorded values are not reset, archived or filtered per period. The history behind a KPI is one continuous series.
- The current value is the newest recorded value, full stop. If your last entry is from 28 July and you open the card on 3 August, that July number is still shown as the current value — and it is graded against August’s ideal.
- The target is not carried over, doubled or reset. A KPI has exactly one target, and it applies to whichever period is current.
On the first day of a period a cumulative KPI’s ideal is exactly
0. For a “Higher is better” KPI that makes any non-negative value On track for that one day. The gap badge on the dashboard card is hidden while the ideal is 0; the pill on the KPI detail page is not, and shows+0% vs ideal.
How the target is read: cumulative vs. recurring
Directly below the period sits KPI type, with two cards. The choice does not change the target number — it changes what that number is compared against on any given day.
Cumulative goal
Value accumulates toward target (e.g. revenue). The target is the endpoint you want to reach by the end of the period. The ideal line rises linearly from 0 to the target:
ideal(date) = target ÷ totalDays × days elapsed since period start
Day one counts as zero elapsed days, so the ideal starts at 0. On the last day of the period the ideal is target × (totalDays − 1) ÷ totalDays — 96.77 % of the target in a 31-day month. The full target is only reached on the day after the period ends. A KPI that hits its target exactly on the last day therefore reads slightly ahead of ideal, not level with it.
Wording that follows this choice: the card footer says ideal: …, the gap badge says vs ideal, and the chart legend reads Ideal Trend.
Recurring value
Fresh reading each period against a benchmark (e.g. MAU). The target is a flat benchmark. The ideal is the target on every day of the period — no ramp, no accumulation.
The period still matters for a recurring KPI: it defines the window the charts draw and the label printed next to the target. It just no longer scales the ideal.
Wording here: the card footer says target: …, the gap badge says vs target, and the chart legend and tooltip read Target.
Cumulative goal is the default. Connector-backed KPIs get the type pre-filled from the metric you pick in the Connector Library, along with unit, direction, period and schedule. The welcome wizard’s first-KPI form has no KPI-type field at all, so a KPI created there is always cumulative — the starter packs offered on the same step do set the type per KPI.
Switching an existing KPI between the two types re-grades its whole history against the new ideal line. Changing the target does the same: there is no target history, so every past day is recalculated as if the new number had always applied.
A worked example
A KPI named Revenue, unit EUR, target 12000, direction Higher is better, period Month, type Cumulative goal. Today is 25 July 2026.
The period is 1 July – 31 July 2026, so totalDays is 31 and one day’s share of the target is 12000 ÷ 31 = 387.10 EUR.
| Date | Days elapsed | Ideal |
|---|---|---|
| 1 Jul | 0 | 0.00 EUR |
| 10 Jul | 9 | 3,483.87 EUR |
| 25 Jul | 24 | 9,290.32 EUR |
| 31 Jul | 30 | 11,612.90 EUR |
| 1 Aug | — | 0.00 EUR (new period) |
Say your latest entry is 9000. On 25 July the card then shows:
- Footer, left:
12,000 EUR/mo. Footer, right:ideal: 9,290 EUR— aEURunit is printed without decimals from 1,000 upwards. - Gap badge: the difference is
9000 − 9290.32 = −290.32, which is 3.1 % of the ideal, so the badge reads-3% vs idealin amber (behind, but by less than 10 %). - Status:
9000is above 90 % of the ideal (8,361.29) but below the ideal itself, so the dot is amber and the badge reads At risk.
The same KPI as a Recurring value answers a different question. The ideal is 12,000 EUR on every day of July, so 9000 is 25 % below it: the badge reads -25% vs target in red and the status is Off track, because the value is under 90 % of the benchmark. Cumulative asks have I earned 12,000 so far this month?; recurring asks am I at 12,000 right now?
Where the period shows up in the UI
The period suffix is printed straight after the unit, with no space, on the KPI card footer and in the target pill on the KPI detail page:
| Period | Suffix | Example |
|---|---|---|
| Year | /yr | 50,000 EUR/yr |
| Month | /mo | 12,000 EUR/mo |
| Quarter | /qtr | 15,000 EUR/qtr |
| Custom range | the two dates | Mar 1 – Jun 30 |
A custom range prints its start and end date in place of a suffix, formatted in the app language: Mar 1 – Jun 30 in English, 1. Mär – 30. Jun in German. An incomplete custom range prints /yr, matching the year it silently fell back to.
What periods do not do
None of this exists, so you do not go looking for it:
- There is no week, day or rolling-N-days period. The four above are all of them.
- There is no fiscal-year setting and no way to view a past month, quarter or year. Only a custom range can point at a closed period.
- Pacing is linear only. No seasonality, no weekday weighting, no ramp-up curve, no milestones.
- There is no forecast. Nothing extrapolates your current run rate to the period end.
- The status thresholds (90 % / 110 % of the ideal) are fixed and cannot be set per KPI.
- Charts, the status timeline and the history table read from the last 90 dates that carry an entry for any KPI. On a Year KPI with daily logging, the earliest months drop out of those views — the entry files stay on disk untouched.
Where to go next
- Ideal line & status — how the ideal turns into On track, At risk and Off track
- Anatomy of a KPI — the other fields on the same dialog
- Entering values — how values land on a date
- KPI detail — where the ideal, the gap and the history table live