Period comparison
Value and Progress metrics can compute period-over-period change. withChangeAgainstPreviousPeriod() compares against the immediately-preceding window:
use App\Models\User;
use RoundlyConsulting\Metrics\Enums\Period;
use RoundlyConsulting\Metrics\Facades\Metrics;
Metrics::value()
->count(User::query())
->range(Period::Today)
->withChangeAgainstPreviousPeriod() // vs. yesterday
->toArray();
// result => ['value' => 42.0, 'previous' => 30.0, 'change' => ['percentage' => 40.0, 'is_increase' => true]]The previous window
| Range | Compared against |
|---|---|
7 … 365 | The N days before the current window |
TODAY, YESTERDAY | The day before |
WTD, MTD, QTD, YTD | The same elapsed span of the previous week, month, quarter or year |
THIS_WEEK … THIS_YEAR | The whole previous week, month, quarter or year |
LAST_WEEK … LAST_YEAR | The period before that |
CUSTOM | A window of exactly the same length that ends one second before it starts |
ALL | No comparison |
The ALL range has no bounded window, so only the value is returned.
Compare against any range
compareTo() compares against any period instead — and implies withChangeAgainstPreviousPeriod(). The comparison period resolves as-is, in the metric’s timezone:
use RoundlyConsulting\Metrics\Enums\Period;
Metrics::value()
->count(Order::query())
->range(Period::ThisMonth)
->compareTo(Period::LastYear) // vs. the whole previous calendar year
->toArray();
// The same month a year ago — an explicit custom window
Metrics::value()
->count(Order::query())
->range(Period::ThisMonth)
->compareTo(Period::Custom, '2025-09-01 00:00:00', '2025-09-30 23:59:59')
->toArray();Progress change
Progress metrics add the previous value’s progress and a change block with the percentage change and the deltas in value and in progress points — a ProgressResult is also a ValueResult, so change() returns the percentage:
Metrics::progress()
->sum(Order::query(), 'total')
->target(10000)
->range(Period::MonthToDate)
->withChangeAgainstPreviousPeriod()
->toArray();
// result => [
// 'value' => 8200.0, 'progress' => 82.0,
// 'previous' => 6500.0, 'previous_progress' => 65.0,
// 'target' => 10000.0, 'avoid' => false,
// 'change' => ['percentage' => 26.0, 'is_increase' => true, 'progress' => 17.0, 'value' => 1700.0],
// ]The change percentage handles a zero previous value gracefully: it returns 100 when the current value is positive and 0 otherwise. change.is_increase is true when the current value exceeds the previous one.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.