TL;DR: Apache Fory Rust is a blazingly-fast, cross-language serialization framework that delivers ultra-fast serialization performance while automatically handling circular references, trait objects, and schema evolution. Built with Rust's safety guarantees and zero-copy techniques, it's designed for developers who refuse to compromise between performance and developer experience. Every backend engineer has faced this moment: your application needs to serialize complex data structures such as nested objects, circular references, polymorphic types, and you're forced to choose between three bad options: Fast but fragile: Hand-rolled binary formats that break with schema changes Flexible but slow: JSON/Protocol with 10x performance overhead Complex and limiting: Existing solutions that don't support your language's advanced features Apache Fory Rust eliminates this false choice. It's a serialization framework that delivers exceptional performance while automatically handling the complexities of modern applications—no IDL files, no manual schema management, no compromises. Apache Fory Rust speaks the same binary protocol as Java, Python, C++, Go, and other language implementations. Serialize data in Rust, deserialize in Python — it just works. No schema files. No code generation. No version mismatches. let user = User { name : "Alice" . to_string ( ) , age : 30 , metadata : HashMap :: from ( [ ( "role" , "admin" ) ] ) , } ; let bytes = fory . serialize ( & user ) ; user = fory . deserialize ( bytes ) # Just works! This isn't just convenient — it changes how we develop microservices architectures where different teams use different languages. Most serialization frameworks panic when encountering circular references. Apache Fory tracks and preserves reference identity automatically: Shared Reference: use fory :: Fory ; use std :: rc :: Rc ; let fory = Fory :: default ( ) ; let shared = Rc :: new ( String :: from ( "shared_value" ) ) ; let data = vec! [ shared . clone ( ) , shared . clone ( ) , shared . clone ( ) ] ; let bytes = fory . serialize ( & data ) ; let decoded : Vec < Rc < String >> = fory . deserialize ( & bytes ) ? ; assert_eq! ( decoded . len ( ) , 3 ) ; assert_eq! ( * decoded [ 0 ] , "shared_value" ) ; assert! ( Rc :: ptr_eq ( & decoded [ 0 ] , & decoded [ 1 ] ) ) ; assert! ( Rc :: ptr_eq ( & decoded [ 1 ] , & decoded [ 2 ] ) ) ; Circular Reference: use fory :: { ForyObject , RcWeak } ; #[derive(ForyObject)] struct Node { value : i32 , parent : RcWeak < RefCell < Node >> , children : Vec < Rc < RefCell < Node >> > , } let parent = Rc :: new ( RefCell :: new ( Node { ... } ) ) ; let child = Rc :: new ( RefCell :: new ( Node { parent : RcWeak :: from ( & parent ) , ... } ) ) ; parent . borrow_mut ( ) . children . push ( child . clone ( ) ) ; let bytes = fory . serialize ( & parent ) ; let decoded : Rc < RefCell < Node >> = fory . deserialize ( & bytes ) ? ; assert! ( Rc :: ptr_eq ( & decoded , & decoded . borrow ( ) . children [ 0 ] . borrow ( ) . parent . upgrade ( ) . unwrap ( ) ) ) ; This isn't just a feature—it's essential for graph databases, object-relational mappers, and domain models. Rust's trait system enables powerful abstractions, but serializing Box is notoriously difficult. Apache Fory makes it trivial: use fory :: { ForyObject , Serializer , register_trait_type } ; trait Animal : Serializer { fn speak ( & self ) -> String ; } #[derive(ForyObject)] struct Dog { name : String , breed : String } #[derive(ForyObject)] struct Cat { name : String , color : String } register_trait_type! ( Animal , Dog , Cat ) ; let animals : Vec < Box < dyn Animal >> = vec! [ Box :: new ( Dog { ... } ) , Box :: new ( Cat { ... } ) , ] ; let bytes = fory . serialize ( & animals ) ; let decoded : Vec < Box < dyn Animal >> = fory . deserialize ( & bytes ) ? ; decoded [ 0 ] . speak ( ) ; decoded [ 1 ] . speak ( ) ; Alternative: Using dyn Any without trait registration: use std :: rc :: Rc ; use std :: any :: Any ; let dog : Rc < dyn Any > = Rc :: new ( Dog { name : "Rex" . to_string ( ) , breed : "Labrador" . to_string ( ) } ) ; let cat : Rc < dyn Any > = Rc :: new ( Cat { name : "Whiskers" . to_string ( ) , color : "Orange" . to_string ( ) } ) ; let bytes = fory . serialize ( & dog ) ; let decoded : Rc < dyn Any > = fory . deserialize ( & bytes ) ? ; let unwrapped = decoded . downcast_ref :: < Dog > ( ) . unwrap ( ) ; assert_eq! ( unwrapped . name , "Rex" ) ; Supports: Box - Owned trait objects - Owned trait objects Rc / Arc - Reference-counted trait objects / - Reference-counted trait objects Rc / Arc - Runtime type dispatch without traits / - Runtime type dispatch without traits Auto-generated wrapper types for standalone serialization This unlocks plugin systems, heterogeneous collections, and extensible architectures that were previously impossible to serialize. Microservices evolve independently. Apache Fory's Compatible mode allows schema changes without coordination: use fory :: { Fory , ForyObject } ; #[derive(ForyObject)] struct User { name : String , age : i32 , address : String , } let mut fory_v1 = Fory :: default ( ) . compatible ( true ) ; fory_v1 . register :: < User > ( 1 ) ; #[derive(ForyObject)] struct User { name : String , age : i32 , phone : Option < String > , metadata : HashMap < String , String > , } let mut fory_v2 = Fory :: default ( ) . compatible ( true ) ; fory_v2 . register :: < User > ( 1 ) ; let v1_bytes = fory_v1 . serialize ( & user_v1 ) ; let user_v2 : User = fory_v2 . deserialize ( & v1_bytes ) ? ; Compatibility rules: ✅ Add new fields (default values applied) ✅ Remove fields (skipped during deserialization) ✅ Reorder fields (matched by name) ✅ Change nullability ( T ↔ Option ) ↔ ) ❌ Type changes (except nullable variants) This is critical for zero-downtime deployments and polyglot microservices. Apache Fory uses a sophisticated binary protocol designed for both performance and flexibility: | fory header | reference meta | type meta | value data | Key innovations: Efficient encoding: Variable-length integers, compact type IDs, bit-packed flags Reference tracking: Deduplicates shared objects automatically (serialize once, reference thereafter) Meta compression: Gzip compression for type metadata in meta-sharing mode Little-endian layout: Optimized for modern CPU architectures Unlike reflection-based frameworks, Apache Fory generates serialization code at compile time via procedural macros: use fory :: ForyObject ; #[derive(ForyObject)] struct Person { name : String , age : i32 , address : Address , } Benefits: ⚡ Zero runtime overhead : No reflection, no vtable lookups : No reflection, no vtable lookups 🛡️ Type safety : Compile-time errors instead of runtime panics : Compile-time errors instead of runtime panics 📦 Small binary size : Only code for types you actually use : Only code for types you actually use 🔍 IDE support: Full autocomplete and error checking Apache Fory Rust consists of three focused crates: fory/ # High-level API └─ Convenience wrappers, derive re-exports fory-core/ # Core serialization engine ├─ fory.rs # Main entry point ├─ buffer.rs # Zero-copy binary I/O ├─ serializer/ # Type-specific serializers ├─ resolver/ # Type registration & dispatch ├─ meta/ # Meta string compression └─ row/ # Row format implementation fory-derive/ # Procedural macros ├─ object/ # ForyObject derive macro └─ fory_row.rs # ForyRow derive macro This modular design ensures clean separation of concerns and makes the codebase maintainable. 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 Microservices with polyglot teams Different services in different languages Need seamless data exchange without schema files Schema evolution across independent deployments High-performance data pipelines Processing millions of records per second Memory-constrained environments (use row format) Analytics workloads with selective field access Complex domain models Circular references (parent-child relationships, graphs) Polymorphic types (trait objects, inheritance hierarchies) Rich object graphs with shared references Real-time systems Low-latency requirements ( <1ms serialization) serialization) Memory-mapped file access Zero-copy deserialization critical You need human-readable data: Use JSON/YAML for debugging You need long-term storage format: Use Parquet for data lakes Your data is trivial: serde + bincode is simpler for basic types Add to Cargo.toml : [dependencies] fory = "0.13" use fory :: { Fory , Error , 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" . to_string ( ) , age : 30 , email : "[email protected]" . to_string ( ) , } ; let bytes = fory . serialize ( & user ) ; let decoded : User = fory . deserialize ( & bytes ) ? ; assert_eq! ( user , decoded ) ; Ok ( ( ) ) } use fory :: Fory ; let mut fory = Fory :: default ( ) . compatible ( true ) . xlang ( true ) ; fory . register_by_namespace :: < User > ( 1 ) ; let bytes = fory . serialize ( & user ) ; Register types with consistent IDs or names across all languages: By ID ( fory.register::(1) ): Faster serialization, more compact encoding, but requires coordination to avoid ID conflicts ( ): Faster serialization, more compact encoding, but requires coordination to avoid ID conflicts By name ( fory.register_by_name::("example.User") ): More flexible, less prone to conflicts, easier to manage across teams, but slightly larger encoding Apache Fory Rust supports a comprehensive type system: Primitives: bool , i8 , i16 , i32 , i64 , f32 , f64 , String Collections: Vec , HashMap , BTreeMap , HashSet , Option Smart Pointers: Box , Rc , Arc , RcWeak , ArcWeak , RefCell , Mutex Date/Time: chrono::NaiveDate , chrono::NaiveDateTime Custom Types: Derive ForyObject for object graphs, ForyRow for row format Trait Objects: Box , Rc , Arc , Rc , Arc Apache Fory Rust is production-ready today, but we're just getting started and continuing active development: ✅ Static codegen via procedural macros ✅ Row format serialization with zero-copy ✅ Cross-language object graph serialization ✅ Shared and circular reference tracking ✅ Weak pointer support (RcWeak, ArcWeak) ✅ Trait object serialization (Box/Rc/Arc) ✅ Schema evolution in compatible mode Cross-language reference serialization : serialize Rc/Arc to/from other languages. : serialize to/from other languages. Partial row updates: Mutate row format in-place We're actively seeking contributors for: Performance tuning : Profile and optimize hot paths : Profile and optimize hot paths Documentation : More examples, tutorials, and guides : More examples, tutorials, and guides Testing: Fuzzing, property tests, edge case coverage Fory becomes fully thread-safe after registration is complete. Once every type is registered (which requires &mut Fory ), wrap the instance in an Arc and freely share it across worker threads for concurrent serialization and deserialization. use fory :: Fory ; use std :: { sync :: Arc , thread } ; let mut fory = Fory :: default ( ) ; fory . register :: < Item > ( 1 ) ? ; let fory = Arc :: new ( fory ) ; let item = Item :: default ( ) ; let handles : Vec < _ > = ( 0 .. 4 ) . map ( | _ | { let fory = Arc :: clone ( & fory ) ; let input = item . clone ( ) ; thread :: spawn ( move | | { let bytes = fory . serialize ( & input ) ; let decoded : Item = fory . deserialize ( & bytes ) . expect ( "valid data" ) ; ( bytes , decoded ) } ) } ) . collect ( ) ; for handle in handles { let ( bytes , decoded ) = handle . join ( ) . expect ( "thread finished" ) ; } Apache Fory uses Result for all fallible operations: use fory :: Error ; match fory . deserialize :: < User > ( & bytes ) { Ok ( user ) => process_user ( user ) , Err ( Error :: TypeMismatch ) => log :: error! ( "Schema mismatch" ) , Err ( Error :: BufferTooShort ) => log :: error! ( "Incomplete data" ) , Err ( e ) => log :: error! ( "Deserialization failed: {}" , e ) , } Apache Fory is an Apache Software Foundation project with a vibrant, growing community: We welcome contributions of all kinds: Code: Implement features from the roadmap Docs: Write tutorials, examples, and guides Testing: Add benchmarks, fuzz tests, integration tests Feedback: Report bugs, request features, share use cases See CONTRIBUTING.md for guidelines. Apache Fory is licensed under the Apache License 2.0, a permissive open-source license that allows commercial use, modification, and distribution. Apache Fory Rust represents a paradigm shift in serialization: No more trade-offs : Get performance and flexibility : Get performance and flexibility No more boilerplate : Derive macros handle the complexity : Derive macros handle the complexity No more lock-in: Trait-object and shared reference support by nature Whether you're building microservices, data pipelines, or real-time systems, Apache Fory Rust delivers the performance you need with the ergonomics you deserve. Try it today: cargo add fory Join the community: git clone https://github.com/apache/fory.git cd fory/rust cargo test --features tests Share your experience: