Skip to content

Trackers

Track numbers, text, durations, timestamps, and repeat counts alongside your moods and tasks.

A tracker history grid

Overview

A tracker is a named metric declared in configuration and logged with a -<name> argument. Tracker definitions specify whether a value is an integer, decimal float, duration, text string, or valueless marker.

Basics

Define a tracker

Add a [tracker.<name>] section to the file opened by im :config:

toml
[tracker.water]
kind = "float"
low = 0
high = 10
interval = { anchor = "2026-01-01T00:00:00Z", span = "1 day" }

The interval anchor includes an explicit time-zone offset. Bounds set the score range for color gradients in grids and today rows; enabling strict = true gates logged values within the configured range.

Choose a tracker kind

KindLog syntaxAccepted valueUse it for
integer-pushups 25Plain whole numberWhole-number counts and reps
float-rating 7.5Plain number (integer or decimal)Decimal measurements and scores
duration-mile 6m30sDuration string (e.g. 45s, 6m 30s, 1h)Timed activities and durations
text-win "fixed the flaky test"StringNotes and labels
null-sleepNone (valueless)Timestamp markers or slot counts

Value forms are checked per kind: integer requires whole numbers, float accepts decimal values, duration parses duration strings and stores total seconds, text stores strings verbatim, and null trackers accept no arguments.

Log a tracker

Log a tracker by itself:

sh
im -water 2.5
im -pushups 25
im -mile 6m30s
im -win "fixed the flaky test"
im -sleep

Combine trackers with a mood:

sh
im focused -water 2.5 -pushups 25

The today preview displays trackers attached to a mood under linked:. A numeric tracker can also be attached to an existing mood from the today view using ctrl-l.

Use intervals

An interval groups entries into calendar slots starting from its anchor timestamp:

toml
[tracker.pushups]
kind = "integer"
low = 0
high = 50
interval = { anchor = "2026-01-01T00:00:00Z", span = "1 day", cumulative = true }
  • Replace mode (cumulative = false, default): Each calendar slot keeps the latest entry. Logging again in the same slot replaces the previous entry.
  • Cumulative mode (cumulative = true): Every log in the slot is preserved. Grid dots show the sum of all values in the slot for numeric and duration kinds, count total entries for null, and list all entries for text.

Configure bounds and strict validation

low and high configure the range used for color binning and validation:

Kind / Modelow and high formatMeaning
integerWhole number (e.g. 0, 50)Value range for coloring and strict gate
floatNumber (e.g. 0.0, 10.0)Value range for coloring and strict gate
durationDuration string (e.g. "5m", "10m")Time range for coloring and strict gate
textWhole number (e.g. 1, 140)Character count limit for strict gate
null (replace)Duration offset (e.g. "22h", "6h")Slot time window for coloring and strict gate
null (cumulative)Whole number (e.g. 1, 5)Entry count threshold for coloring

Setting strict = true validates logs and updates:

  • Numeric and duration trackers require the logged value to fall within the inclusive span between low and high.
  • Text trackers require the character count to fall within the low and high limits.
  • Replace-mode null trackers require the entry time to fall within the circular time window between low and high (offsets relative to the slot start).
toml
[tracker.rating]
kind = "integer"
low = 1
high = 5
strict = true

[tracker.sleep]
kind = "null"
low = "22h"
high = "6h"
strict = true
interval = { anchor = "2026-01-01T00:00:00Z", span = "1 day" }

View tracker history

sh
im :
im :week rating
im :month rating pushups
im :year @stretch

A bare : shows the mood grid. Add tracker names to display their score dots. Prefix a recurring task name with @ to show its completion dots.

Grid ranges can be calendar-based or rolling; configure them in [grid]. See Configuration.

ProTip: Assign low, high, and custom colors to a tracker to make dot colors communicate progress at a glance.

FAQ

Why did Im reject my tracker value?

Tracker kinds validate input format and bounds:

  • integer requires whole numbers (e.g. 25).
  • float requires numbers (e.g. 7.5).
  • duration requires duration strings (e.g. 6m 30s).
  • text requires text.
  • null trackers take no argument and require an interval definition.
  • Trackers with strict = true require values within their configured low and high range.

Can I change a tracker definition later?

Yes. When updating a tracker's kind, older stored entries can be reviewed and aligned by running im :db doctor.

Why did my latest tracker value replace the previous one?

Interval trackers default to replace mode (cumulative = false), keeping the latest entry for each slot. Set cumulative = true on the interval to accumulate entries across the slot instead.