Symptom
The "Virtual Network", "Bandwidth", "Azure Firewall" or "Private Link" lines in Cost Management keep rising, and nobody can say which application causes them.
1. Break down by meter
Cost Management → Cost analysis → group by Meter (and then by Resource), filter on service name for networking services. Typical meters:
| Meter family | Charged for |
|---|---|
| VNet peering (intra-region / global) | GB in and out on each side of the peering |
| Bandwidth: inter-region / internet egress | GB leaving a region or going to the internet |
| Private Link | Per endpoint-hour + GB processed |
| NAT Gateway | Per hour + GB processed |
| Azure Firewall | Per deployment-hour + GB processed |
| VPN / ExpressRoute gateway | Per gateway-hour by SKU (+ ER circuit and metered data on some plans) |
Export to a storage account (daily cost export) if you want to trend these over months.
2. Find the flows
Enable VNet flow logs with traffic analytics on the hub and busy spokes, then query top talkers:
NTANetAnalytics
| where TimeGenerated > ago(7d) and SubType == "FlowLog"
| summarize GB = round(sum(BytesSrcToDest + BytesDestToSrc) / 1e9, 1) by SrcIp, DestIp, DestPort, FlowDirection
| sort by GB desc | take 25
Map IPs to resources (traffic analytics adds subnet/VM fields) and you'll usually see a few patterns.
3. Common causes and fixes
| Pattern | Fix |
|---|---|
| Spoke ↔ spoke traffic through the hub firewall, paying peering twice + firewall processing | Allow direct peering for trusted, high-volume pairs, or put tightly coupled apps in the same spoke |
| Backup or replication to another region over and over | Check replication schedules and compression; is the cross-region copy needed for every system? |
| VMs pulling container images/packages from the internet daily | Use ACR with geo-replication / caching, internal package mirrors |
| Private endpoints in every spoke for the same service | Centralise shared endpoints in the hub (watch peering cost vs endpoint cost) |
| Private endpoints for storage accounts that are never used | Remove them with the unused accounts |
| Large egress to on-premises over ExpressRoute with metered data | Compare with unlimited data plan once volume is known |
| NAT Gateway on subnets with little outbound need | Consolidate subnets onto one NAT Gateway per region/zone where design allows |
| Logs shipped cross-region to a central workspace | Keep workspaces regional or filter at the source |
4. Right-size gateways and firewalls
- VPN/ExpressRoute gateway SKU: check bandwidth and tunnel metrics over 30 days; downsize where the SKU allows (some changes require redeployment).
- Azure Firewall: Basic/Standard/Premium. Pay for Premium only where you use its features (TLS inspection, IDPS). Non-prod firewalls can be deallocated out of hours (see the firewall optimization post).
- Remove gateways for retired VPNs and old ExpressRoute connections.
5. Design rules that keep it down
- Keep chatty components (app + database + cache) in the same region and VNet.
- Prefer zone-aware placement for chatty tiers where latency matters.
- Decide hub inspection by risk: inspect north-south always, east-west where it adds security value.
- Use service endpoints where private endpoints aren't required (no per-GB Private Link charge; different security properties, so check with your security team).
6. Track monthly
A small workbook or cost view: networking cost by meter and by spoke/application tag, top 10 flows by GB. Review it with the platform team monthly.
Warning
Bypassing the hub firewall for cost reasons is a security decision. Document which flows go direct, why, and who approved it, and keep NSGs tight on both sides.
Checklist
- Networking cost broken down by meter and resource
- Flow logs and traffic analytics on hub and busy spokes
- Top flows mapped to applications
- Hairpinning, unused endpoints and repeated transfers fixed
- Gateway and firewall SKUs right-sized
- Monthly networking cost review