Skip to content

fix(telematics): retention pruner no longer scans the whole device_events table every run - #381

Merged
roncodes merged 1 commit into
refactor/identity-stub-from-fleetops-datafrom
fix/telematics-prune-scans
Oct 11, 2026
Merged

roncodes merged 1 commit into
refactor/identity-stub-from-fleetops-datafrom
fix/telematics-prune-scans

Conversation

@roncodes

Copy link
Copy Markdown
Member

What

fleetops:prune-telematics-data runs every 15 minutes. On a dev database with a 2.3M-row device_events table it held MySQL for minutes per batch (single statements running 300–500 s, database at 200–320 % CPU, API requests timing out) even though every telematics connection was inactive and there was nothing left to prune.

Polling itself was already correct: fleetops:sync-telematics only queues connections in active/connected states, so inactive connections generate no device-event traffic. The load was the retention sweep.

Why it scanned everything

  • Batches were ordered by id while the scope ranged over created_at, so MySQL walked the primary key instead of the (company_uuid, created_at) retention index. Batches now order by the ranged column.
  • The orphan scope was company_uuid IS NULL OR company_uuid NOT IN (select uuid from companies), which cannot use an index. The gone company uuids are now resolved once per table from a grouped index scan, and the scope becomes IS NULL / IN (...).
  • The compaction sweep re-read every already-compacted row on every run. A per-scope watermark (cache, best effort) now limits it to rows that aged into the window since the last complete sweep; a capped or dry run never advances it.
  • The soft-deleted purge had no index on deleted_at, so it walked the table even when nothing was trashed. Two migrations add (company_uuid, deleted_at) on device_events and positions, guarded like the existing retention index migrations.

Validation

Validation is deferred to CI and the maintainer's run (per the agreed workflow): php -l passes on the three files; behaviour of the existing PruneTelematicsDataCommandTest is unchanged (same rows deleted/compacted, only ordering and scope shape differ). The watermark uses the Cache facade in try/catch so test bootstraps without a cache store are unaffected.

Operator notes

  • Run php artisan migrate to add the two indexes (an online index build on a large table takes a while).
  • Prune runs already in flight keep their current statements until they finish; the next scheduled tick uses the new queries.

Docs / API

No user-facing or API change; no docs or postman updates needed.

Stacked on refactor/identity-stub-from-fleetops-data (#380) because that is the checked-out dev branch; rebase onto the release branch if preferred.

…e_events table every run

fleetops:prune-telematics-data ran every 15 minutes and, on a 2.3M-row device_events table, held the database for minutes per batch even though every telematics connection was inactive and nothing was left to prune:

- batches were ordered by id while the scope ranged over created_at, so MySQL walked the primary key instead of the (company_uuid, created_at) retention index; batches now order by the ranged column
- the orphan scope was 'company_uuid IS NULL OR NOT IN (select uuid from companies)', which cannot use an index; the gone company uuids are now resolved once per table from a grouped index scan and the scope becomes IS NULL / IN (...)
- the compaction sweep re-read every already-compacted row on every run; a per-scope watermark (cache) now limits it to rows that aged into the window since the last complete sweep
- the soft-deleted purge had no index on deleted_at; two migrations add (company_uuid, deleted_at) on device_events and positions

Polling itself was already correct: fleetops:sync-telematics only queues connections in active/connected states.
@roncodes
roncodes merged commit feaea0e into refactor/identity-stub-from-fleetops-data Oct 11, 2026
@roncodes
roncodes deleted the fix/telematics-prune-scans branch October 11, 2026 03:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant