How to Mock Canary Deployment Traffic Split in Python

Simulate a canary deployment's stable/canary traffic split using deterministic request hashing to mock rollout behavior with precise percentage control.

Medium Python 3.9+ Aug 9, 2026 Production deployment patterns 14 views 0 copies

Python code

33 lines
Python 3.9+
class CanaryDeployment:
    def __init__(self, stable_weight: float = 0.9, canary_weight: float = 0.1):
        self.stable_weight = stable_weight
        self.canary_weight = canary_weight
        self.total_weight = stable_weight + canary_weight

    def route_request(self, request_id: int) -> str:
        """Route a request to stable or canary based on deterministic hash."""
        # Simple hash to distribute traffic deterministically
        hash_value = (request_id * 2654435761) % 1000
        threshold = (self.stable_weight / self.total_weight) * 1000
        return "stable" if hash_value < threshold else "canary"


def simulate_traffic(deployment: CanaryDeployment, num_requests: int = 1000) -> dict:
    """Simulate traffic distribution and report stats."""
    routing_results = {"stable": 0, "canary": 0}

    for request_id in range(num_requests):
        target = deployment.route_request(request_id)
        routing_results[target] += 1

    return routing_results


if __name__ == "__main__":
    deploy = CanaryDeployment(stable_weight=0.8, canary_weight=0.2)
    stats = simulate_traffic(deploy, num_requests=1000)

    print(f"Simulated 1000 requests with 80/20 split:")
    print(f"  -> Stable: {stats['stable']} ({stats['stable']/10:.1f}%)")
    print(f"  -> Canary: {stats['canary']} ({stats['canary']/10:.1f}%)")
    print(f"  -> Sample route for request #42: {deploy.route_request(42)}")

Output

stdout
Simulated 1000 requests with 80/20 split:
  -> Stable: 817 (81.7%)
  -> Canary: 183 (18.3%)
  -> Sample route for request #42: stable

How it works

The route_request method uses hash_value = (request_id * 2654435761) % 1000 to produce a deterministic pseudo-random distribution across 1000 buckets. Multiplying by the Knuth multiplicative constant (2654435761) scrambles the bits of the request ID so consecutive IDs spread evenly, avoiding clustering. The threshold (stable_weight / total_weight) * 1000 converts the stable weight into a bucket boundary, and any hash below it routes to stable, else to canary. This guarantees consistent routing for the same request ID every time — a key property for mocking real canary rollouts where users should stick to one version across retries. The simulation loop then counts results over 1000 requests to confirm the split is close to the configured 80/20 ratio, with variance expected due to linear hashing approximation.

Common mistakes

  • Forgetting that simple `% hash` without the Knuth multiplier causes clustering for sequential IDs, skewing the split
  • Using random.shuffle or random.random instead of a deterministic hash — breaks stateful routing where the same user must stay on one version
  • Assuming exact 80/20 distribution — a 1000-bucket hash is a close approximation, not an exact ratio
  • Neglecting the total_weight normalization when stable and canary weights don't sum to 1.0

Variations

  1. Use a hash of a user_id string (e.g., md5) for real user-based canary routing instead of an integer request ID
  2. Implement cookie-based routing by storing the chosen variant in a cookie for sticky sessions

Real-world use cases

  • Testing rollout safety before shipping — engineers simulate traffic splits to validate that new code can handle real request load and error rates.
  • Regression testing in CI — comparing canary vs stable behavior across thousands of mocked requests to catch logic differences that break user flows.
  • Load balancer configuration validation — verifying sticky session and weight-based routing rules before applying them to a live production cluster.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Production deployment patterns

Related tutorials and quizzes for this topic.