Seconds_Behind_Master reports how far behind the SQL thread is on the events it has received, which is not the same as how stale the data is.
-- on the primary, every second
REPLACE INTO heartbeat (id, ts) VALUES (1, NOW(6));
-- on the replica
SELECT TIMESTAMPDIFF(MICROSECOND, ts, NOW(6)) / 1000 AS lag_ms
FROM heartbeat WHERE id = 1;
-- and the case that exposes the difference:
-- during a long ALTER, Seconds_Behind_Master reports 0
The long-ALTER case is the one that produces an incident: the replica is applying one statement, has received nothing newer, and honestly reports zero — while being an hour behind in every sense that matters. A heartbeat row measures wall-clock staleness end to end and cannot be fooled by any of it. It costs one write per second and is the only number worth alerting on.