Skip to content

Commit a4c41af

Browse files
committed
Merge branch 'main' of github.com:FasterXML/jackson into main
2 parents 9b1deec + 76a96cd commit a4c41af

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

jackson3/MIGRATING_TO_JACKSON_3.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,46 @@ For the full list of all issues resolved for 3.0, see [Jackson 3.0 Release Notes
5656
* Blog posts about regarding Jackson 3 release from our own @cowtowncoder [here](https://cowtowncoder.medium.com/jackson-3-0-0-ga-released-1f669cda529a)
5757
* Jackson 3 support in Spring [here](https://spring.io/blog/2025/10/07/introducing-jackson-3-support-in-spring)
5858

59-
---
59+
## Performance considerations (new in 3.x)
60+
61+
While the functional migration covers API and behavior changes, a couple of **default settings in 3.x can have modest performance impact** compared to 2.x. If you are sensitive to throughput/latency, consider the following:
62+
63+
1. **Trailing-token checks**
64+
- In Jackson 3.x, `DeserializationFeature.FAIL_ON_TRAILING_TOKENS` is **enabled by default** (it was off by default in 2.x). This adds a small amount of overhead because the parser validates there is no extra content after a successful value parse.
65+
- If your inputs are trusted/controlled and you want to match 2.x behavior, you can disable it:
66+
67+
```java
68+
JsonMapper mapper = JsonMapper.builder()
69+
.disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)
70+
.build();
71+
```
72+
73+
- Recommendation: keep it **enabled** for security/correctness unless profiling shows a measurable regression on your workload.
74+
75+
2. **Recycler pool choice**
76+
- Jackson 3.0 defaults to a **deque-based** `RecyclerPool`, which can add overhead in some common cases versus the 2.x default (`JsonRecyclerPools.threadLocalPool()`).
77+
- If your workload benefited from the 2.x behavior, set the pool explicitly when building your `TokenStreamFactory` (e.g., `JsonFactory`), and then pass that factory to your mapper:
78+
79+
```java
80+
JsonFactory factory = JsonFactory.builder()
81+
.recyclerPool(JsonRecyclerPools.threadLocalPool())
82+
.build();
83+
84+
JsonMapper mapper = JsonMapper.builder(factory)
85+
.build();
86+
```
87+
88+
- Note: choose the pool that matches your deployment model (single-thread hot loops vs. highly concurrent). Test both options under production-like load.
89+
90+
91+
We will expand this section as more performance-affecting defaults are identified.
92+
93+
94+
**References**
95+
- Default for trailing-tokens in 3.0 discussion: [jackson-databind#3406](https://github.com/FasterXML/jackson-databind/issues/3406)
96+
- Recycler pool defaults & alternatives: [jackson-core#1117](https://github.com/FasterXML/jackson-core/issues/1117), default change notes [jackson-core#1266](https://github.com/FasterXML/jackson-core/issues/1266), how to override in 2.17.x/3.x [jackson-core#1293](https://github.com/FasterXML/jackson-core/issues/1293)
97+
- Background on moving away from ThreadLocal pools (virtual threads): [jackson-core#919](https://github.com/FasterXML/jackson-core/issues/919)
98+
6099

61100
# Conversion
62101

@@ -340,6 +379,7 @@ But not all changes are equally likely to cause compatibility problems: here are
340379

341380
#### Changes: DeserializationFeature
342381

382+
* `DeserializationFeature.FAIL_ON_TRAILING_TOKENS` (**enabled in 3.0**, disabled in 2.x): enables validation that no extra content follows a parsed value; improves safety but introduces modest overhead. Disable if inputs are trusted and performance is critical.
343383
* `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` (disabled in 3.0): May mask real issues with name mismatch
344384
* `DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES` (enabled in 3.0): May start failing `@JsonCreator` usage where missing values for primitive (like `int`) valued properties can start failing.
345385

@@ -419,6 +459,20 @@ JsonFactory f2 = f.rebuild()
419459
.build();
420460
```
421461

462+
##### Choosing a RecyclerPool (performance)
463+
464+
To align with 2.x performance characteristics, you may explicitly configure the recycler pool on the factory builder:
465+
466+
```java
467+
JsonFactory f = JsonFactory.builder()
468+
.recyclerPool(JsonRecyclerPools.threadLocalPool())
469+
.build();
470+
471+
JsonMapper mapper = JsonMapper.builder(f).build();
472+
```
473+
474+
If your workload is highly concurrent, benchmark the default deque-based pool versus `threadLocalPool()` and choose based on observed throughput/latency and memory behavior.
475+
422476
Finally, to pass customized `TokenStreamFactory` for `ObjectMapper`, you will need to pass instance to `builder()` like so:
423477

424478
```

0 commit comments

Comments
 (0)