News: Grab ได้ทำการ migrate service บางส่วนจาก Go เป็น Rust

"Performance isn’t just about speed — it’s about confidence that your system won’t break under pressure."
grab-migration-from-go-to-rust-cover-image

เข้าใจที่มา

Grab มีระบบหนึ่งชื่อว่า Counter Service หน้าที่ของมันคือจัดการ transaction counter สำหรับบริการต่างๆ (เช่น การเรียกรถ การจ่ายเงิน ฯลฯ)
ระบบนี้มีภารกิจสำคัญคือ ต้องนับให้แม่นและเร็วมาก เพราะถ้านับผิด = เงินหรือข้อมูลเพี้ยนทันที

เดิมทีทีม Grab เขียนระบบนี้ด้วย Go (Golang) ซึ่งก็ถือว่าดีอยู่แล้ว แต่เมื่อระบบเติบโตจนต้องรองรับปริมาณข้อมูลและการเรียกใช้งานระดับมหาศาล
ทีมเริ่มเจอปัญหา latency สูง, CPU ใช้เยอะ, และ garbage collection (GC) กลายเป็นคอขวด

เข้าใจปัญหา

ทีม Grab พบว่า Go มีข้อจำกัดบางอย่างในเคสที่ต้องการ “low latency + high concurrency” แบบสุดขีด

ปัญหาหลักที่เจอคือ:

  1. GC pauses: การเก็บกวาดหน่วยความจำทำให้ latency แกว่ง
  2. CPU overhead: ใน workload ที่เน้น memory-intensive, Go ใช้ CPU มากเกินไป
  3. ไม่สามารถควบคุม memory layout ได้ดีเท่าที่ต้องการ — ทำให้ tuning ระบบได้ยาก

เมื่อ Grab เริ่มต้องรองรับการประมวลผลมากขึ้น เช่น ในระบบการจ่ายเงินแบบเรียลไทม์ ทีมจึงเริ่มมองหาภาษาใหม่ที่ เร็ว, ปลอดภัย, และ predictable

ทำไมถึงเลือก Rust

ทีม Grab ทดลองหลายภาษา ทั้ง C++, Java, และ Rust
แต่สุดท้าย Rust ชนะเพราะมันให้สิ่งที่ Go ไม่มี:

  • Memory safety โดยไม่ต้องมี GC
  • Zero-cost abstraction (ไม่ต้องแลกความเร็วกับความสะดวก)
  • Thread safety และ predictable performance
  • Ecosystem ที่โตเร็ว โดยเฉพาะใน systems programming

และที่สำคัญ — Rust สามารถทำงานร่วมกับ Go ได้ ในช่วงเปลี่ยนผ่าน (ผ่าน FFI) ทำให้ migration ค่อย ๆ ทำได้โดยไม่ต้อง rewrite ทั้งระบบทันที

วิธีที่ทีม Grab ย้ายระบบ

ทีมไม่ได้เขียนใหม่ทั้งหมดในทีเดียว แต่ใช้แนวทาง “strangler pattern” — ค่อยๆ เขียนส่วนสำคัญใหม่ใน Rust แล้วเชื่อมกับ Go เดิม

กระบวนการหลักคือ:

  1. สร้าง Rust microservice ที่ทำหน้าที่เฉพาะส่วน critical (เช่น counter core)
  2. ใช้ FFI bridge ให้ Go เรียกใช้ Rust code ได้
  3. ค่อยๆ ย้าย logic ที่เหลือมาทีละส่วน

ผลลัพธ์

หลัง migration ไป Rust ทีม Grab รายงานผลลัพธ์ที่น่าทึ่ง:

before-after-result-table-from-go-to-rust
result หลังจากการ migrate จาก Golang เป็น Rust

บทเรียนจาก Grab

Go เหมาะกับ speed of development, Rust เหมาะกับ speed of system.

"Go ทำให้ทีมเคลื่อนไหวเร็ว แต่ Rust ทำให้ระบบนิ่งและเร็วขึ้น"

Rust บังคับให้คิดอย่างมีระบบตั้งแต่ต้น — เพราะต้องจัดการ ownership และ lifetime ชัดเจน
นั่นทำให้บัคเรื่อง memory หายไปแทบหมด การ rewrite ไม่ได้แปลว่าทิ้งของเดิม
Grab ใช้ Rust เสริม Go ไม่ใช่แทนทันที — ค่อย ๆ ปรับจนมั่นใจ

บทสรุป

การเลือกภาษาไม่ใช่ศาสนา แต่คือการเลือกเครื่องมือที่เหมาะกับ “ภารกิจของระบบ”

Rust ไม่ได้มาแทน Go ในทุกกรณี — แต่ในโลกที่ความเร็วและความเสถียรคือทุกสิ่ง มันอาจเป็นเหมือน ดาบของนักรบที่ไม่ต้องเหลาอีกต่อไป

sandwiched-developer-author
s
WRITTEN BY

sirawich

[@portabletext/react] Unknown block type "undefined", specify a component for it in the `components.types` prop
Read More

Related posts

sandwiched-developer-golang-art-of-empty-world
sandwiched-developer-author
s
sirawich
·Jun 20, 2025

🕊️ Golang: ศิลปะแห่งความว่างเปล่าที่เปลี่ยนโลก

sandwiched-developer-go-ภาษาของผู้ไม่เร่งรีบ-แต่ไปถึงเส้นชัยก่อน
sandwiched-developer-author
s
sirawich
·Jun 3, 2025

🐢 Go: ภาษาของผู้ไม่เร่งรีบ แต่ไปถึงเส้นชัยก่อน

sandwiched-developer-rust-slient
sandwiched-developer-author
s
sirawich
·May 31, 2025

Rust ความเงียบงันของเหล็กกล้า

golang-ภาษาแห่งความสงบ-ที่เกิดมาเพื่อรองรับความวุ่นวาย
sandwiched-developer-author
s
sirawich
·May 31, 2025

Golang ภาษาแห่งความสงบ ที่เกิดมาเพื่อรองรับความวุ่นวาย