# The science of routing print orders

[Canva](https://yomu.fyi/company/canva) · Constantinos Kavadias · Dec 10, 2024

**Type:** Problem & solution

## Summary

Canva's global print network requires selecting optimal suppliers to balance delivery times, packaging counts, and environmental emissions. To resolve these challenges before user checkout, the engineering team designed a modular routing architecture that decouples graph construction, decision logic, and path traversal. During graph traversal, the system generates action objects capturing forward paths and decision query results, which are compiled into timestamped routing logs in blob storage for asynchronous auditing. Utilizing preprocessed graph queries alongside ElastiCache, Redis, and database read replicas, the infrastructure sustains high-throughput evaluation without coupling cost logic to traversal code. As a result, print routing completes within an average of 50 milliseconds at the 99th percentile during peak usage while maintaining 99.999% data availability.

## Context

Canva's expanding print product catalog and distributed global supplier network made it difficult to determine production and shipping locations efficiently. Querying relational databases at runtime was impractical, and traditional traversal algorithms tightly coupled decision costs with pathfinding, hindering configurability and checkout speed.

## Approach / What changed

Canva built a decoupled, plug-and-play architecture separating graph building, decision-making, and graph traversal. The system records traversal actions into asynchronous routing logs stored in key-value blob storage, preprocesses graphs and queries, and leverages Redis, ElastiCache, and database read replicas to support fast lookups.

## Takeaways

- Decoupling decision-making logic from graph traversal algorithms prevents regressions and allows independent component changes or A/B testing.
- Traversal steps and engine decisions are packaged into unique routing logs saved asynchronously to key-value blob storage with automated expiry for debugging.
- Preprocessing graphs alongside caching with ElastiCache and Redis achieved 99.999% availability and 50 ms p99 routing latency during peak loads.

**Tags:** [Architecture](https://yomu.fyi/topic/architecture), [Caching](https://yomu.fyi/topic/caching), [Performance](https://yomu.fyi/topic/performance), [Redis](https://yomu.fyi/topic/redis)

[Read original post](https://www.canva.dev/blog/engineering/the-science-of-routing-print-orders)
