Engineering serialization cost as a system budget across encode/decode CPU, allocation and retention, wire/storage bytes, copies, buffers, compression, schema evolution, compatibility, security, and rollout. Covers format/library selection by workload and contract, streaming versus materialization, buffer ownership/backpressure, representative JMH/component/load experiments, production attribution, and mixed-version failure tests. Use when serialization is measured hot, a new wire/cache/topic format is chosen, or “zero-copy”/binary-format claims need validation. General benchmark mechanics, schema governance, and Java native-serialization hardening have separate owners.
Choose and operate a serialization boundary from total system cost and compatibility, not one
library's small-payload throughput chart. The fastest encoder can lose after wire bytes,
compression, copies, allocation, downstream parsing, schema migration, or recovery are included.
Ownership boundary
This skill owns serialization performance models, experiments, buffer/copy strategy, and
production attribution.
schema-evolution-and-compatibility owns compatibility governance and rollout contracts.
java-serialization-hardening owns deep ObjectInputStream security/migration.
off-heap-memory owns native/direct memory lifecycle; serialization-performance owns how the
codec uses those buffers.
Decision contract
Inspect the project's toolchain, resolved codec versions/modules, framework configuration and
deployed readers before choosing an API. This skill has no universal Java/library baseline;
documentation examples are not authorization to upgrade the target. Missing measurements leave
performance benefits hypothetical; missing compatibility evidence can block a format migration.
boundary and trust zone: in-process/cache/process/network/storage/topic
producer/consumer languages, versions, ownership and deployment skew
payload schema, size/cardinality/nesting/optional-field and value distributions
read/write ratio and fields accessed
throughput/latency/tail/CPU/allocation/wire/storage objectives
streaming, framing, random access, compression and batching requirements
buffer ownership/lifetime/backpressure and maximum message policy
compatibility/registry/unknown-field/default/ordering/canonicalization rules
security/resource limits/privacy and malformed-input behavior
migration, dual-read/write, replay, rollback and retained-data horizon
Cost model
Measure stages separately and together:
end-to-end serialization cost =
object/model construction
+ encode/decode CPU
+ allocation, retention and GC consequence
+ buffer growth/copy/reference-count/lifetime cost
+ compression/decompression
+ framing/checksum/encryption
+ wire/storage bytes and downstream I/O
+ schema lookup/validation/conversion
+ queueing/backpressure/retry/replay effects
Normalize per business message and per useful byte/field where appropriate. Batch-level results can
hide per-message tail and oversized-item failure.
Eliminate by contract before speed
Constraint
Consequence
untrusted input
safe parser/resource limits; native Java serialization is not a default
long-lived data or rolling deploy
explicit schema/compatibility and stable identifiers
multiple languages
supported implementations and conformance fixtures for each
selective access to large immutable payload
indexed/lazy format may help if lifetime/validation costs fit
deterministic/canonical rules, not ordinary serializer defaults
No format automatically supplies organizational compatibility. Registry policy, generated code,
field IDs, defaults, unknown fields, enum evolution, maps/order, and implementation versions must
be tested across deployed producers/consumers.
Format families and trade-offs
Text/self-describing (for example JSON): broad interoperability and inspectability; repeated
names and lexical conversion can increase bytes/CPU. Parsers may reuse field-name symbols and
stream tokens, so “one String per key/value” is not a valid universal model.
Schema-based formats: Protocol Buffers uses numbered field tags; Avro binary records encode
values in writer-schema order without per-field tags. Their parsing, skipping and evolution
rules differ. Generated objects may provide direct access after materialization. Use
references/format-selection.md when comparing formats or changing codec configuration.
Indexed/in-place access formats (for example FlatBuffers/Cap'n Proto designs): avoid full
object materialization for some access patterns, while adding offset traversal, validation,
alignment/layout, buffer-lifetime, implementation and mutation constraints.
Object-graph/library-specific codecs (for example Kryo): flexible and often efficient within
controlled ecosystems; class registration, graph/reference semantics and version compatibility
become application protocol responsibilities.
“Zero-copy” is a claim about specific copies and stages, not end-to-end absence of copying. Kernel,
TLS, framing, decompression, buffer conversion, alignment and application materialization may remain.
Buffer, ownership, and streaming
Prefer writing to the next stage's bounded buffer/stream when it eliminates a demonstrated copy.
Before reuse/pooling, define:
owner, thread-safety, handoff and release point;
maximum retained capacity and oversized-message behavior;
heap/direct/native accounting and container headroom;
partial write/read, cancellation, timeout and exception cleanup;
reference-count/use-after-release and data leakage between tenants;
pool exhaustion/backpressure and shutdown/redeploy cleanup.
An asynchronous send must retain exclusive ownership or an appropriate lease until the transport
has finished reading the bytes. Enqueue, timeout or cancellation alone does not prove that point.
A read-only view can still observe mutations through another alias; copy or defer reuse when the
handoff contract cannot establish safety. Discard/reset a failed codec only by its documented policy.
ThreadLocal avoids concurrent codec use but can retain large buffers per platform thread and
behaves differently with virtual-thread workloads. Pools bound instances only if acquisition,
capacity reset, eviction, failure and telemetry are designed. Reuse can reduce allocation while
increasing retained memory or contention.
Library-specific caution
Do not infer protocol safety from a benchmark snippet:
Kryo registrations can use compact/stable IDs for registered types even when registration is not
globally required. setRegistrationRequired(true) rejects accidental unregistered types; it is
not what makes existing registered types use their IDs.
registration IDs and serializers must remain compatible with retained bytes and rolling versions;
order-based implicit registration is fragile unless frozen and tested.
Kryo instances are generally not thread-safe; choose confinement/pooling and test reset state.
disabling graph reference tracking changes semantics for shared/cyclic graphs, not only speed.
library defaults and version serializers are not substitutes for cross-version golden fixtures.
Never pin versions or capability claims from memory. Inspect the current official documentation,
release artifact and supported JDK/platform matrix.
Measurement ladder
Corpus characterization: production-derived, privacy-safe cohorts for size, nesting, values,
optional/unknown fields, compressibility, malformed and maximum inputs.
Semantic/conformance tests: an independent contract oracle plus round-trip and
cross-language/version fixtures for unknown/default/null/presence and numeric fidelity;
canonical bytes where required, corruption/resource limits. A same-codec round trip alone
cannot prove interoperability or that both directions did not normalize away required data.
JMH mechanism benchmark: encode and decode separately plus round trip where relevant; CPU,
allocation, output size, buffer mode, lifecycle, multiple forks and raw results.
Component benchmark: framing, registry, compression, buffer pool, network/storage and
backpressure with realistic concurrency.
Production/canary evidence: profiles, allocation/GC, queue depth, payload sizes, errors,
retries and SLOs normalized by useful work.
Migration/failure test: rolling versions, replayed old bytes, rollback, poison/max messages,
dependency/registry outage and resource exhaustion.
Use references/benchmarking-serialisers.md for the experiment matrix.
Production attribution
CPU samples at ObjectMapper.readValue, a generated parser, or codec method show sampled CPU
location, not automatically optimization value. Establish frequency per business operation,
inclusive/self cost, payload cohort, compilation/native frames, allocation/GC consequence, queueing,
and whether I/O or compression dominates end-to-end latency.
Allocation profiles find creation sites; they do not prove retained memory. Correlation between
allocation and GC pauses is not additive causal attribution because thread durations overlap and
collector work is phase-dependent. Use aligned work-normalized evidence and a controlled change.
Security and resource safety
Treat all deserialization across a trust boundary as parser attack surface:
cap bytes, nesting/depth, collections/arrays, references and decompressed expansion;
reject/route malformed, incompatible, unknown-type and oversized messages deterministically;
bound time, memory, concurrency and retries; avoid poison-message loops;
authenticate/integrity-check at the correct layer and protect sensitive payload/profile data;
fuzz/property-test parsers and cross-version fixtures.
Avoid Java native serialization for new external boundaries. If legacy ObjectInputStream remains,
use ObjectInputFilter with class and resource constraints, per-context policy where applicable,
and a migration plan; follow java-serialization-hardening and official serialization-filter docs.
Decision framework
Prefer a candidate when it:
satisfies trust, language, compatibility and retained-data constraints;
meets CPU/allocation/wire/tail objectives over all important payload cohorts;
has supported implementations, tooling and observable failure modes;
integrates with bounded buffers/backpressure and operational recovery;
survives mixed-version, rollback and malformed/max-input tests.
Reject or defer when the measured benefit is below migration risk/cost, only a toy corpus was tested,
the producer/consumer rollout cannot be made compatible, or buffer/native headroom is unbounded.
Return the contract, deployed baseline, supported observations, proposed change and validating
experiment. Mark failed/missing measurements inconclusive; report measured gains separately from
unexecuted rollout or failure tests. Scale the checks below to the changed boundary.
Anti-patterns
Anti-pattern
Why dangerous
Better alternative
Narrow exception
Choose fastest median encode
ignores decode/tail/bytes/compatibility
weighted system scorecard and failure tests
isolated one-way ephemeral path
“Binary is faster”
payload/library/hardware vary
representative corpus and stages
“Zero-copy” as architecture
copy boundaries/lifetime hidden
byte-movement and ownership map
verified single-stage claim
ThreadLocal unbounded buffers
retained memory multiplies by threads
cap/shrink/pool/stream with telemetry
few stable platform threads
New byte array per message by habit
copy/allocation pressure
stream/bounded reusable buffer after proof
ownership requires immutable byte array
Raw registration order as protocol
mixed deploy corrupts meaning
explicit stable IDs/schema/golden fixtures
single disposable session
Same-process A/B called controlled
order/JIT/GC interference remains
blocked/forked experiment and controls
exploratory diagnosis
Definition of done
Contract, trust boundary, compatibility horizon and migration are explicit.
Representative corpus includes size/value/schema/malformed/max cohorts.
Encode, decode, round trip, bytes, allocation, copies, compression and failure are measured as relevant.
Buffer ownership, retention, backpressure, cancellation and shutdown are bounded/tested.
JMH results preserve fork/corpus identity and component/load behavior validates impact.
Cross-version/language, rollback/replay and registry/dependency failures pass.
Security/resource limits and observability exist in production.
1---2name: serialization-performance3description: Engineering serialization cost as a system budget across encode/decode CPU, allocation and retention, wire/storage bytes, copies, buffers, compression, schema evolution, compatibility, security, and rollout. Covers format/library selection by workload and contract, streaming versus materialization, buffer ownership/backpressure, representative JMH/component/load experiments, production attribution, and mixed-version failure tests. Use when serialization is measured hot, a new wire/cache/topic format is chosen, or “zero-copy”/binary-format claims need validation. General benchmark mechanics, schema governance, and Java native-serialization hardening have separate owners.4---56# Serialization performance78## Purpose910Choose and operate a serialization boundary from total system cost and compatibility, not one11library's small-payload throughput chart. The fastest encoder can lose after wire bytes,12compression, copies, allocation, downstream parsing, schema migration, or recovery are included.1314## Ownership boundary1516- This skill owns serialization performance models, experiments, buffer/copy strategy, and17 production attribution.18- `schema-evolution-and-compatibility` owns compatibility governance and rollout contracts.19- `java-serialization-hardening` owns deep `ObjectInputStream` security/migration.20- `jmh-microbenchmarks` owns harness validity; `load-testing` owns end-to-end arrivals/queueing.21- `off-heap-memory` owns native/direct memory lifecycle; `serialization-performance` owns how the22 codec uses those buffers.2324## Decision contract2526Inspect the project's toolchain, resolved codec versions/modules, framework configuration and27deployed readers before choosing an API. This skill has no universal Java/library baseline;28documentation examples are not authorization to upgrade the target. Missing measurements leave29performance benefits hypothetical; missing compatibility evidence can block a format migration.3031```text32boundary and trust zone: in-process/cache/process/network/storage/topic33producer/consumer languages, versions, ownership and deployment skew34payload schema, size/cardinality/nesting/optional-field and value distributions35read/write ratio and fields accessed36throughput/latency/tail/CPU/allocation/wire/storage objectives37streaming, framing, random access, compression and batching requirements38buffer ownership/lifetime/backpressure and maximum message policy39compatibility/registry/unknown-field/default/ordering/canonicalization rules40security/resource limits/privacy and malformed-input behavior41migration, dual-read/write, replay, rollback and retained-data horizon42```4344## Cost model4546Measure stages separately and together:4748```text49end-to-end serialization cost =50 object/model construction51 + encode/decode CPU52 + allocation, retention and GC consequence53 + buffer growth/copy/reference-count/lifetime cost54 + compression/decompression55 + framing/checksum/encryption56 + wire/storage bytes and downstream I/O57 + schema lookup/validation/conversion58 + queueing/backpressure/retry/replay effects59```6061Normalize per business message and per useful byte/field where appropriate. Batch-level results can62hide per-message tail and oversized-item failure.6364## Eliminate by contract before speed6566| Constraint | Consequence |67| ------------------------------------------- | ----------------------------------------------------------------------- |68| untrusted input | safe parser/resource limits; native Java serialization is not a default |69| long-lived data or rolling deploy | explicit schema/compatibility and stable identifiers |70| multiple languages | supported implementations and conformance fixtures for each |71| selective access to large immutable payload | indexed/lazy format may help if lifetime/validation costs fit |72| streaming/unknown total size | incremental API, framing, cancellation, backpressure |73| human inspection/interoperability | text/self-describing trade may outweigh bytes/CPU |74| canonical bytes/signatures/dedup | deterministic/canonical rules, not ordinary serializer defaults |7576No format automatically supplies organizational compatibility. Registry policy, generated code,77field IDs, defaults, unknown fields, enum evolution, maps/order, and implementation versions must78be tested across deployed producers/consumers.7980## Format families and trade-offs8182- **Text/self-describing** (for example JSON): broad interoperability and inspectability; repeated83 names and lexical conversion can increase bytes/CPU. Parsers may reuse field-name symbols and84 stream tokens, so “one String per key/value” is not a valid universal model.85- **Schema-based formats:** Protocol Buffers uses numbered field tags; Avro binary records encode86 values in writer-schema order without per-field tags. Their parsing, skipping and evolution87 rules differ. Generated objects may provide direct access after materialization. Use88 `references/format-selection.md` when comparing formats or changing codec configuration.89- **Indexed/in-place access formats** (for example FlatBuffers/Cap'n Proto designs): avoid full90 object materialization for some access patterns, while adding offset traversal, validation,91 alignment/layout, buffer-lifetime, implementation and mutation constraints.92- **Object-graph/library-specific codecs** (for example Kryo): flexible and often efficient within93 controlled ecosystems; class registration, graph/reference semantics and version compatibility94 become application protocol responsibilities.9596“Zero-copy” is a claim about specific copies and stages, not end-to-end absence of copying. Kernel,97TLS, framing, decompression, buffer conversion, alignment and application materialization may remain.9899## Buffer, ownership, and streaming100101Prefer writing to the next stage's bounded buffer/stream when it eliminates a demonstrated copy.102Before reuse/pooling, define:103104- owner, thread-safety, handoff and release point;105- maximum retained capacity and oversized-message behavior;106- heap/direct/native accounting and container headroom;107- partial write/read, cancellation, timeout and exception cleanup;108- reference-count/use-after-release and data leakage between tenants;109- pool exhaustion/backpressure and shutdown/redeploy cleanup.110111An asynchronous send must retain exclusive ownership or an appropriate lease until the transport112has finished reading the bytes. Enqueue, timeout or cancellation alone does not prove that point.113A read-only view can still observe mutations through another alias; copy or defer reuse when the114handoff contract cannot establish safety. Discard/reset a failed codec only by its documented policy.115116`ThreadLocal` avoids concurrent codec use but can retain large buffers per platform thread and117behaves differently with virtual-thread workloads. Pools bound instances only if acquisition,118capacity reset, eviction, failure and telemetry are designed. Reuse can reduce allocation while119increasing retained memory or contention.120121## Library-specific caution122123Do not infer protocol safety from a benchmark snippet:124125- Kryo registrations can use compact/stable IDs for registered types even when registration is not126 globally required. `setRegistrationRequired(true)` rejects accidental unregistered types; it is127 not what makes existing registered types use their IDs.128- registration IDs and serializers must remain compatible with retained bytes and rolling versions;129 order-based implicit registration is fragile unless frozen and tested.130- Kryo instances are generally not thread-safe; choose confinement/pooling and test reset state.131- disabling graph reference tracking changes semantics for shared/cyclic graphs, not only speed.132- library defaults and version serializers are not substitutes for cross-version golden fixtures.133134Never pin versions or capability claims from memory. Inspect the current official documentation,135release artifact and supported JDK/platform matrix.136137## Measurement ladder1381391. **Corpus characterization:** production-derived, privacy-safe cohorts for size, nesting, values,140 optional/unknown fields, compressibility, malformed and maximum inputs.1412. **Semantic/conformance tests:** an independent contract oracle plus round-trip and142 cross-language/version fixtures for unknown/default/null/presence and numeric fidelity;143 canonical bytes where required, corruption/resource limits. A same-codec round trip alone144 cannot prove interoperability or that both directions did not normalize away required data.1453. **JMH mechanism benchmark:** encode and decode separately plus round trip where relevant; CPU,146 allocation, output size, buffer mode, lifecycle, multiple forks and raw results.1474. **Component benchmark:** framing, registry, compression, buffer pool, network/storage and148 backpressure with realistic concurrency.1495. **Production/canary evidence:** profiles, allocation/GC, queue depth, payload sizes, errors,150 retries and SLOs normalized by useful work.1516. **Migration/failure test:** rolling versions, replayed old bytes, rollback, poison/max messages,152 dependency/registry outage and resource exhaustion.153154Use `references/benchmarking-serialisers.md` for the experiment matrix.155156## Production attribution157158CPU samples at `ObjectMapper.readValue`, a generated parser, or codec method show sampled CPU159location, not automatically optimization value. Establish frequency per business operation,160inclusive/self cost, payload cohort, compilation/native frames, allocation/GC consequence, queueing,161and whether I/O or compression dominates end-to-end latency.162163Allocation profiles find creation sites; they do not prove retained memory. Correlation between164allocation and GC pauses is not additive causal attribution because thread durations overlap and165collector work is phase-dependent. Use aligned work-normalized evidence and a controlled change.166167## Security and resource safety168169Treat all deserialization across a trust boundary as parser attack surface:170171- cap bytes, nesting/depth, collections/arrays, references and decompressed expansion;172- reject/route malformed, incompatible, unknown-type and oversized messages deterministically;173- bound time, memory, concurrency and retries; avoid poison-message loops;174- authenticate/integrity-check at the correct layer and protect sensitive payload/profile data;175- fuzz/property-test parsers and cross-version fixtures.176177Avoid Java native serialization for new external boundaries. If legacy `ObjectInputStream` remains,178use `ObjectInputFilter` with class and resource constraints, per-context policy where applicable,179and a migration plan; follow `java-serialization-hardening` and official serialization-filter docs.180181## Decision framework182183Prefer a candidate when it:184185- satisfies trust, language, compatibility and retained-data constraints;186- meets CPU/allocation/wire/tail objectives over all important payload cohorts;187- has supported implementations, tooling and observable failure modes;188- integrates with bounded buffers/backpressure and operational recovery;189- survives mixed-version, rollback and malformed/max-input tests.190191Reject or defer when the measured benefit is below migration risk/cost, only a toy corpus was tested,192the producer/consumer rollout cannot be made compatible, or buffer/native headroom is unbounded.193Return the contract, deployed baseline, supported observations, proposed change and validating194experiment. Mark failed/missing measurements inconclusive; report measured gains separately from195unexecuted rollout or failure tests. Scale the checks below to the changed boundary.196197## Anti-patterns198199| Anti-pattern | Why dangerous | Better alternative | Narrow exception |200| ----------------------------------- | --------------------------------------- | ------------------------------------------- | --------------------------------------- |201| Choose fastest median encode | ignores decode/tail/bytes/compatibility | weighted system scorecard and failure tests | isolated one-way ephemeral path |202| “Binary is faster” | payload/library/hardware vary | representative corpus and stages |203| “Zero-copy” as architecture | copy boundaries/lifetime hidden | byte-movement and ownership map | verified single-stage claim |204| ThreadLocal unbounded buffers | retained memory multiplies by threads | cap/shrink/pool/stream with telemetry | few stable platform threads |205| New byte array per message by habit | copy/allocation pressure | stream/bounded reusable buffer after proof | ownership requires immutable byte array |206| Raw registration order as protocol | mixed deploy corrupts meaning | explicit stable IDs/schema/golden fixtures | single disposable session |207| Same-process A/B called controlled | order/JIT/GC interference remains | blocked/forked experiment and controls | exploratory diagnosis |208209## Definition of done210211- [ ] Contract, trust boundary, compatibility horizon and migration are explicit.212- [ ] Representative corpus includes size/value/schema/malformed/max cohorts.213- [ ] Encode, decode, round trip, bytes, allocation, copies, compression and failure are measured as relevant.214- [ ] Buffer ownership, retention, backpressure, cancellation and shutdown are bounded/tested.215- [ ] JMH results preserve fork/corpus identity and component/load behavior validates impact.216- [ ] Cross-version/language, rollback/replay and registry/dependency failures pass.217- [ ] Security/resource limits and observability exist in production.218219## References220221- [Format-selection scorecard](references/format-selection.md)222- [Benchmarking and profiling serializers](references/benchmarking-serialisers.md)223- [Java serialization filtering](https://docs.oracle.com/en/java/javase/25/core/serialization-filtering1.html)224- [Protocol Buffers encoding](https://protobuf.dev/programming-guides/encoding/)225- [Apache Avro specification](https://avro.apache.org/docs/current/specification/)226- [FlatBuffers internals](https://flatbuffers.dev/internals/)227- [Cap'n Proto encoding](https://capnproto.org/encoding.html)228- [Kryo documentation](https://github.com/EsotericSoftware/kryo)
Run npx skillmds@latest add robsonkades/serialization-performance in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Engineering serialization cost as a system budget across encode/decode CPU, allocation and retention, wire/storage bytes, copies, buffers, compression, schema evolution, compatibility, security, and rollout. Covers format/library selection by workload and contract, streaming versus materialization, buffer ownership/backpressure, representative JMH/component/load experiments, production attribution, and mixed-version failure tests. Use when serialization is measured hot, a new wire/cache/topic format is chosen, or “zero-copy”/binary-format claims need validation. General benchmark mechanics, schema governance, and Java native-serialization hardening have separate owners. It is listed under Web & Frontend on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
robsonkades (@robsonkades) published this skill. Their other Agent Skills are listed on their SkillMD profile.