Skip to content

gofeed v1.4.1 roughly doubles ParseRSS cost (+192% allocs) — parser held at v1.3.0 #212

Description

@IAmBod

Summary

mmcdole/gofeed v1.3.0 → v1.4.1 roughly doubles the cost of the feed parse
path. #210 holds the parser at v1.3.0 so the rest of that dependency group
could land; this issue tracks actually taking the upgrade.

Measurement

Measured on top of main with only gofeed bumped (go get github.com/mmcdole/gofeed@v1.4.1), leaving the go directive at 1.25.9 so the
toolchain change that rode along in the group PR isn't a confounder.
BenchmarkParseRSS, -benchmem -count=6, benchstat:

ParseRSS-16  sec/op       707.7µ ± 4%  →  1330.0µ ± 13%   +87.94% (p=0.002 n=6)
ParseRSS-16  B/op        878.9Ki ± 0%  →  1572.7Ki ± 0%   +78.95% (p=0.002 n=6)
ParseRSS-16  allocs/op    8.498k ± 0%  →   24.801k ± 0%  +191.85% (p=0.002 n=6)

These numbers match the group PR's gate failure exactly, and pinning gofeed
back returns ParseRSS to baseline (~, p=0.310), so the parser bump accounts
for the entire regression.

The allocation count is the tell: +192% allocs/op for the same input is a
per-item or per-element allocation that used to be avoided, not a constant-factor
slowdown. sec/op tracking it at ~+88% is consistent with allocator/GC pressure
being the mechanism rather than added parsing work.

Why it matters here

Feed parsing is the service's hot path — every poll cycle, every feed. At the
default poll intervals a 2x parse cost is mostly GC pressure rather than
wall-clock risk, but it scales with feed count, and the catalog ships 179+ feeds.

What to do

  • Diff gofeed v1.3.0...v1.4.1 for the allocation change (the goxpp
    dependency also moved, and it's the XML pull-parser underneath — suspect
    it first).
  • Decide: absorb the cost, work around it at our call site, or raise it
    upstream with this benchmark attached.
  • If it's staying pinned for a while, add a dependabot.yml ignore entry so
    the group PR doesn't keep re-proposing it.
  • Un-pin in go.mod once resolved.

Notes

scripts/bench-compare.sh caught this on the dependency PR before it merged,
which is exactly the job it was added for.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions