Changelog — March 10, 2026
Critical watermark performance overhaul: pre-generated watermark derivatives eliminate on-the-fly processing, load shedding and concurrency controls prevent ECONNRESET cascades. Release v1.11.3.
✨ New Features
- Pre-generated Watermark Derivatives in Asset Pipeline — Watermarked thumbnail and preview WebP files are now generated during the BullMQ asset-processing job, reusing the already-downloaded temp file. Files are stored in R2 at
projects/{id}/watermarks/{assetId}/and their URLs are saved in the Asset metadata JSON. GraphQL resolvers now return the static R2 URL when available, completely eliminating on-the-fly watermark generation for newly processed assets. The/images/watermark/endpoint is kept as a fallback for legacy assets pending re-processing.#PR-284
🐛 Bug Fixes
-
Watermark Proxy ECONNRESET & Client Performance — Fixed socket exhaustion caused by unbounded concurrent R2 fetches: added a concurrency semaphore (max 8) and request deduplication on the API side. On the frontend,
rootMarginwas reduced (400 → 200 px) andstaleTimeincreased (5 → 30 s) to significantly reduce the volume of simultaneous watermark requests. This addresses the ECONNRESET / 502 / 503 cascade experienced by client viewers.#PR-283#PR-284 -
Route-level Load Shedding for Watermark Endpoint — When more than 10 watermark requests are processed concurrently, excess requests are immediately redirected to the non-watermarked derivative URL instead of queuing. This prevents the API server from being overwhelmed and stops the error cascade into downstream GraphQL endpoints.
#PR-284
📦 Dependencies & Infrastructure
-
Backfill Script for Watermark Derivatives — Added
scripts/backfill-watermarks.mjsto enqueue asset-processing jobs for existingPHOTOassets that do not yet have pre-generated watermark URLs. Supports--dry-runand--project <id>flags with cursor-based pagination (batch size 200).#PR-284 -
Generated Artifacts Updated — Prisma client and react-email build artifacts regenerated to reflect the latest schema changes.
#PR-283
By theodaguier