Skip to content

Add librsvg to runtime for fast SVG rasterization#21

Merged
fleveque merged 1 commit into
mainfrom
fix/svg-rsvg-runtime
May 16, 2026
Merged

Add librsvg to runtime for fast SVG rasterization#21
fleveque merged 1 commit into
mainfrom
fix/svg-rsvg-runtime

Conversation

@fleveque

Copy link
Copy Markdown
Owner

Root cause of the 504

After #20 deployed, the next REP.MC request actually got past Wikidata cleanly:

```
22:30:42 cache miss for REP.MC
22:30:43 found logo via Wikidata, source=wikidata:Q174747
[504 to browser]
```

…but then went silent. No "processed" log line, no error. The hang is in `ProcessAll` — Wikimedia returned an SVG (Repsol's official logo), and the Alpine `vips` package doesn't pull `librsvg` in by default. When libvips' SVG path can't find librsvg, it falls back to a much slower code path:

resize one logo to 5 sizes
with librsvg ~100ms
without librsvg ~30s

The 30s case was tripping kamal-proxy's request timeout.

Fix

Add `librsvg` to the runtime `apk add` line. ~3MB of additional image size.

Test plan

  • After deploy, hit REP.MC again. Logs should show `processed` shortly after `found logo via Wikidata` (sub-second). Browser gets a real Repsol logo.
  • Same for DGE.L.

🤖 Generated with Claude Code

Wikimedia logos come back as SVG. libvips can rasterize SVG via librsvg,
but the Alpine `vips` package doesn't pull librsvg in by default — when
it's missing, libvips falls back to a much slower SVG path. Each call
to ProcessAll resizes the source to 5 sizes sequentially, so the delta
is roughly:

  with librsvg:    ~100ms total per logo
  without librsvg: ~30s total per logo

The 30s case was hitting kamal-proxy's request timeout, causing the
user-visible 504s observed today on the first REP.MC request after the
wikidata layer landed:

  cache miss → wikidata Q174747 (1.3s) → processing... → [504]

One-line apk install fix. ~3MB of additional image size.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fleveque fleveque merged commit e899c61 into main May 16, 2026
2 checks passed
@fleveque fleveque deleted the fix/svg-rsvg-runtime branch May 16, 2026 22:35
fleveque added a commit that referenced this pull request May 16, 2026
After yesterday's librsvg install (#21), the next REP.MC request still
hung at processing — turns out the Alpine `vips` package is compiled
WITHOUT rsvg support (verified via `vips --vips-config`), so installing
librsvg as a runtime lib does nothing. libvips can't load it.

Fortunately Wikimedia exposes server-side rasterization via the
`Special:FilePath/<file>?width=N` endpoint: when the source is SVG it
redirects to a thumbnail-server PNG; when it's already a raster the
query param is ignored. Either way, our downstream libvips pipeline
only sees PNG bytes — which it handles fine without librsvg.

Sandbox-verified: hit Special:FilePath/Repsol_logo.svg?width=512 →
HTTP 301 → upload.wikimedia.org/...//960px-Repsol_logo.svg.png → real
PNG (960×240, 8-bit RGBA). 512 chosen so the largest output size
(xl=256px) downsamples cleanly with headroom.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant