# This Rocket Ain't Stopping - Achieving Zero Downtime for Rails to Golang API Migration

[Grab](https://yomu.fyi/company/grab) · Lian Yuanlin · Oct 18, 2016

**Type:** Problem & solution

## Summary

Grab transitioned its public passenger app APIs from a legacy Rails application to a Golang service-oriented architecture to consolidate its codebase and engineering teams. Initial attempts to proxy traffic through a cloned Rails server via gRPC were abandoned after encountering TCP load imbalances during autoscaling events and memory leaks in the gRPC Ruby gem. The team pivoted to direct logic migration, porting Ruby logic directly into Go while decomposing modules into standalone services. Verification relied on log-based load testing and live shadow testing, where write operations were safely validated using mock data access layers that evaluated expected database outcomes. Production rollout progressed endpoint-by-endpoint using requests-per-second traffic throttling and prewarmed AWS Elastic Load Balancers before executing the final DNS switch.

## Context

Grab was transitioning from a Rails and NodeJS stack to a full Golang Service Oriented Architecture and needed to migrate live public passenger app APIs from an existing Rails app to a new Go server cluster without downtime.

## Approach / What changed

The team migrated endpoints individually across four phases—logic migration, log-based load testing, shadow testing with mock data access layers for write requests, and progressive rollout using requests-per-second throttling and prewarmed ELBs before cutting over DNS.

## Takeaways

- Initial proxying between Go and a Rails clone via gRPC was abandoned due to TCP persistent connection load imbalances during autoscaling events and a memory leak in the gRPC RubyGem.
- Shadow testing non-idempotent write requests (PUT/POST/DELETE) was achieved without duplicate writes by wrapping data access objects in mock code that generated and verified expected database rows.
- Throttling shadow and rollout traffic by percentage caused ELB request drops on high-traffic endpoints, prompting a switch to explicit requests-per-second (RPS) rate limits and ELB prewarming.

**Tags:** [AWS](https://yomu.fyi/topic/aws), [Go](https://yomu.fyi/topic/go), [Migrations](https://yomu.fyi/topic/migration), [REST APIs](https://yomu.fyi/topic/rest-api), [Testing](https://yomu.fyi/topic/testing)

[Read original post](https://engineering.grab.com/zero-downtime-migration)
