The cross-AZ data transfer costs hiding in your database traffic
The line item nobody can explain
Cross-AZ data transfer is one of the least understood costs on an AWS bill. It does not map to a resource you can point at, it just shows up as data transfer charges, and it grows silently as traffic increases. A common source is an application instance talking to its database across an Availability Zone boundary, paying per gigabyte in both directions for traffic that could have been free.
$20k a year for traffic that should be free
One client was paying over $20,000 a year in cross-AZ data transfer, a large part of it for traffic between EC2 instances and their databases that happened to sit in a different Availability Zone.
Some of that was a legacy pattern: a single instance talking to a single Aurora instance. When those two are in different AZs, there is no upside at all, only downsides: you pay for the transfer, you add latency on every query, and you have taken on a dependency across two AZs, so an outage in either one can take the setup down. Same AZ is cheaper, faster, and more resilient at the same time.
Finding it by tag
The challenge, as usual, is finding which databases have this problem across a large fleet. This client had consistent tags on both sides, for example a Customer tag with the same value on a database and the instance using it.
I built a small tool that uses those tags to match each database to the instance that talks to it, then flags every case where the two are in different AZs. For each of those, it reads the database’s network bandwidth metrics, calculates the resulting data transfer cost, and outputs a spreadsheet ordered by cost.
It turned out that almost half of all their databases were in a different AZ from the instance using them.
The fix, with no application changes
For Aurora, moving a database to the same AZ as its consumer does not require touching the application. You create a read replica in the target AZ and trigger a failover to it, so the writer ends up co-located with the instance that uses it. From the application’s perspective nothing changes.
Doing that across the affected databases was set to save the client about $16,000 a year, without their team having to lift a finger, and with better latency and more resilience as a bonus. The same check is worth running against ElastiCache, which can have exactly the same cross-AZ pattern.
What to check
- Are your application instances and the databases they talk to in the same AZ? For single-instance-to-single-database setups, there is rarely a reason not to be.
- Do you have consistent tags that let you match a database to its consumer? If so, finding the mismatches is straightforward to automate.
- Which of those mismatched pairs move the most traffic? That is where the money is, and where to start.
If you suspect cross-AZ traffic is quietly inflating your bill, book a discovery call or reach out on LinkedIn.
-Cristian