FTW should retain the history needed for local energy management, charging, forecasts and support without storing every driver poll indefinitely. Live telemetry and safety must keep their current freshness and cadence.
Current code buffers every scalar emission in telemetry.Store and persists it through persistTelemetryTick. RecentRetention keeps those rows for 14 days; RolloffToParquet copies the same resolution to daily files. Dashboard JSON also keeps 30 days of hot snapshots. This amplifies live database growth, archive work and backup IO. See #1246, #1280 and #1259.
Proposed fixed defaults for scalar/chart history:
| Age |
Stored resolution |
Storage |
| First day |
10 seconds |
SQLite |
| 1–30 days |
1 minute |
Parquet |
| 30 days–2 years |
5 minutes |
Parquet |
| Longer |
Energy totals and selected events |
Existing ledger/event retention |
Do not reduce the control or driver polling rate. Aggregate before writing scalar/chart history. Keep energy accounting separate: meter deltas, power integration, import/export direction, gaps and resets must use the original measurements before compaction. Forecast training uses its existing quarter-hour observations. Preserve settings, stable identities, session goals, command outcomes and fault transitions.
Gauge buckets need count, sum, min/max, last value/time, interval width and coverage; gap intervals stay gaps. Never average a cumulative meter into energy or a status code into a new state. Merge summaries by counts/coverage, not by averaging averages. Only retain fields that have a concrete product consumer; raw export to a user-owned store stays optional and must not become a dependency of Core.
Implement in stages:
- Verify each consumer and define the aggregate/coverage contract, including counters and status signals.
- Write 10-second summaries at ingestion with bounded memory, shutdown flush, retry receipts and no duplicate contribution after an uncertain commit. Keep the live store and ledger path independent.
- Publish verified 1-minute and then 5-minute Parquet summaries with bounded maintenance. Readers must support old and new files and report the actual resolution.
- Convert old history outside the control path, restartably. Verify weighted totals, extrema, coverage and time bounds before pruning. Preserve the existing backup until restore has passed; do not run blocking VACUUM on a live box.
- Measure storage growth, archive load, backup size, durable-goal latency and live collection on Pi. A smaller file alone is not a passing control/IO test.
Acceptance tests: irregular polling, one-second power spike, sign changes, cumulative counter reset, outage/reconnect, late correction, duplicate retry, restart mid-bucket, partial archive failure, mixed old/new archive reads and backup/restore across the transition. Energy and EV delivered totals must match the original-measurement reference. Diagnostics must retain the spike and transitions while empty periods remain missing.
This issue records the owner's direction and a proposed retention policy. The new aggregation policy has not shipped. Existing storage reliability fixes remain necessary during the transition.
FTW should retain the history needed for local energy management, charging, forecasts and support without storing every driver poll indefinitely. Live telemetry and safety must keep their current freshness and cadence.
Current code buffers every scalar emission in
telemetry.Storeand persists it throughpersistTelemetryTick.RecentRetentionkeeps those rows for 14 days;RolloffToParquetcopies the same resolution to daily files. Dashboard JSON also keeps 30 days of hot snapshots. This amplifies live database growth, archive work and backup IO. See #1246, #1280 and #1259.Proposed fixed defaults for scalar/chart history:
Do not reduce the control or driver polling rate. Aggregate before writing scalar/chart history. Keep energy accounting separate: meter deltas, power integration, import/export direction, gaps and resets must use the original measurements before compaction. Forecast training uses its existing quarter-hour observations. Preserve settings, stable identities, session goals, command outcomes and fault transitions.
Gauge buckets need count, sum, min/max, last value/time, interval width and coverage; gap intervals stay gaps. Never average a cumulative meter into energy or a status code into a new state. Merge summaries by counts/coverage, not by averaging averages. Only retain fields that have a concrete product consumer; raw export to a user-owned store stays optional and must not become a dependency of Core.
Implement in stages:
Acceptance tests: irregular polling, one-second power spike, sign changes, cumulative counter reset, outage/reconnect, late correction, duplicate retry, restart mid-bucket, partial archive failure, mixed old/new archive reads and backup/restore across the transition. Energy and EV delivered totals must match the original-measurement reference. Diagnostics must retain the spike and transitions while empty periods remain missing.
This issue records the owner's direction and a proposed retention policy. The new aggregation policy has not shipped. Existing storage reliability fixes remain necessary during the transition.