# Idle VPC Interface Endpoint

> An Interface endpoint bills an hourly fee for every ENI it places, 1 per subnet it spans, so a 3-AZ endpoint costs three times a single-AZ one before any byte moves. ZopNight fires only on endpoints whose BytesProcessed peak stays under 1 MiB across 30 covered days, and prices the saving per ENI.

Source: https://zop.dev/integrations/aws/recommendations/idle-vpc-interface-endpoint
Updated: 2026-08-19

---

## Gateway endpoints are free; this rule knows it

VPC endpoints come in two economics. Gateway endpoints (S3, DynamoDB) are free routing
constructs. Flagging one is always wrong, and the rule hard-excludes anything discovery
does not positively identify as an Interface endpoint. Interface (PrivateLink) endpoints are
the billable kind: each one provisions an ENI per subnet, and each ENI carries [an hourly fee
plus data charges](https://aws.amazon.com/privatelink/pricing/). The fee accrues identically at zero traffic, which is what makes an idle
one worth hunting.

## Multiplied by availability zones

The per-AZ structure is why these findings are bigger than they look. The standard
three-subnet template creates three ENIs per endpoint (three hourly fees), and a VPC with a
dozen service endpoints built that way carries dozens of billed ENIs. The rule reads the
endpoint's ENI count from discovery and prices cost as count × the single-AZ rate; an
endpoint whose count was never captured abstains rather than assuming one.

## What has to be true before it fires

Four gates, all mandatory: the endpoint is an available Interface endpoint; its
[BytesProcessed series](https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-cloudwatch-metrics.html) exists with at least 30 days of coverage and a window peak under the
1 MiB floor (tolerating keepalive chatter while any real traffic spike disqualifies); the
ENI count is known; and a positive per-ENI rate was resolved. Any gap abstains. This rule
replaced an older fail-open version that flagged every available endpoint on no usage
evidence at all. It also currently sits behind a deployment feature flag, so an eligible
endpoint may not surface until that cohort gate opens.

## Measure one endpoint yourself

```bash
aws cloudwatch get-metric-statistics \
  --namespace AWS/PrivateLinkEndpoints --metric-name BytesProcessed \
  --dimensions Name="VPC Endpoint Id",Value=vpce-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 Maximum
```

## Deleting without breaking DNS

Private DNS is the sharp edge: with the endpoint gone, the service hostname resolves back to
public IPs, so security groups or route setups that assumed private paths may start failing
closed. Confirm no application depends on the endpoint's DNS names, delete from the VPC
console, and each removed ENI stops billing immediately.
