Releases: apache/fory
v0.14.1
Highlights
- feat(rust): add generate_default attr, no longer generate Default by default by @ariesdevil in #3074
Features
- feat(rust): add generate_default attr, no longer generate Default by default by @ariesdevil in #3074
- feat(java): mark createSerializer as public by @chaokunyang
Bug Fix
- fix(java): Fix CopyOnWriteArrayList field serialization by @vybhavjs in #3079
- fix(java): Better ergonomics for AllowListChecker by @Asuka-star in #3061
- fix(java): fix read class def when writing classdefs by @chaokunyang in 3ad627c9
- fix(Rust): Move the calculating of TypeMeta::bytes and TypeMeta::hash ahead of serialization by @urlyy in #3060
- fix(Rust): prevent obtaining generic type metadata on custom types(struct/enum) by @urlyy in #3057
Full Changelog: v0.14.0...v0.14.1
v0.14.1-rc1
Highlights
- feat(rust): add generate_default attr, no longer generate Default by default by @ariesdevil in #3074
Features
- feat(rust): add generate_default attr, no longer generate Default by default by @ariesdevil in #3074
- feat(java): mark createSerializer as public by @chaokunyang
Bug Fix
- fix(java): Fix CopyOnWriteArrayList field serialization by @vybhavjs in #3079
- fix(java): Better ergonomics for AllowListChecker by @Asuka-star in #3061
- fix(java): fix read class def when writing classdefs by @chaokunyang in 3ad627c9
- fix(Rust): Move the calculating of TypeMeta::bytes and TypeMeta::hash ahead of serialization by @urlyy in #3060
- fix(Rust): prevent obtaining generic type metadata on custom types(struct/enum) by @urlyy in #3057
Full Changelog: v0.14.0...v0.14.1-rc1
v0.14.0
Highlights
- Official C++ Support: Introduced the official Apache Fory C++ implementation, featuring a high-performance object graph serialization framework, xlang support, and comprehensive benchmarks.
- Row Format & Type System: Implemented a new row-oriented format type system across Java, Python, and C++, enabling row-columnar conversions and removing external Arrow dependencies for schema encoding.
- Performance Enhancements: Significant optimizations across all languages, including thread-local context management in Rust, fast flat-int maps for C++ type dispatch, and optimized buffer read/write operations.
- Ecosystem Updates: Added support for JDK 25 (Java), Go 1.23, and Bazel 8. Python support has been officially marked as stable with improved build parallelism.
- Advanced Java Features: Added GraalVM Native Image support via
ForyFeatureand new optimized serializers for blocking queues and final fields.
Features
- feat(python): add raw method to buffer object by @chaokunyang in #2875
- feat(rust): add duration serializer support by @chaokunyang in #2878
- feat(rust): add typename to unregistered error message by @chaokunyang in #2881
- perf(rust): support criterion profiler to generate flamegraph by @chaokunyang in #2882
- refactor(rust): merge fory_debug into fory macro attr by @chaokunyang in #2883
- feat(rust): direct derive primitve write/read by @chaokunyang in #2890
- perf(rust): optimize buffer write read perf by @chaokunyang in #2892
- feat(Rust): Support u128 & u128_array by @urlyy in #2899
- feat(c++): implement fory cpp object graph serialization framework by @chaokunyang in #2908
- feat(python): pure python row-columar convert by @chaokunyang in #2919
- feat(c++): implement xlang serialization for c++ by @chaokunyang in #2925
- feat(c++/python): add row format schema and remove arrow dependency by @chaokunyang in #2928
- feat(java): implement fory row format type system by @chaokunyang in #2931
- feat(python): implement cython bazel build directly without 3rd deps by @chaokunyang in #2936
- feat(c+/python): upgrade bazel to bazel8 by @chaokunyang in #2937
- feat(java/python/c++): add schema encoder and remove arrow serializers by @chaokunyang in #2938
- feat(c++): check max dyn depth when deserializing polymorphic types by @chaokunyang in #2939
- feat(c++): add cmake build support and add cpp examples by @chaokunyang in #2942
- feat(c++ ): add cpp benchmark by @chaokunyang in #2943
- perf(rust): use segmented pool to reduce contention of fory pool by @chaokunyang in #2945
- perf(rust): use thread local to manage fory rust WriteContext/ReadContext by @chaokunyang in #2946
- feat(rust): add fory config for rust by @chaokunyang in #2947
- perf(c++): optimize cpp serialization performance by @chaokunyang in #2944
- perf(c++): remove shared_ptr from type info to reduce atomic counter cost by @chaokunyang in #2951
- feat: refine python module check by @chaokunyang in #2952
- feat(java): support jdk 25 by @chaokunyang in #2954
- feat(java): add optimized serializers for blocking queues by @zhan7236 in #2955
- perf(c++): directly error set instead of result to reduce cost on hotpath by @chaokunyang in #2959
- perf(c++): optimize primitive struct fields read performance by @chaokunyang in #2960
- feat(java): implement FinalFieldReplaceResolveSerializer for final fields with writeReplace/readResolve methods by @mchernyakov in #2917
- perf(c++): add mac profile script for c++ by @chaokunyang in #2962
- perf(c++): fair benchmark for cpp by @chaokunyang in #2963
- perf(c++): optimize type dispatch performance by a fast flat-int map by @chaokunyang in #2966
- perf(c++): add media content benchmark by @chaokunyang in #2968
- feat(c++): support polymorphic collection elements serialization by @chaokunyang in #2974
- feat(c++): add cpp tuple serializer by @chaokunyang in #2975
- refactor(xlang): use 0 for unknow type id by @chaokunyang in #2985
- feat(java): Add ForyFeature for GraalVM Native Image by @mengnankkkk in #2701
- feat(c++): support container xlang serialization with polymorphic elements by @chaokunyang in #2980
- feat(python): parallel python wheel build by @chaokunyang in #2989
- perf(c++): improve the serialization performance of array/collection by @LiangliangSui in #2986
- feat(go): upgrade go to to 1.23 by @chaokunyang in #2995
- perf(c++): centralize error state in context for faster serialization by @chaokunyang in #3009
- refactor(go): redesign serialization implementation with performance and usability improvements by @chaokunyang in #2998
- refactor(rust): merge rust type layer into TypeMeta by @chaokunyang in #3019
- ci: remove macos x86 CI for Python by @chaokunyang in #3023
- feat(c++): support unsigned type for cpp by @chaokunyang in #3022
- feat(c++): support variant-based union type serialization for c++ by @chaokunyang in #3032
- feat(java): refactor ObjectStreamSerializer to use meta shared compatible serializer by @chaokunyang in #3034
- feat(java): separate user register type id with fory registered type id by @chaokunyang in #3035
- feat(): add c++ user guide doc by @chaokunyang in #3037
- refactor(c++/rust): refine c++ serialize_to API by @chaokunyang in #3045
Bug Fix
- fix(Rust): fix Binary implementation by @urlyy in #2902
- fix(rust): fix array field support by @chaokunyang in #2933
- fix(rust): raise error for nested polymorphics for collection by @chaokunyang in #2934
- fix(kotlin): support Kotlin field with Java reserved world by @chaokunyang in #2948
- fix(java): handle TypeVariable in row format type inference by @chaokunyang in #2949
- fix(java): use single quotes in Python command for Windows compatibility by @zhan7236 in #2953
- fix(java): fix race condition in blocking queue serializers by @zhan7236 in #2956
- fix(cpp): fix the type error by @LiangliangSui in #2961
- fix(go): fix struct value reference tracking bug by @chaokunyang in #2991
- fix(java): support serialization of CopyOnWriteArraySet by @LiangliangSui in #2999
Other Improvements
- docs: fix broken table in in java_serialization_guide.md by @mosinnik in #2876
- chore(rust): fix tuple test comment by @chaokunyang in #2877
- docs(rust): remove redundant doc for shared reference by @chaokunyang in #2879
- chore(Java): Update java quickstart doc, for note register order-sensitive by @moooonk in #2837
- chore(CI): Add caching for bazel in github workflows by @prakash-218 in #2888
- chore(CI): Fix cache with symlinks by @prakash-218 in #2893
- chore: move benchmarks to separate dir to speed up ci build by @chaokunyang in #2894
- docs: fix rust benchmark links by @chaokunyang in #2896
- docs: fix cargo benchmark comand in doc by @chaokunyang in #2897
- chore: bump release version to 0.13.1 by @chaokunyang in #2901
- docs(java): add logging section by @mosinnik in #2905
- chore(c++): remove cpp benchmarks by @chaokunyang in #2926
- chore(c++): move meta string to meta dir by @chaokunyang in #2940
- docs: remove unused type mappings for arrow types by @chaokunyang in #2964
- chore: Remove the content related to arrow. by @LiangliangSui in #2965
- chore(c++): move common macro into macros.h by @chaokunyang in https://github.com/apache/f...
v0.14.0-rc1
Highlights
- Official C++ Support: Introduced the official Apache Fory C++ implementation, featuring a high-performance object graph serialization framework, xlang support, and comprehensive benchmarks.
- Row Format & Type System: Implemented a new row-oriented format type system across Java, Python, and C++, enabling row-columnar conversions and removing external Arrow dependencies for schema encoding.
- Performance Enhancements: Significant optimizations across all languages, including thread-local context management in Rust, fast flat-int maps for C++ type dispatch, and optimized buffer read/write operations.
- Ecosystem Updates: Added support for JDK 25 (Java), Go 1.23, and Bazel 8. Python support has been officially marked as stable with improved build parallelism.
- Advanced Java Features: Added GraalVM Native Image support via
ForyFeatureand new optimized serializers for blocking queues and final fields.
Features
- feat(python): add raw method to buffer object by @chaokunyang in #2875
- feat(rust): add duration serializer support by @chaokunyang in #2878
- feat(rust): add typename to unregistered error message by @chaokunyang in #2881
- perf(rust): support criterion profiler to generate flamegraph by @chaokunyang in #2882
- refactor(rust): merge fory_debug into fory macro attr by @chaokunyang in #2883
- feat(rust): direct derive primitve write/read by @chaokunyang in #2890
- perf(rust): optimize buffer write read perf by @chaokunyang in #2892
- feat(Rust): Support u128 & u128_array by @urlyy in #2899
- feat(c++): implement fory cpp object graph serialization framework by @chaokunyang in #2908
- feat(python): pure python row-columar convert by @chaokunyang in #2919
- feat(c++): implement xlang serialization for c++ by @chaokunyang in #2925
- feat(c++/python): add row format schema and remove arrow dependency by @chaokunyang in #2928
- feat(java): implement fory row format type system by @chaokunyang in #2931
- feat(python): implement cython bazel build directly without 3rd deps by @chaokunyang in #2936
- feat(c+/python): upgrade bazel to bazel8 by @chaokunyang in #2937
- feat(java/python/c++): add schema encoder and remove arrow serializers by @chaokunyang in #2938
- feat(c++): check max dyn depth when deserializing polymorphic types by @chaokunyang in #2939
- feat(c++): add cmake build support and add cpp examples by @chaokunyang in #2942
- feat(c++ ): add cpp benchmark by @chaokunyang in #2943
- perf(rust): use segmented pool to reduce contention of fory pool by @chaokunyang in #2945
- perf(rust): use thread local to manage fory rust WriteContext/ReadContext by @chaokunyang in #2946
- feat(rust): add fory config for rust by @chaokunyang in #2947
- perf(c++): optimize cpp serialization performance by @chaokunyang in #2944
- perf(c++): remove shared_ptr from type info to reduce atomic counter cost by @chaokunyang in #2951
- feat: refine python module check by @chaokunyang in #2952
- feat(java): support jdk 25 by @chaokunyang in #2954
- feat(java): add optimized serializers for blocking queues by @zhan7236 in #2955
- perf(c++): directly error set instead of result to reduce cost on hotpath by @chaokunyang in #2959
- perf(c++): optimize primitive struct fields read performance by @chaokunyang in #2960
- feat(java): implement FinalFieldReplaceResolveSerializer for final fields with writeReplace/readResolve methods by @mchernyakov in #2917
- perf(c++): add mac profile script for c++ by @chaokunyang in #2962
- perf(c++): fair benchmark for cpp by @chaokunyang in #2963
- perf(c++): optimize type dispatch performance by a fast flat-int map by @chaokunyang in #2966
- perf(c++): add media content benchmark by @chaokunyang in #2968
- feat(c++): support polymorphic collection elements serialization by @chaokunyang in #2974
- feat(c++): add cpp tuple serializer by @chaokunyang in #2975
- refactor(xlang): use 0 for unknow type id by @chaokunyang in #2985
- feat(java): Add ForyFeature for GraalVM Native Image by @mengnankkkk in #2701
- feat(c++): support container xlang serialization with polymorphic elements by @chaokunyang in #2980
- feat(python): parallel python wheel build by @chaokunyang in #2989
- perf(c++): improve the serialization performance of array/collection by @LiangliangSui in #2986
- feat(go): upgrade go to to 1.23 by @chaokunyang in #2995
- perf(c++): centralize error state in context for faster serialization by @chaokunyang in #3009
- refactor(go): redesign serialization implementation with performance and usability improvements by @chaokunyang in #2998
- refactor(rust): merge rust type layer into TypeMeta by @chaokunyang in #3019
- ci: remove macos x86 CI for Python by @chaokunyang in #3023
- feat(c++): support unsigned type for cpp by @chaokunyang in #3022
- feat(c++): support variant-based union type serialization for c++ by @chaokunyang in #3032
- feat(java): refactor ObjectStreamSerializer to use meta shared compatible serializer by @chaokunyang in #3034
- feat(java): separate user register type id with fory registered type id by @chaokunyang in #3035
- feat(): add c++ user guide doc by @chaokunyang in #3037
- refactor(c++/rust): refine c++ serialize_to API by @chaokunyang in #3045
Bug Fix
- fix(Rust): fix Binary implementation by @urlyy in #2902
- fix(rust): fix array field support by @chaokunyang in #2933
- fix(rust): raise error for nested polymorphics for collection by @chaokunyang in #2934
- fix(kotlin): support Kotlin field with Java reserved world by @chaokunyang in #2948
- fix(java): handle TypeVariable in row format type inference by @chaokunyang in #2949
- fix(java): use single quotes in Python command for Windows compatibility by @zhan7236 in #2953
- fix(java): fix race condition in blocking queue serializers by @zhan7236 in #2956
- fix(cpp): fix the type error by @LiangliangSui in #2961
- fix(go): fix struct value reference tracking bug by @chaokunyang in #2991
- fix(java): support serialization of CopyOnWriteArraySet by @LiangliangSui in #2999
Other Improvements
- docs: fix broken table in in java_serialization_guide.md by @mosinnik in #2876
- chore(rust): fix tuple test comment by @chaokunyang in #2877
- docs(rust): remove redundant doc for shared reference by @chaokunyang in #2879
- chore(Java): Update java quickstart doc, for note register order-sensitive by @moooonk in #2837
- chore(CI): Add caching for bazel in github workflows by @prakash-218 in #2888
- chore(CI): Fix cache with symlinks by @prakash-218 in #2893
- chore: move benchmarks to separate dir to speed up ci build by @chaokunyang in #2894
- docs: fix rust benchmark links by @chaokunyang in #2896
- docs: fix cargo benchmark comand in doc by @chaokunyang in #2897
- chore: bump release version to 0.13.1 by @chaokunyang in #2901
- docs(java): add logging section by @mosinnik in #2905
- chore(c++): remove cpp benchmarks by @chaokunyang in #2926
- chore(c++): move meta string to meta dir by @chaokunyang in #2940
- docs: remove unused type mappings for arrow types by @chaokunyang in #2964
- chore: Remove the content related to arrow. by @LiangliangSui in #2965
- chore(c++): move common macro into macros.h by @chaokunyang in https://github.com/apache/f...
v0.13.2
Highlights
- perf(rust): use thread local to manage fory rust WriteContext/ReadContext by @chaokunyang in
#2946 - feat(rust): add typename to unregistered error message by @chaokunyang in #2881
Features
- feat(rust): add fory config for rust by @chaokunyang in #2947
- perf(rust): use thread local to manage fory rust WriteContext/ReadContext by @chaokunyang in
#2946 - perf(rust): use segmented pool to reduce contention of fory pool by @chaokunyang in
#2945 - feat(Rust): Support u128 & u128_array by @urlyy in #2899
- perf(rust): optimize buffer write read perf by @chaokunyang in #2892
- feat(rust): direct derive primitve write/read by @chaokunyang in #2890
- refactor(rust): merge fory_debug into fory macro attr by @chaokunyang in #2883
- perf(rust): support criterion profiler to generate flamegraph by @chaokunyang in
#2882 - feat(rust): add typename to unregistered error message by @chaokunyang in #2881
- feat(rust): add duration serializer support by @chaokunyang in #2878
- feat(python): add raw method to buffer object by @chaokunyang in #2875
- feat: refine python module check by @chaokunyang in #2952
Bug Fix
- fix(kotlin): support Kotlin field with Java reserved world by @chaokunyang in
#2948 - fix(rust): raise error for nested polymorphics for collection by @chaokunyang in
#2934 - fix(rust): fix array field support by @chaokunyang in #2933
- fix(Rust): fix Binary implementation by @urlyy in #2902
Other Improvements
- docs(java): add logging section by @mosinnik in #2905
- docs: fix cargo benchmark comand in doc by @chaokunyang in #2897
- chore: move benchmarks to separate dir to speed up ci build by @chaokunyang in
#2894 - chore(CI): Fix cache with symlinks by @PrakashRaj-GK in #2893
- chore(CI): Add caching for bazel in github workflows by @PrakashRaj-GK in #2888
- chore(Java): Update java quickstart doc, for note register order-sensitive by @monk in
#2837 - docs(rust): remove redundant doc for shared reference by @chaokunyang in #2879
- chore(rust): fix tuple test comment by @chaokunyang in #2877
- docs: fix broken table in in java_serialization_guide.md by @mosinnik in #2876
Full Changelog: v0.13.1...v0.13.2
v0.13.2-rc1
Highlights
- perf(rust): use thread local to manage fory rust WriteContext/ReadContext by @chaokunyang in
#2946 - feat(rust): add typename to unregistered error message by @chaokunyang in #2881
Features
- feat(rust): add fory config for rust by @chaokunyang in #2947
- perf(rust): use thread local to manage fory rust WriteContext/ReadContext by @chaokunyang in
#2946 - perf(rust): use segmented pool to reduce contention of fory pool by @chaokunyang in
#2945 - feat(Rust): Support u128 & u128_array by @urlyy in #2899
- perf(rust): optimize buffer write read perf by @chaokunyang in #2892
- feat(rust): direct derive primitve write/read by @chaokunyang in #2890
- refactor(rust): merge fory_debug into fory macro attr by @chaokunyang in #2883
- perf(rust): support criterion profiler to generate flamegraph by @chaokunyang in
#2882 - feat(rust): add typename to unregistered error message by @chaokunyang in #2881
- feat(rust): add duration serializer support by @chaokunyang in #2878
- feat(python): add raw method to buffer object by @chaokunyang in #2875
- feat: refine python module check by @chaokunyang in #2952
Bug Fix
- fix(kotlin): support Kotlin field with Java reserved world by @chaokunyang in
#2948 - fix(rust): raise error for nested polymorphics for collection by @chaokunyang in
#2934 - fix(rust): fix array field support by @chaokunyang in #2933
- fix(Rust): fix Binary implementation by @urlyy in #2902
Other Improvements
- docs(java): add logging section by @mosinnik in #2905
- docs: fix cargo benchmark comand in doc by @chaokunyang in #2897
- chore: move benchmarks to separate dir to speed up ci build by @chaokunyang in
#2894 - chore(CI): Fix cache with symlinks by @PrakashRaj-GK in #2893
- chore(CI): Add caching for bazel in github workflows by @PrakashRaj-GK in #2888
- chore(Java): Update java quickstart doc, for note register order-sensitive by @monk in
#2837 - docs(rust): remove redundant doc for shared reference by @chaokunyang in #2879
- chore(rust): fix tuple test comment by @chaokunyang in #2877
- docs: fix broken table in in java_serialization_guide.md by @mosinnik in #2876
Full Changelog: v0.13.1...v0.13.2-rc1
v0.13.1
Highlights
- Support rust enum variant and schema evolution for tuple/struct style enum
- Support rust tuple serialization and schema evolution
- Support rust skip macro attributes
Enum Schema Evolution
Fory v0.13.1 adds comprehensive enum schema evolution in Compatible mode, supporting all three variant types (Unit, Unnamed, Named):
- Add/remove variants: Unknown variants fall back to
#[fory(default)] - Add/remove fields: Named variants support field evolution with automatic defaults
- Modify elements: Unnamed variants handle element count changes (extras skipped, missing use defaults)
- Variant type changes: Convert between Unit/Unnamed/Named with automatic default values
// Version 1
#[derive(ForyObject)]
enum Command {
#[fory(default)]
Noop,
Execute { name: String, args: i32 },
}
// Version 2 - Added field and new variant
// both `fory(default)` and standard `default` are supported
#[derive(Default, ForyObject)]
enum Command {
#[default]
Noop,
Execute { name: String, args: i32, env: String }, // Added 'env'
Cancel { reason: String }, // New variant
}
// V1→V2: Missing 'env' gets default ""; Cancel→Noop fallback in V1
// V2→V1: Extra 'env' skipped; Cancel→Noop fallbackTuple Schema Evolution
Tuples (1-22 elements) now support length evolution in Compatible mode:
- Length changes: Grow or shrink tuple size (missing elements get defaults, extras discarded)
- Collections:
Vec,HashMap,HashSetelements fully supported - Nested tuples: Multi-level nesting with independent evolution per level
- Smart pointers:
Option,Arc,Rcwrapped elements handle evolution correctly - Struct fields: Tuple fields in structs evolve independently
let fory = Fory::default().compatible(true);
// Serialize 2-element tuple
let short = (42i32, "hello".to_string());
let bin = fory.serialize(&short).unwrap();
// Deserialize as 4-element tuple - extras get defaults
let long: (i32, String, f64, bool) = fory.deserialize(&bin).unwrap();
assert_eq!(long, (42, "hello".to_string(), 0.0, false));
// Reverse: 4→2 elements, extras discarded
let long = (100i32, "world".to_string(), 3.14, true);
let bin = fory.serialize(&long).unwrap();
let short: (i32, String) = fory.deserialize(&bin).unwrap();
assert_eq!(short, (100, "world".to_string()));Features
- feat(rust): add rust benchmark report script and result by @chaokunyang in #2835
- feat(rust): rust benchmark print serialized data size by @chaokunyang in #2845
- feat(rust): Support rust tagged union enum by @urlyy in #2855
- feat(rust): support unsigned number for rust by @chaokunyang in #2857
- feat(rust): support rust tuple serialization and schema evolution by @chaokunyang in #2858
- feat(go): implement new field ordering and type hash algorithm by @ThisingL in #2868
- feat: support fory skip macro attributes(#2864) by @kitty-eu-org in #2865
- feat(Rust): Support usize by @urlyy in #2870
- feat(rust): make whether write type/ref compile-time evaluation by @chaokunyang in #2871
- feat(rust): add array support for rust by @chaokunyang in #2874
- feat(rust): support enum variant for schema evolution mode by @chaokunyang in #2873
Bug Fix
- fix: fix 0.14.0 snapshot version by @chaokunyang in #2842
- fix(java): setting the ForyJitCompilerThreadFactory to produce daemon threads by @coderunner234 in #2869
- fix: modify the depth setting in Fory to prevent duplicate registrations. by @mengnankkkk in #2852
Other Improvements
- docs(rust): update rust benchmark report table by @chaokunyang in #2836
- chore(rust): update cargo toml for publish by @chaokunyang in #2838
- chore: bump release version to 0.13.0 by @chaokunyang in #2841
- docs: fix doc sync dest by @chaokunyang in #2839
- docs: refactor readme by @chaokunyang in #2843
- docs: add AGENTS to readme by @chaokunyang in #2844
- chore: remove agents from main readme by @chaokunyang in #2846
- docs: update readme by @chaokunyang in #2847
- docs: fix xlang type mapping link by @chaokunyang in #2848
- chore(Java): Make RustXlangTest cases independent from each other by @urlyy in #2834
- chore(java): Remove print property names by @Danden1 in #2860
- chore(python): add py3.13 release flag by @chaokunyang in #2872
- chore(rust): add tests to use #[derive(ForyObject)] in macro_rules! by @REASY in #2867
New Contributors
- @Danden1 made their first contribution in #2860
- @coderunner234 made their first contribution in #2869
- @REASY made their first contribution in #2867
Full Changelog: v0.13.0...v0.13.1
v0.13.0
Highlights
- Dynamic Trait Object Serialization for Rust
- Shared/Circular ownership serialization for Rust
- Schema Forward/Backward compatibilify for Rust
- Drop-in Replacement for Python pickle: support local function/classes/
__reduce__/__getstate__serialization - Schema Forward/Backward compatibilify for Python dataclass
- Support codegen for xlang mode in java
- Primitive array compression using SIMD
- Compact Row Codec for Row Format
- Schema Forward/Backward compatibilify for Go
- Ahead-of-time codegen for golang struct serialization
Rust: First Release Highlights
This is the first Apache Fory Rust release, delivering a complete, high‑performance serialization stack. If you build Rust services or libraries, you can now use Fory natively with strong typing, performance, and schema evolution.
- Derive-based object graph serialization via
#[derive(ForyObject)] - Polymorphism for trait objects:
Box<dyn Trait>,Rc<dyn Trait>,Arc<dyn Trait>, plusdyn Any - Shared and circular reference tracking:
Rc/ArcandRcWeak/ArcWeak - Forward/backward compatible schema evolution (Compatible mode)
- Zero-copy Row format via
#[derive(ForyRow)]with selective field access - Thread-safe and multi-thread capable serialization (context pool)
- Broad collection support (e.g.,
VecDeque,LinkedList,BTreeMap,BTreeSet,BinaryHeap)
Quick start (minimal example):
use fory::{Fory, Error};
use fory::ForyObject;
#[derive(ForyObject, Debug, PartialEq)]
struct User {
name: String,
age: i32,
email: String,
}
fn main() -> Result<(), Error> {
let mut fory = Fory::default();
fory.register::<User>(1)?;
let user = User { name: "Alice".into(), age: 30, email: "[email protected]".into() };
let bytes = fory.serialize(&user)?;
let decoded: User = fory.deserialize(&bytes)?;
assert_eq!(user, decoded);
Ok(())
}- Guide: Rust Serialization – https://fory.apache.org/docs/docs/guide/rust_serialization
- Crate: fory on crates.io – https://crates.io/crates/fory
- API docs: docs.rs – https://docs.rs/fory/latest/fory
Rust Benchmarks
Below are serialize throughput results (TPS; higher is better) comparing Fory with JSON and Protobuf across multiple datasets and sizes.
| Datatype | Size | Operation | Fory TPS | JSON TPS | Protobuf TPS | Fastest |
|---|---|---|---|---|---|---|
| company | small | serialize | 10,063,906 | 761,673 | 896,620 | fory |
| company | medium | serialize | 412,507 | 33,835 | 37,590 | fory |
| company | large | serialize | 9,183 | 793 | 880 | fory |
| ecommerce_data | small | serialize | 2,350,729 | 206,262 | 256,970 | fory |
| ecommerce_data | medium | serialize | 59,977 | 4,699 | 5,242 | fory |
| ecommerce_data | large | serialize | 3,727 | 266 | 295 | fory |
| person | small | serialize | 13,632,522 | 1,345,189 | 1,475,035 | fory |
| person | medium | serialize | 3,839,656 | 337,610 | 369,031 | fory |
| person | large | serialize | 907,853 | 79,631 | 91,408 | fory |
| simple_list | small | serialize | 27,726,945 | 4,874,957 | 4,643,172 | fory |
| simple_list | medium | serialize | 4,770,765 | 401,558 | 397,551 | fory |
| simple_list | large | serialize | 606,061 | 41,061 | 44,565 | fory |
| simple_map | small | serialize | 22,862,369 | 3,888,025 | 2,695,999 | fory |
| simple_map | medium | serialize | 2,128,973 | 204,319 | 193,132 | fory |
| simple_map | large | serialize | 177,847 | 18,419 | 18,668 | fory |
| simple_struct | small | serialize | 35,729,598 | 10,167,045 | 8,633,342 | fory |
| simple_struct | medium | serialize | 34,988,279 | 9,737,098 | 6,433,350 | fory |
| simple_struct | large | serialize | 31,801,558 | 4,545,041 | 7,420,049 | fory |
| system_data | small | serialize | 5,382,131 | 468,033 | 569,930 | fory |
| system_data | medium | serialize | 174,240 | 11,896 | 14,753 | fory |
| system_data | large | serialize | 10,671 | 876 | 1,040 | fory |
Note: Results depend on hardware, dataset, and implementation versions. See the Rust guide for how to run benchmarks yourself: https://github.com/apache/fory/blob/main/rust/benches/README.md
Python: Drop‑in Replacement for pickle
pyfory now acts as a high‑performance drop‑in replacement for pickle/cloudpickle, while keeping the same simple API and adding security and performance features.
- Serialize any Python object in Python‑native mode (
xlang=False): global/local functions, lambdas, global/local classes, instance/class/static methods - Honors Python hooks:
__getstate__,__setstate__,__reduce__,__reduce_ex__ - Reference tracking for shared/circular graphs with
ref=True - Pickle protocol 5 out‑of‑band buffers for zero‑copy via
pickle.PickleBuffer(NumPy, Pandas, etc.) - Security:
strict=Truefor registration‑based safety andDeserializationPolicyfor fine‑grained control - Threading:
ThreadSafeForyfor safe multi‑thread use - Familiar API:
dumps/loadsare aliases ofserialize/deserialize
Quick start:
import pyfory
# Drop-in replacement for pickle/cloudpickle
fory = pyfory.Fory(xlang=False, ref=True, strict=False)
def make_multiplier(k):
def mul(x):
return k * x
return mul
binary = fory.dumps(make_multiplier(10))
assert fory.loads(binary)(3) == 30Read more: Python Guide – https://fory.apache.org/docs/latest/python_serialization/
Features
- feat(java): support object stream serialization for graalvm by @chaokunyang in #2464
- refactor(java): rename abstract collection/map serializers to Map/ListLikeSerializer by @chaokunyang in #2466
- feat(memory): add customizable MemoryAllocator interface by @adriacabeza in #2467
- feat: Chain wheel test/build and release workflows by @esafak in #2483
- feat(python): set default languge to python for pyfory by @chaokunyang in #2490
- feat(python): add register api to python by @chaokunyang in #2491
- feat(python): meta compression for python by @chaokunyang in #2504
- feat(python): type meta encoding for python by @chaokunyang in #2509
- feat(CI): Cache npm, add node 24, lock file by @esafak in #2523
- feat(Rust): Implementing Type Compatible by @urlyy in #2492
- feat(Rust): support Option in MetaFieldType se/de by @urlyy in #2528
- feat(rust): support skipping fields bytes when deserializing in compatible mode by @urlyy in #2545
- feat(go): add type meta encoding for meta share by @junjiexh in #2554
- feat(Rust): Support automatic conversion between T and
Option<T>when deserialize by @urlyy in #2563 - feat(java): bean encoder implemented interfaces honor
@Ignoreby @stevenschlansker in #2576 - refactor(java): refactor fory java exception hierarchical structure by @chaokunyang in #2577
- feat(Go): Implement ahead of time codegen for fory-go serialization by @ThisingL in #2553
- feat(java): support limit deserialization depth by @chaokunyang in #2578
- feat(rust): add fory rust benchmark by @chaokunyang in #2583
- perf(rust): optimize rust deserialize perf by @chaokunyang in #2584
- feat(rust): add rust profiler for serialization by @chaokunyang in #2588
- refactor(go): rename FieldInfo to FieldDef to avoide name collision by @junjiexh in #2594
- feat(python): meta share mode for pyfory compatible serialization by @chaokunyang in #2593
- feat(java/python): align java and python compatible mode serialization by @chaokunyang in #2602
- feat(java/python): support enum xlang serialization by @chaokunyang in #2603
- feat(Rust): support basic type se/de aligned with java by @urlyy in #2585
- perf(python/java): Fix & optimize cross-language meta-share mode by @pandalee99 in #2601
- feat(go): align cross-language type serialization for primitive arrays by @pandalee99 in #2610
- feat(java): support codegen for xlang mode in java by @chaokunyang in #2613
- feat(java): primitive array compression using SIMD by @adriacabeza in #2485
- refactor(go): Replace globalTypeResolver with factory-based serializer registration by @ThisingL in #2615
- feat(go): Implement compatible mode with metashare mode by @junjiexh in #2607
- feat(java): suppo...
v0.13.0-rc2
Highlights
- Dynamic Trait Object Serialization for Rust
- Shared/Circular ownership serialization for Rust
- Schema Forward/Backward compatibilify for Rust
- Drop-in Replacement for Python pickle: support local function/classes/
__reduce__/__getstate__serialization - Schema Forward/Backward compatibilify for Python dataclass
- Support codegen for xlang mode in java
- Primitive array compression using SIMD
- Compact Row Codec for Row Format
- Schema Forward/Backward compatibilify for Go
- Ahead-of-time codegen for golang struct serialization
Features
- feat(java): support object stream serialization for graalvm by @chaokunyang in #2464
- refactor(java): rename abstract collection/map serializers to Map/ListLikeSerializer by @chaokunyang in #2466
- feat(memory): add customizable MemoryAllocator interface by @adriacabeza in #2467
- feat: Chain wheel test/build and release workflows by @esafak in #2483
- feat(python): set default languge to python for pyfory by @chaokunyang in #2490
- feat(python): add register api to python by @chaokunyang in #2491
- feat(python): meta compression for python by @chaokunyang in #2504
- feat(python): type meta encoding for python by @chaokunyang in #2509
- feat(CI): Cache npm, add node 24, lock file by @esafak in #2523
- feat(Rust): Implementing Type Compatible by @urlyy in #2492
- feat(Rust): support Option in MetaFieldType se/de by @urlyy in #2528
- feat(rust): support skipping fields bytes when deserializing in compatible mode by @urlyy in #2545
- feat(go): add type meta encoding for meta share by @junjiexh in #2554
- feat(Rust): Support automatic conversion between T and Option when deserialize by @urlyy in #2563
- feat(java): bean encoder implemented interfaces honor
@Ignoreby @stevenschlansker in #2576 - refactor(java): refactor fory java exception hierarchical structure by @chaokunyang in #2577
- feat(Go): Implement ahead of time codegen for fory-go serialization by @ThisingL in #2553
- feat(java): support limit deserialization depth by @chaokunyang in #2578
- feat(rust): add fory rust benchmark by @chaokunyang in #2583
- perf(rust): optimize rust deserialize perf by @chaokunyang in #2584
- feat(rust): add rust profiler for serialization by @chaokunyang in #2588
- refactor(go): rename FieldInfo to FieldDef to avoide name collision by @junjiexh in #2594
- feat(python): meta share mode for pyfory compatible serialization by @chaokunyang in #2593
- feat(java/python): align java and python compatible mode serialization by @chaokunyang in #2602
- feat(java/python): support enum xlang serialization by @chaokunyang in #2603
- feat(Rust): support basic type se/de aligned with java by @urlyy in #2585
- perf(python/java): Fix & optimize cross-language meta-share mode by @pandalee99 in #2601
- feat(go): align cross-language type serialization for primitive arrays by @pandalee99 in #2610
- feat(java): support codegen for xlang mode in java by @chaokunyang in #2613
- feat(java): primitive array compression using SIMD by @adriacabeza in #2485
- refactor(go): Replace globalTypeResolver with factory-based serializer registration by @ThisingL in #2615
- feat(go): Implement compatible mode with metashare mode by @junjiexh in #2607
- feat(java): support concurent map serialization when being updated by @chaokunyang in #2617
- feat(java): support concurrent updates when serializing collections by @chaokunyang in #2623
- feat(python): support limit pyfory depth by @chaokunyang in #2625
- feat(Rust): sort fields && feat Enum && fix read/write type_info && fix type_meta en/decode by @urlyy in #2630
- feat(python): drop-in replacement for pickle serialization by @chaokunyang in #2629
- refactor(java): refactor type resolver by @chaokunyang in #2640
- feat(java): support type converters for comaptible mode by @chaokunyang in #2641
- refactor(java/python): refine collection header bitmap by @chaokunyang in #2642
- feat(go): metashare mode support collection and map and nested object by @junjiexh in #2643
- feat(go): Add slice and map support to fory-go codegen serialization by @ThisingL in #2638
- refactor(go): Change codegen annotation from //fory:gen to //fory:generate by @ThisingL in #2648
- feat(rust): support Map and register_by_name by @urlyy in #2649
- feat(java): support graalvm 25 by @chaokunyang in #2652
- feat(java): support deserialize not registered/exsited class/fields for xlang compatible mode by @chaokunyang in #2655
- refactor(Rust): Refactor compile-time code & fix named_enum & fix skip enum by @urlyy in #2657
- feat(python): support local py class serialization by @chaokunyang in #2665
- refactor(go): refine collection header bitmap by @junjiexh in #2656
- feat(python): support class methods serialization by @chaokunyang in #2670
- refactor(go): refine collection header bitmap in codegen by @ThisingL in #2676
- feat(rust): support box serde for rust by @chaokunyang in #2677
- feat(rust): support reference tracking for rust Rc/Arc by @chaokunyang in #2678
- feat(python): refine python serialization api by @chaokunyang in #2673
- refactor(Rust): Refine api name by @urlyy in #2671
- feat(rust): support rust dyn trait object serialization by @chaokunyang in #2691
- feat(rust): support dyn any trait object serialization for box/arc/rc by @chaokunyang in #2704
- feat(rust): support shared reference tracking for arc/rc by @chaokunyang in #2707
- feat(rust): avoid downcast method of multiple trait objects in same module conflict by @chaokunyang in #2708
- feat(rust): add deref to arc/rc wrapper by @chaokunyang in #2709
- refactor(rust): unify rc/arc wrapper macro arms into one function by @chaokunyang in #2711
- perf(Rust): Use SIMD to se/de string by @urlyy in #2716
- feat(Rust): named_xx se/de && ext se/de && add unittest by @urlyy in #2712
- feat(rust): support RcWeak/ArcWeak for circular reference tracking by @chaokunyang in #2714
- feat(rust): support limit max dyn depth by @chaokunyang in #2730
- feat(Rust): Unroll fields loop & Add a feature for this by @urlyy in #2724
- feat(python): make fory out-of-band serialization compatible with pickle5 by @chaokunyang in #2732
- refactor(go): Replace legacy RegisterTagType api call by @junjiexh in #2696
- feat(python): add thread safe fory by @chaokunyang in #2735
- feat(rust): support VecDeque/LinkedList serialization by @chaokunyang in #2741
- feat(rust): support btreemap serialization by @chaokunyang in #2743
- feat(rust): support btree set and binary heap serialization by @chaokunyang in #2744
- feat(Rust): support context_pool to reduce context allocation && support se/de in multi-thread by @urlyy in #2737
- feat(ci): cache Bazel binary in Python CI workflow by @SanyamSuyal in #2745
- feat(rust): rewrite fory derive macro for smaller and faster generated code using compile-time fields sort algorithm by @chaokunyang in #2749
- feat(ci): add maven cache to ci for faster build by @chaokunyang in #2751
- feat(rust): fast fory_read_compatible macro to use match by assigned field id by @chaokunyang in #2758
- refactor(rust): use compatible bool instead of enum to simplify API by @chaokunyang in #2763
- feat(rust): query type meta from parsed cach...
v0.13.0-rc1
Highlights
- Dynamic Trait Object Serialization for Rust
- Shared/Circular ownership serialization for Rust
- Schema Forward/Backward compatibilify for Rust
- Drop-in Replacement for Python pickle: support local function/classes/
__reduce__/__getstate__serialization - Schema Forward/Backward compatibilify for Python dataclass
- Support codegen for xlang mode in java
- Primitive array compression using SIMD
- Compact Row Codec for Row Format
- Schema Forward/Backward compatibilify for Go
- Ahead-of-time codegen for golang struct serialization
Features
- feat(java): support object stream serialization for graalvm by @chaokunyang in #2464
- refactor(java): rename abstract collection/map serializers to Map/ListLikeSerializer by @chaokunyang in #2466
- feat(memory): add customizable MemoryAllocator interface by @adriacabeza in #2467
- feat: Chain wheel test/build and release workflows by @esafak in #2483
- feat(python): set default languge to python for pyfory by @chaokunyang in #2490
- feat(python): add register api to python by @chaokunyang in #2491
- feat(python): meta compression for python by @chaokunyang in #2504
- feat(python): type meta encoding for python by @chaokunyang in #2509
- feat(CI): Cache npm, add node 24, lock file by @esafak in #2523
- feat(Rust): Implementing Type Compatible by @urlyy in #2492
- feat(Rust): support Option in MetaFieldType se/de by @urlyy in #2528
- feat(rust): support skipping fields bytes when deserializing in compatible mode by @urlyy in #2545
- feat(go): add type meta encoding for meta share by @junjiexh in #2554
- feat(Rust): Support automatic conversion between T and Option when deserialize by @urlyy in #2563
- feat(java): bean encoder implemented interfaces honor
@Ignoreby @stevenschlansker in #2576 - refactor(java): refactor fory java exception hierarchical structure by @chaokunyang in #2577
- feat(Go): Implement ahead of time codegen for fory-go serialization by @ThisingL in #2553
- feat(java): support limit deserialization depth by @chaokunyang in #2578
- feat(rust): add fory rust benchmark by @chaokunyang in #2583
- perf(rust): optimize rust deserialize perf by @chaokunyang in #2584
- feat(rust): add rust profiler for serialization by @chaokunyang in #2588
- refactor(go): rename FieldInfo to FieldDef to avoide name collision by @junjiexh in #2594
- feat(python): meta share mode for pyfory compatible serialization by @chaokunyang in #2593
- feat(java/python): align java and python compatible mode serialization by @chaokunyang in #2602
- feat(java/python): support enum xlang serialization by @chaokunyang in #2603
- feat(Rust): support basic type se/de aligned with java by @urlyy in #2585
- perf(python/java): Fix & optimize cross-language meta-share mode by @pandalee99 in #2601
- feat(go): align cross-language type serialization for primitive arrays by @pandalee99 in #2610
- feat(java): support codegen for xlang mode in java by @chaokunyang in #2613
- feat(java): primitive array compression using SIMD by @adriacabeza in #2485
- refactor(go): Replace globalTypeResolver with factory-based serializer registration by @ThisingL in #2615
- feat(go): Implement compatible mode with metashare mode by @junjiexh in #2607
- feat(java): support concurent map serialization when being updated by @chaokunyang in #2617
- feat(java): support concurrent updates when serializing collections by @chaokunyang in #2623
- feat(python): support limit pyfory depth by @chaokunyang in #2625
- feat(Rust): sort fields && feat Enum && fix read/write type_info && fix type_meta en/decode by @urlyy in #2630
- feat(python): drop-in replacement for pickle serialization by @chaokunyang in #2629
- refactor(java): refactor type resolver by @chaokunyang in #2640
- feat(java): support type converters for comaptible mode by @chaokunyang in #2641
- refactor(java/python): refine collection header bitmap by @chaokunyang in #2642
- feat(go): metashare mode support collection and map and nested object by @junjiexh in #2643
- feat(go): Add slice and map support to fory-go codegen serialization by @ThisingL in #2638
- refactor(go): Change codegen annotation from //fory:gen to //fory:generate by @ThisingL in #2648
- feat(rust): support Map and register_by_name by @urlyy in #2649
- feat(java): support graalvm 25 by @chaokunyang in #2652
- feat(java): support deserialize not registered/exsited class/fields for xlang compatible mode by @chaokunyang in #2655
- refactor(Rust): Refactor compile-time code & fix named_enum & fix skip enum by @urlyy in #2657
- feat(python): support local py class serialization by @chaokunyang in #2665
- refactor(go): refine collection header bitmap by @junjiexh in #2656
- feat(python): support class methods serialization by @chaokunyang in #2670
- refactor(go): refine collection header bitmap in codegen by @ThisingL in #2676
- feat(rust): support box serde for rust by @chaokunyang in #2677
- feat(rust): support reference tracking for rust Rc/Arc by @chaokunyang in #2678
- feat(python): refine python serialization api by @chaokunyang in #2673
- refactor(Rust): Refine api name by @urlyy in #2671
- feat(rust): support rust dyn trait object serialization by @chaokunyang in #2691
- feat(rust): support dyn any trait object serialization for box/arc/rc by @chaokunyang in #2704
- feat(rust): support shared reference tracking for arc/rc by @chaokunyang in #2707
- feat(rust): avoid downcast method of multiple trait objects in same module conflict by @chaokunyang in #2708
- feat(rust): add deref to arc/rc wrapper by @chaokunyang in #2709
- refactor(rust): unify rc/arc wrapper macro arms into one function by @chaokunyang in #2711
- perf(Rust): Use SIMD to se/de string by @urlyy in #2716
- feat(Rust): named_xx se/de && ext se/de && add unittest by @urlyy in #2712
- feat(rust): support RcWeak/ArcWeak for circular reference tracking by @chaokunyang in #2714
- feat(rust): support limit max dyn depth by @chaokunyang in #2730
- feat(Rust): Unroll fields loop & Add a feature for this by @urlyy in #2724
- feat(python): make fory out-of-band serialization compatible with pickle5 by @chaokunyang in #2732
- refactor(go): Replace legacy RegisterTagType api call by @junjiexh in #2696
- feat(python): add thread safe fory by @chaokunyang in #2735
- feat(rust): support VecDeque/LinkedList serialization by @chaokunyang in #2741
- feat(rust): support btreemap serialization by @chaokunyang in #2743
- feat(rust): support btree set and binary heap serialization by @chaokunyang in #2744
- feat(Rust): support context_pool to reduce context allocation && support se/de in multi-thread by @urlyy in #2737
- feat(ci): cache Bazel binary in Python CI workflow by @SanyamSuyal in #2745
- feat(rust): rewrite fory derive macro for smaller and faster generated code using compile-time fields sort algorithm by @chaokunyang in #2749
- feat(ci): add maven cache to ci for faster build by @chaokunyang in #2751
- feat(rust): fast fory_read_compatible macro to use match by assigned field id by @chaokunyang in #2758
- refactor(rust): use compatible bool instead of enum to simplify API by @chaokunyang in #2763
- feat(rust): query type meta from parsed cach...