Prune persistentIds older than 24h so config.json stops growing - #9
Merged
Merged
Conversation
cassiostp
force-pushed
the
cs/bounded-persistent-ids
branch
2 times, most recently
from
August 17, 2026 18:28
e3dbea4 to
3c1ccfe
Compare
cassiostp
force-pushed
the
cs/bounded-persistent-ids
branch
from
September 15, 2026 20:29
3c1ccfe to
151af30
Compare
cassiostp
force-pushed
the
cs/bounded-persistent-ids
branch
2 times, most recently
from
September 16, 2026 03:42
4cf7fbe to
2ce3473
Compare
cassiostp
marked this pull request as ready for review
September 16, 2026 03:48
cassiostp
requested review from
patrickdbakke,
victoroliveira-superhuman and
zindlerb
September 16, 2026 03:48
zindlerb
approved these changes
Sep 16, 2026
| const savedApiKey = config.get('fcmApiKey'); | ||
| if (started) { | ||
| webContents.send(NOTIFICATION_SERVICE_STARTED, (credentials.fcm || {}).token); | ||
| send(NOTIFICATION_SERVICE_STARTED, ((credentials || {}).fcm || {}).token); |
There was a problem hiding this comment.
I would keep existing behaviour here where if we don't pass in credential we raise an error.
Every received push appends one id to config.json and the list is never trimmed, so the file grows without bound - fleet median 54k ids / 2.2 MB, p99 1M ids / 40 MB - and each push rewrites the whole file synchronously on the main process. Each id embeds a microsecond timestamp, so age is the natural bound: ids older than 24 hours are pruned on start and on every write. The list exists only to stop the server redelivering pushes on the next login, and desktop pushes carry a 5-minute (or 0) TTL, so anything older can never be replayed - no count cap or acked-ids signal is needed. Unparsable ids are dropped deliberately: keeping them would be the only path back to unbounded growth if the id format ever changes, while dropping one costs at most a single redelivery. CLI-2311
cassiostp
force-pushed
the
cs/bounded-persistent-ids
branch
from
September 16, 2026 14:25
2ce3473 to
01bcd69
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every delivered push appends a
persistentIdtoconfig.jsonand the list is never trimmed, so the file grows without bound andelectron-configrewrites all of it synchronously on the main process for each push. Across 46.6k native devices (log.push_receiver_config_stats, Sep 8–15) the darwin p50 is 53.7k ids / 2.2 MB and the p99 is 981k ids / 40 MB. At the median ~360 pushes per active day, a median device serialises ~0.8 GB/day of JSON on the UI thread.Fix
Each id is
0:{microsecondTimestamp}%{hash}, so its age is known.pruneStaledrops ids older than 24 h from the list seeded intolisten()at start and from every append.24 h is safe because the list only prevents the server from redelivering pushes on the next login, and the backend sends desktop pushes with
TTL: 5 minutes(new-email,calendar-event) orTTL: 0(history,userdata-history) (mail-backend/lib/notifications/notify.go). Nothing older can be replayed; the margin covers clock skew. Ids that do not parse are dropped so a format change cannot reintroduce unbounded growth.webContents.sendcalls are guarded withisDestroyed().Rollout
Publish as 2.1.10 and bump
native/package.jsonin desktop. The first login after upgrade sends the pruned list. Rollback is a version revert; the old code reads the same array. Expected signal inlog.push_receiver_config_stats:persistent_ids_countp50 from ~50k to a few hundred,config_bytesp50 from 2.2 MB to under 50 KB.CLI-2311