Apache Fory Rust – JSON/Protobuf보다 10~20배 빠른 직렬화 프레임워크
(fory.apache.org)- Apache Fory Rust는 초고속 직렬화 성능과 자동 참조 관리를 제공하는 크로스랭귀지 직렬화 프레임워크
 - Rust의 제로카피 기술과 타입 안전성을 기반으로, 순환 참조·트레이트 객체·스키마 진화를 자동 처리
 - IDL 파일이나 코드 생성 없이 Rust, Python, Java, Go 등 다양한 언어 간 데이터 교환 지원
 - 벤치마크 결과, JSON·Protobuf 대비 10~20배 이상 빠른 처리 속도를 기록
 - 마이크로서비스·데이터 파이프라인·실시간 시스템 등 고성능 환경에서 활용 가치 높음
 
직렬화의 딜레마와 Apache Fory Rust의 등장
- 기존 직렬화 방식은 속도·유연성·언어 호환성 중 하나를 포기해야 하는 한계 존재
- 수작업 바이너리 포맷은 빠르지만 스키마 변경에 취약
 - JSON/Protobuf는 유연하지만 10배 이상의 성능 오버헤드
 - 기존 솔루션은 언어 고유 기능 지원 부족
 
 - Apache Fory Rust는 성능과 유연성을 동시에 확보, IDL·수동 스키마 관리 불필요
 
주요 특징
- 
1. 진정한 크로스랭귀지 지원
- 동일한 바이너리 프로토콜을 Java, Python, C++, Go 등에서 공유
 - Rust에서 직렬화한 데이터를 Python에서 그대로 역직렬화 가능
 - 스키마 파일·코드 생성·버전 불일치 문제 없음, 다언어 마이크로서비스 간 데이터 교환 단순화
 
 - 
2. 자동 순환·공유 참조 처리
- 대부분의 프레임워크가 실패하는 순환 참조 구조를 자동 추적 및 보존
 - 동일 객체를 여러 번 참조해도 한 번만 직렬화, 참조 동일성 유지
 - 그래프 데이터베이스·ORM·복잡한 도메인 모델에 적합
 
 - 
3. 트레이트 객체 직렬화
- Rust의 
Box등 트레이트 객체 직렬화를 지원 - 
register_trait_type!매크로로 다형적 타입 등록 가능 - 
Box,Rc,Arc,dyn Any등 다양한 형태 지원 - 플러그인 시스템·이질적 컬렉션·확장 가능한 아키텍처 구현 가능
 
 - Rust의 
 - 
4. 스키마 진화(호환 모드)
- 
Compatible 모드로 서비스 버전 간 스키마 변경 허용
- 필드 추가·삭제·순서 변경·옵션 타입 변환 가능
 - 타입 변경은 불가
 
 - 무중단 배포와 독립적 마이크로서비스 진화에 유용
 
 - 
Compatible 모드로 서비스 버전 간 스키마 변경 허용
 
기술적 기반
- 
프로토콜 설계
- 구조: 
| fory header | reference meta | type meta | value data | - 가변 길이 정수·압축 메타데이터·참조 추적·리틀엔디언 레이아웃 적용
 - 공유 객체 중복 제거 및 타입 메타데이터 압축으로 성능 향상
 
 - 구조: 
 - 
컴파일 타임 코드 생성
- 리플렉션 대신 매크로 기반 코드 생성으로 런타임 오버헤드 제거
 - 
#[derive(ForyObject)]매크로가 직렬화·역직렬화 함수 자동 생성 - 타입 안전성 확보, 바이너리 크기 최소화, IDE 자동완성 지원
 
 - 
아키텍처 구성
- 
fory/: 고수준 API - 
fory-core/: 직렬화 엔진 (버퍼 I/O, 타입 등록, 메타 압축 등) - 
fory-derive/: 프로시저 매크로 정의 - 모듈화된 구조로 유지보수성과 확장성 확보
 
 - 
 
벤치마크 결과
- JSON 및 Protobuf 대비 10~20배 이상 빠른 처리 속도
 - 예시:
- 
simple_struct(small) → Fory 35,729,598 TPS / JSON 10,167,045 / Protobuf 8,633,342 - 
person(medium) → Fory 3,839,656 TPS / JSON 337,610 / Protobuf 369,031 
 - 
 - 모든 테스트 케이스에서 Fory가 최고 성능 기록
 
활용 시나리오
- 
적합한 사용 사례
- 다언어 마이크로서비스: 스키마 파일 없이 데이터 교환
 - 고성능 데이터 파이프라인: 초당 수백만 레코드 처리
 - 복잡한 도메인 모델: 순환 참조·다형성 구조 지원
 - 실시간 시스템: 1ms 이하 지연, 제로카피 역직렬화
 
 - 
대안 고려
- 사람이 읽기 쉬운 포맷 필요 시 → JSON/YAML
 - 장기 저장 포맷 필요 시 → Parquet
 - 단순 데이터 구조 → serde + bincode
 
 
시작하기
- 
설치
- 
Cargo.toml에 추가:[dependencies] fory = "0.13" 
 - 
 - 
기본 직렬화 예시
- 
#[derive(ForyObject)]로 구조체 등록 후serialize()/deserialize()사용 - 타입 ID 등록으로 데이터 일관성 유지
 
 - 
 - 
크로스랭귀지 직렬화
- 
compatible(true).xlang(true)설정으로 다언어 호환 모드 활성화 - ID 또는 이름 기반 등록(
register_by_namespace,register_by_name) 지원 
 - 
 
지원 타입
- 기본형: bool, 정수, 부동소수, String
 - 컬렉션: Vec, HashMap, BTreeMap, HashSet, Option
 - 스마트 포인터: Box, Rc, Arc, RcWeak, ArcWeak, RefCell, Mutex
 - 날짜/시간: chrono 타입
 - 사용자 정의 객체: ForyObject, ForyRow
 - 트레이트 객체: Box/Rc/Arc, Rc/Arc
 
로드맵
- 
v0.13에서 제공
- 정적 코드 생성, 제로카피 Row 포맷, 순환 참조 추적, 트레이트 객체 직렬화, 스키마 호환 모드
 
 - 
예정 기능
- 크로스랭귀지 참조 직렬화, 부분 Row 업데이트
 
 
프로덕션 고려사항
- 
스레드 안전성: 등록 완료 후 
Arc로 공유 가능 (Send + Sync) - 
에러 처리: 
Result기반, 타입 불일치·버퍼 부족 등 명시적 오류 구분 
문서 및 커뮤니티
- 공식 문서: fory.apache.org/docs
 - API 문서: docs.rs/fory
 - 커뮤니티: GitHub, Slack, Issue Tracker 운영
 - Apache License 2.0 기반 오픈소스
 
결론
- Apache Fory Rust는 성능·유연성·언어 호환성의 절충을 제거한 차세대 직렬화 프레임워크
 - 매크로 기반 자동화, 트레이트 객체 지원, 순환 참조 처리로 개발 효율 극대화
 - 마이크로서비스·데이터 파이프라인·실시간 시스템 등에서 즉시 활용 가능
 
Hacker News 의견
- 
새로운 포맷을 만들기보다 W3C EXI(Binary XML) 같은 기존 기술의 툴링을 개선하는 데 집중했으면 좋겠음
단순히 빠르기만 해서는 부족하고, Aeron/SBT처럼 생태계가 없는 포맷은 확산이 어려움. XML은 이미 그 생태계를 갖추고 있음- Binary XML 인코딩은 특정 상황에서는 유용하지만, 최신 바이너리 직렬화 포맷들보다 효율적이지 않음
또한 공유 참조나 순환 참조 같은 복잡한 객체 그래프를 자연스럽게 표현하지 못함
Fory 포맷은 이런 문제를 해결하면서도 언어 간 호환성과 스키마 진화를 지원하도록 처음부터 설계되었음 - W3C EXI나 ASN.1 BER 중 어느 것이 더 나은지는 모르겠지만, DOP(데이터 중심 설계) 접근이 맞다고 생각함
즉, 인코딩을 먼저 설계하고 언어나 클라이언트로 거꾸로 확장하는 방식이 바람직함 
 - Binary XML 인코딩은 특정 상황에서는 유용하지만, 최신 바이너리 직렬화 포맷들보다 효율적이지 않음
 - 
벤치마크가 공정한지 의문이 듦
코드 링크를 보면, Fory 구조체가 아닌 경우 직렬화 과정에서 to/from 변환이 포함되어 있음
이 변환 과정에서 문자열 복제나 배열 재할당이 발생함
실제 시스템에서는 tonic이 8KB 버퍼를 제공하므로, 단순 Vec::default()보다 효율적일 것임- 이 벤치마크는 공정하지 않음
Xeon Gold 6136 CPU 기준으로 10배 향상처럼 보이지만, to/from 변환과 Vec 복제를 제거하고 8KB 버퍼를 미리 할당하면 실제로는 3배 수준임
벤치마크는 Fory 관련 코드가 전혀 없는 tower service/codec 스타일로 다시 작성되어야 함
Fory는 테스트 중 writer pool을 사용하고 있음
관련 코드 참고 
 - 이 벤치마크는 공정하지 않음
 - 
장기적으로 언어 간 호환성을 유지하려면 IDL 기반의 명세화된 계약이 필요하다고 생각함
언어에서 직렬화로 출발하는 접근은 초기엔 편하지만, 시간이 지나면 언어 런타임 변화에 취약해짐- 언어가 많아질수록 공식 스키마가 중요해짐
단일 언어 프로젝트는 IDL 없이도 단순하게 유지 가능하지만, 세 언어 이상부터는 IDL이 단일 진실의 원천 역할을 함
Apache Fory는 선택적으로 IDL 지원을 추가할 예정이며, 팀 상황에 맞게 언어 우선 혹은 스키마 우선 방식을 선택할 수 있게 할 계획임 
 - 언어가 많아질수록 공식 스키마가 중요해짐
 - 
스키마 없이 언어 간 공유 타입을 어떻게 유지하는지 궁금함
 - 
CapnProto나 Flatbuffers 같은 직렬화 없는 포맷 대신 Fory를 써야 하는 이유가 궁금함
압축이 필요하면 zstd를 쓰면 됨
그래도 Fory의 광범위한 언어 지원과 사용 편의성은 인상적임
Python에서는 여전히 dill을 선호함 — 코드 객체까지 직렬화 가능하기 때문임
dill 링크 - 
벤치마크 링크가 404였지만, 정상 링크를 찾았음
 - 
이름을 “Fury”에서 “Fory”로 바꾼 게 아쉬움
Fury는 빠른 직렬화 프레임워크에 딱 맞는 이름이었음- “Fury”는 원래 내가 지은 이름이라 애착이 있었지만, 어쩔 수 없이 변경해야 했음
 
 - 
대부분의 바이너리 프로토콜은 데이터 크기를 줄이려 함
Protobuf는 정수 압축(varint, zigzag)을 사용함
단순 TPS만 비교하면 C 구조체를 그대로 전송하는 “do nothing” 방식이 항상 이길 수밖에 없음- Fory도 정수 압축을 지원하며, Protobuf와 데이터 크기가 거의 동일함
다양한 데이터셋에서의 비교표를 제시함 - 두 가지 스키마 호환 모드가 존재하지만, 마이너 버전 간 바이너리 호환성 보장은 없음
 
 - Fory도 정수 압축을 지원하며, Protobuf와 데이터 크기가 거의 동일함
 - 
Fory의 4096 타입 제한이 충분한지 궁금함
관련 코드 참고- 모든 경우에 충분하지는 않겠지만, 필요하다면 확장 가능함
실제로 4096개 이상의 프로토콜 메시지를 정의한 사례는 거의 보지 못했음 
 - 모든 경우에 충분하지는 않겠지만, 필요하다면 확장 가능함
 - 
Rust 벤치마크 링크가 404 오류를 냄
문서 루트에서는 벤치마크 디렉터리를 찾을 수 없었음- 아마 이 링크들, Rust 직렬화 가이드가 해당 내용일 것으로 추정함