Keep device runtime state out of PostgreSQL - #7
Conversation
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_24d7273f-5853-4bf0-8c22-a8d7527088c3) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_ca4a0a37-d2a8-4bfa-b53b-7013f32c691e) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_59aff440-7150-4df1-b04f-dd1c4f745928) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_dd399add-753b-4674-99fb-e112cbfd386a) |
Makes the devices table inventory/configuration-only and keeps poll-derived runtime state in memory.
Runtime state
Last available
STA write amplification
Other write reduction
Legacy status/status_reason columns remain for schema compatibility but are documented as unused by the poller/API. Job, alert, audit, and mismatch records remain durable by design.
Note
Overview
Treats
devicesas durable inventory only and stops using PostgreSQL for poll-derived runtime state (online/offline, reasons, upgrading). After a restart, APIs and bulk ops report unknown until the in-memory stats store is populated—no fallback to staledevices.status.Poller and children: Removes per-poll (and per-transition)
UPDATE devicesfor status/reason across Wave, AirMAX/LTU, MAC mismatch, parent/child propagation, and missing STA association. Child updates SELECT identity from DB and push state via the stats store + WebSocket only.markMissingSTAsOfflineusesSetStatusByMACChangedso WebSocket fires only when status/reason actually change.last_seen: Replaces ~10-minute batch status/last_seensync with an hourlysyncLastSeenToDBthat batch-updates each MAC’s in-memory timestamp (with skip logic for recent DB writes). Add/upsert paths no longer setstatuson insert/update; STA hot paths addIS DISTINCT FROMguards to avoid write amplification.API/reports/firmware: List/get devices overlay status, reason, and fresher
last_seenfrom live stats; reports usereportLiveStatus. Firmware jobs no longer setdevices.status = 'upgrading'. Learn MAC keys offdevice_identity_mismatchesinstead ofstatus_reason. AirMAX GPS is fill-once inventory (COALESCE); SPEC documents the pattern.Reviewed by Cursor Bugbot for commit f2b5383. Bugbot is set up for automated code reviews on this repo. Configure here.
Follow-up review fixes
devices.status; a device with no live stats is ineligible until freshly polled.last_seenpersistence is chunked at 2,000 rows (4,000 bind parameters) per statement and binds Go timestamps astimestamptz.OnlineStatusBatchhelper.Validation
CI run 35412981298 is green on head
f2b5383d43dea1faa0446cb2b089065b2c6deb0e: