Presence is upserted unconditionally, with no state comparison. Writes come from two paths, not just heartbeat ticks:
| Trigger |
Writes |
| Any admin or front-end render |
1 (admin/online, includes/heartbeat.php:103) |
| Post-edit screen render |
2 (+ editor-{id}, :108) |
| Heartbeat tick |
1 (admin/online) |
| Heartbeat tick, post-edit screen |
3 (+ editor-{id} + lock-{id}) |
Most of these change only date_gmt. The three-write case is the duplicate entry in #134; resolving that removes one write per tick before anything here is evaluated.
Options
- Client-side: hash current state, send only on change or near TTL expiry.
- Server-side: skip the write if incoming state matches stored state and
date_gmt is not near cutoff.
- Accept the volume and document the rationale.
Constraints
The ping is also the keepalive. Any solution gating writes on state change must still write before TTL expiry, or active users appear offline.
A client-side diff cannot cover render-time writes, which happen server-side during the page request. Only a server-side diff covers both paths.
The render-time write is deliberate. It closes the gap between the previous page's pagehide DELETE and the next tick (includes/heartbeat.php:88-90). Removing it makes presence stale during in-admin navigation.
#132 should measure both paths separately: renders scale with navigation, ticks with concurrent sessions.
Presence is upserted unconditionally, with no state comparison. Writes come from two paths, not just heartbeat ticks:
admin/online,includes/heartbeat.php:103)editor-{id},:108)admin/online)editor-{id}+lock-{id})Most of these change only
date_gmt. The three-write case is the duplicate entry in #134; resolving that removes one write per tick before anything here is evaluated.Options
date_gmtis not near cutoff.Constraints
The ping is also the keepalive. Any solution gating writes on state change must still write before TTL expiry, or active users appear offline.
A client-side diff cannot cover render-time writes, which happen server-side during the page request. Only a server-side diff covers both paths.
The render-time write is deliberate. It closes the gap between the previous page's
pagehideDELETE and the next tick (includes/heartbeat.php:88-90). Removing it makes presence stale during in-admin navigation.#132 should measure both paths separately: renders scale with navigation, ticks with concurrent sessions.