Skip to content

Revert Blackbird default; align Jackson to 2.21#21

Merged
jkschneider merged 1 commit into
mainfrom
perf-fixes
May 10, 2026
Merged

Revert Blackbird default; align Jackson to 2.21#21
jkschneider merged 1 commit into
mainfrom
perf-fixes

Conversation

@jkschneider
Copy link
Copy Markdown
Member

@jkschneider jkschneider commented May 10, 2026

Summary

Why revert Blackbird

The original PR's bench was on Jackson 2.17.2 — RealTraceBench (replaying a captured mod run trace) showed Blackbird at ~2x faster deserialize and ~1.5x serialize. Re-running the same bench against Jackson 2.21.x tells a different story:

Bench (Jackson 2.21.1, real trace, max=303KB payload) Vanilla Blackbird
serialize_max 317 ± 19 µs 540 ± 31 µs ← ~70% slower
deserialize_max 1537 ± 220 µs 1500 ± 68 µs (a wash)

The serialize regression is real (tight error bars, no CI overlap). End-to-end on mod run org.openrewrite.node.migrate.upgrade-node-24 against the JS Applications working set, BatchVisit p50/p99 went up 4-12x / 4-65x against the pre-Blackbird baseline.

We don't yet have a clean answer for why Blackbird 2.21.x regresses serialize while 2.17.2 didn't — Jackson 2.21 likely shifted the reflective-vs-generated-accessor balance — but the data is unambiguous: shipping Blackbird as a default in this Jackson lineage is a net loss for the primary consumer.

Why bump parameter-names

moderne-cli and recent openrewrite/rewrite force all com.fasterxml.jackson* to 2.21.1 via dependency resolution rules. Pinning jackson-module-parameter-names to 2.17.2 in jsonrpc resolves to the forced 2.21.1 anyway in those consumers, but locally and in any consumer that doesn't force, the 2.17.2 / 2.21.1 mix is the slightly-skewed combo that may explain some of the Blackbird-regression weirdness above. Aligning the pin to 2.21.1 keeps BOM resolution stable.

What stays

Test plan

  • jsonrpc unit tests pass (./gradlew test)
  • Re-run mod run upgrade-node-24 against the JS Applications working set with this version and confirm BatchVisit p50/p99 return to the pre-1.0.8 baseline

…ackson 2.21

The Blackbird default registered in #20 was benched against Jackson 2.17.2,
where it showed a ~2x deserialize win. moderne-cli (the primary consumer) and
most current openrewrite components have moved to Jackson 2.21, where
Blackbird no longer wins on deserialize and *regresses* serialize by ~70%
on the real-trace JMH bench (vanilla 317±19 µs vs Blackbird 540±31 µs on a
303 KB GetObject payload — non-overlapping CIs).

End-to-end this manifests as visibly slower `mod run` in production after
1.0.8 shipped: BatchVisit p50/p99 times rose 4-12x / 4-65x compared to the
1.0.7 baseline on the JS Applications working set.

While here, bump jackson-module-parameter-names from 2.17.2 to 2.21.1 to
match what consumers force via their version-alignment rules; this keeps
the BOM resolution stable and avoids accidental version skew at runtime.

The streaming TokenBuffer-based deserialize from #18 stays — that's the
deserialize-side win Blackbird was attempting to chase, already shipped.
@jkschneider jkschneider merged commit 588f093 into main May 10, 2026
1 check passed
@jkschneider jkschneider deleted the perf-fixes branch May 10, 2026 16:44
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