Skip to main content
idle · aws

Transit Gateways attached but carrying zero bytes

resource types
1
rule IDs covered
1
severity
low

What does ZopNight detect here?

A Transit Gateway bills roughly $36 a month for every attachment even when nothing crosses it. ZopNight reads BytesIn and BytesOut over 30 days and flags the gateway only when both directions sit at exact zero; one direction alone is never enough, and missing data means no finding.

Signal and threshold

How ZopNight evaluates Transit Gateways attached but carrying zero bytes.
Field Value
Rule IDsRC-164
Categoryidle
Severitylow
Metricnone — pure configuration read
Sourcetransit_gw_idle.go

Attachments are the bill, not the gateway

A Transit Gateway has no base charge of its own. AWS bills per attachment-hour, roughly $36 a month for each VPC, VPN or Direct Connect attachment, plus a per-GB processing fee on the traffic that crosses. So an abandoned TGW is not free: every attachment left in place keeps its own meter running, while the data-processing line reads zero precisely because nothing moves anymore.

The same pricing shape explains an edge case. A gateway with no attachments at all prices out to $0, and the rule drops it rather than recommend deleting something that already costs nothing. Whatever survives to become a finding is real, recoverable attachment spend.

Zero in both directions, or nothing

Two of the CloudWatch counters under AWS/TransitGateway carry the evidence: BytesIn and BytesOut, each over a 30-day window. The gateway is idle only when the average and the maximum of both series are exactly 0. A gateway that only egresses, or only ingresses, is still doing a job and is never flagged. An earlier version of this check keyed on an attachments=0 tag that no pipeline ever populated, leaving it permanently silent, and the metric-based test replaced it.

Pulling BytesIn and BytesOut yourself

Terminal window
aws cloudwatch get-metric-statistics \
--namespace AWS/TransitGateway --metric-name BytesIn \
--dimensions Name=TransitGateway,Value=tgw-0123456789abcdef0 \
--start-time "$(date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)" \
--end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--period 86400 --statistics Sum Maximum

Run it a second time with --metric-name BytesOut. Both have to come back flat for the finding to be valid.

Why some idle gateways still go unreported

The rule abstains whenever either byte series is absent or has less than a week of recorded coverage, whenever any sample is non-zero, and whenever no positive monthly price is on record. Beyond those data gates, emission currently sits behind a feature flag: findings stay held back until the aggregator fix this rule depends on is confirmed rolled out to stage. Severity is deliberately low: this is housekeeping, not a cost emergency.

Detaching before deleting

Removal is a guided workflow, not a one-shot delete. Confirm no VPC, VPN or Direct Connect gateway still terminates on the TGW, remove the remaining route-table associations, then delete the gateway itself. Any CloudFormation stack that references it needs updating too, or the next stack operation will fail on the resource you just removed, or quietly recreate it.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·