Incrementally routing traffic to newer version of service


Recently, I had a requirement to incrementally increase the traffic to a newer version of service we were deploying in production.

We didn’t wanted to go with random percentage approach. This is because our users are mobile app users and we didn’t want the users to hit the older version and newer version of service randomly.

That is, we wanted to consistently map the user to either be routed to an older version of newer version based on certain configurable percentage.

Open diagram in fullscren

Our proxy server was based on node.js

After evaluating several algorithms to generate hash based on user id, such as Base64, MD5. I finally zeroed out on CRC32 algorithm.

The simple reason being that output of CRC32 is a simple 32 bit integer which can be easily converted to a percentage value and the performance of crc32 being the fastest among all.

The simple methods below give the gist of algorithm. Our getHash function generates the 32 bit integer and routeRequestBasedonRampUp method uses this integer to map it to 1..100 buckets. Based on the rampup percentage value, it gives a boolean response which is used by proxy layer.

const getHash = userId => {
    return CRC32.str(userId) >>> 0;
};

const routeRequestBasedonRampUp = (userId, rampUpPercent) => {
  const NUM_BUCKETS = 100;
  
  const hash = getHash(userId);
  const bucket = hash % NUM_BUCKETS;

  return (bucket + 1 <= rampUpPercent); 
};

I have used this approach in production with this crc32 library

The decisioning time is <1ms and have been serving us really well.

Please let me know in the comments section if you think any better approach is available.