Relationships
#2999 s3-datastore: pull never removes files deleted on the remote, so a peer's next push re-uploads them and undoes `swamp data gc`
Opened by sntxrr · 10/3/2026· Shipped 10/6/2026
Summary
When one peer runs swamp data gc against a shared @swamp/s3-datastore, the GC removes the files from S3 (delete markers) and from that peer's index shards. A second peer (here swamp serve) pulls afterwards, but its pull does not delete the GC'd files from its own local cache. The second peer's next push then uploads those files again and merges their index entries back into the shards, restoring the pre-GC state.
Measured (two peers on one namespace: a CLI host and a swamp serve container)
- GC on the CLI host: 120,250 excess versions reclaimed. The home-ip model's index shard went 14.2 MB → 28 KB (38,252 → 80 entries).
- 8–12 min later, a scheduled workflow run on serve pushed. The same shard went 28 KB → 14.18 MB in a single write, restoring 38,172 entries.
- Sampled restored files: each has the GC's delete markers (23:04–23:09Z) followed by a new current version (23:16–23:17Z). They were all present in serve's local cache and absent from the CLI host's.
- Cache drift at that point: CLI host 89,436 files / 627 MB; serve 297,986 files / 2.5 GB. serve's sync-state showed
localDirty: false, 0 dirty paths. - The same files show many earlier bursts of identical re-uploads (on 2026-10-02 at 17:58Z, 10:17Z and 01:02Z, on 2026-10-01 at 21:57Z and 04:00Z, four times on 09-30, and earlier). Each burst stores another full copy under bucket versioning. That roughly matches the bucket's ~50 GB/day storage growth and ~2M PUT/day.
- Running the same
swamp data gc --yeson serve itself (dry run: 118,031 excess versions) removed the stale copies: serve's cache dropped to 70,486 files / 872 MB and the index stayed down across the next scheduled runs.- With
SWAMP_DATASTORE_SYNC_TIMEOUT_MS=1800000. On the CLI host, the GC's push had timed out at the 300 s default.
- With
Expected
- A pull removes from the local cache any file whose index entry no longer exists remotely, or that has a remote delete marker. A file deleted by a peer should not reappear on the next push.
- Alternatively, push should not upload files that were never dirty locally.
Also observed
Retention differs by peer: after GC, serve kept 10,096 home-ip files, while the CLI host kept about 139. serve's next push merged its set into the shard (28 KB → 3.4 MB). If both ran the same GC config, I'd expect the same retained set.
Related
- #2683:
pullChangedoverwrites dirty, unpushed cache files. Same area, opposite direction. - #2888: keep a failed push's changes dirty through a pull (shipped in 2026.10.01.1). This would have protected the timed-out GC push, but not this case.
- Filed alongside: every fast-path miss downloads every
_indexshard. The two compound: re-bloated shards make every pull more expensive.
Environment
@swamp/s3-datastore2026.09.24.1 at the time of the re-upload, now 2026.10.01.1 on both peers- swamp
20261002.202148.0-sha.0fc928c8(serve, linux container); CLI on darwin aarch64 - AWS S3, versioning enabled
Upstream repository: https://github.com/systeminit/swamp-extensions
Environment
- Extension:
@swamp/s3-datastore@2026.10.01.1 - swamp:
20261002.194016.0-sha.c0c751a1 - OS:
darwin(aarch64) - Deno:
2.9.7 - Shell:
/bin/zsh
Shipped
Click a lifecycle step above to view its details.
system commented 10/3/2026, 12:36:03 AM
Classified automatically when this issue was filed.
- Source: Extensions
If you feel this classification is incorrect, add a ripple to tell us so.
stack72 commented 10/6/2026, 7:34:59 PM
Thanks @sntxrr for reporting this! We shipped: Pull and push in both @swamp/s3-datastore and @swamp/gcs-datastore reconcile peer deletions: a local file whose index entry existed at the last sync, is gone from an authoritatively read remote index, and is unchanged locally (size plus mtime or sha256) is removed from the cache with its now-empty parent dirs, so a later push walk no longer re-uploads it and undoes swamp data gc. Locally modified copies are kept; nothing is removed when the remote index is cached, missing, synthetic, or empty.. The fix has been merged and a release is on its way. We appreciate your contribution to swamp.
Sign in to post a ripple.