Files
bsky-social-app/bskyogcard/package.json
T
Austin McKinley fc750703ac bskyogcard: downscale avatars before rendering
The card routes fetch each avatar from cdn.bsky.app/img/avatar/,
which serves up to 1000x1000. Cards never display avatars above
~210px, but satori parses and resvg rasterizes images at intrinsic
size: ~4MB of decoded native RGBA per avatar per render, up to 7
avatars per starter-pack card, and satori's 500-entry image LRU
retains the oversized data URIs. Under sustained traffic the native
churn and allocator fragmentation grow RSS unbounded and the service
OOMs against its 2Gi limit roughly hourly (observed in prod: ~20
OOMKills/day/pod for weeks).

Resize fetched avatars to 256px max with sharp before handing them
to the render pipeline. Decoded pixel volume drops ~15x; rendered
output is visually identical since display sizes never exceed the
resize cap. libvips' operation cache is disabled since unique-image
traffic never hits it.

Load-tested with 74 real starter packs (6 rounds, concurrency 8):
peak RSS 1441Mi -> ~1000Mi, JS heap 130-160Mi -> 45-70Mi, and
late-round RSS flattens instead of compounding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 23:07:28 -07:00

42 lines
1.0 KiB
JSON

{
"name": "bskyogcard",
"version": "0.0.0",
"type": "module",
"main": "src/index.ts",
"devEngines": {
"packageManager": {
"name": "pnpm",
"version": "11.10.0",
"onFail": "warn"
}
},
"scripts": {
"start": "tsx ./src/bin.ts",
"dev": "LOG_ENABLED=true LOG_LEVEL=debug node --watch-path ./src --import tsx ./src/bin.ts",
"build": "tsc && cp -r src/assets dist/",
"install-fonts": "tsx scripts/install-fonts.ts",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@atproto/api": "0.20.13",
"@atproto/common": "^0.6.1",
"@resvg/resvg-js": "^2.6.2",
"express": "^4.19.2",
"express-prom-bundle": "^7.0.0",
"http-terminator": "^3.2.0",
"pino": "^9.2.0",
"prom-client": "^15.1.3",
"react": "^19.2.6",
"satori": "^0.26.0",
"sharp": "^0.35.3",
"twemoji": "^14.0.2"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^24.12.2",
"@types/react": "^19.2.15",
"tsx": "^4.21.0",
"typescript": "^6.0.3"
}
}