VPC Endpoint Pricing and AWS PrivateLink Explained: Free Gateway Endpoints, Interface Endpoint Costs, the NAT Gateway Break-Even, ECR and S3 Endpoints, and How to Cut the Bill
VPC endpoint pricing depends entirely on which kind of endpoint you use. Gateway endpoints, which exist only for S3 and DynamoDB, are free: no hourly charge and no data processing charge. Interface endpoints, the AWS PrivateLink kind that every other service uses, cost about $0.01 per hour for each endpoint network interface, and you get one network interface per Availability Zone you enable, plus $0.01 per GB of data processed (cheaper after the first petabyte a month). So one interface endpoint spread over three Availability Zones costs roughly $21.90 a month before any data, and a typical private ECS or Lambda setup that needs five or six of them lands above $100 a month. That is still often cheaper than sending the same traffic through a NAT gateway, which charges about $0.045 per hour and $0.045 for every GB, four and a half times the endpoint's data rate. Below: what PrivateLink actually is, gateway vs interface endpoints side by side, the exact bill math, the break-even point against NAT, which endpoints private workloads really need, the endpoint costs nobody mentions, and how to keep the bill small.
Jake's booking app moved into private subnets in September, on Ethan's advice, and the next AWS bill had a new line Jake did not recognize: "VPC Endpoint Hours." It was $131. "We moved the servers somewhere safer," Jake said, "and safety costs a hundred and thirty-one dollars a month?" Ethan opened Cost Explorer. Six interface endpoints across the production and development VPCs, three Availability Zones each, running every hour of the month; and, two lines further down, a NAT gateway bill that had dropped by more than that, because the container images, logs and secrets were no longer going through it. "So the new line is the cheaper one," Jake said, after a while. "This time," said Ethan.
New to VPC networking? Our plain-English VPC guide explains subnets and route tables, and the internet gateway vs NAT gateway guide covers the other two ways out of a VPC. Prices below are the US East examples on AWS's pricing pages; other Regions differ slightly, so check yours in the AWS Pricing Calculator.
What AWS PrivateLink and VPC endpoints actually are
A VPC endpoint lets resources in a private subnet reach an AWS service without going through the internet, a NAT gateway or an internet gateway. Your traffic stays on the AWS network, and the service sees it arriving from your VPC. There are two designs behind the name:
- Gateway endpoints are a target in your route tables. When an instance sends traffic to S3 or DynamoDB, the route table sends it to the endpoint instead of the NAT gateway. Nothing new appears in your subnet.
- Interface endpoints are AWS PrivateLink: AWS places an elastic network interface with a private IP address in each subnet you choose, and private DNS makes the normal service name (for example
secretsmanager.us-east-1.amazonaws.com) resolve to those private IPs inside your VPC. Your code does not change; the name simply resolves somewhere closer.
PrivateLink is also how you publish your own service privately: you put it behind a Network Load Balancer, create an endpoint service, and other VPCs or accounts connect to it with their own interface endpoints, without peering or overlapping-CIDR worries. AWS Marketplace SaaS products use the same mechanism, which is why you will see "PrivateLink" on vendor pages too.
Why would anyone pay for this when a NAT gateway already gets private subnets to AWS services? Three reasons come up again and again. First, cost: per GB, endpoints are cheaper, and for S3 and DynamoDB they are free. Second, security: with endpoints, a private subnet can have no route to the internet at all, so a compromised instance has nowhere to send data except the services you chose, and an endpoint policy can narrow that to your own buckets and tables. Third, compliance: many audit frameworks ask for traffic to AWS services to stay off the public internet, and endpoints are the simplest way to show that.
"So a gateway endpoint is a signpost," Jake said, "and an interface endpoint is a little office the service opens inside our building." "A little office that charges rent by the hour," said Ethan.
Gateway vs interface endpoints, side by side
| Gateway endpoint | Interface endpoint (PrivateLink) | |
|---|---|---|
| Services | S3 and DynamoDB only | Most AWS services, including S3, plus partner and your own endpoint services |
| Price | Free | About $0.01 per hour per AZ, plus $0.01 per GB processed |
| How traffic finds it | Route table entry with the service's prefix list | Private DNS name resolving to private IPs in your subnets |
| Security | Endpoint policy | Endpoint policy plus a security group on the endpoint |
| Reachable from on premises, VPN, peered VPCs | No | Yes, over Direct Connect, VPN, peering or Transit Gateway |
| Region | Same Region as the VPC | Same Region, with cross-Region connectivity for some services at extra charge |
S3 is the only service with both. Use the free gateway endpoint for traffic from inside the VPC, and add an S3 interface endpoint only when you need to reach S3 privately from on premises or from another network that cannot use your route tables. Our S3 VPC endpoint guide covers the policies that make either one refuse requests.
How interface endpoint charges add up
Two meters run for every interface endpoint you create:
- Endpoint hours. You pay for each hour the endpoint exists, in each Availability Zone you enabled, whether traffic flows or not. Partial hours count as full hours. At about $0.01 per hour per AZ, that is about $7.30 per AZ per month (730 hours).
- Data processed. Every GB that passes through any interface endpoint in the Region is charged: $0.01 per GB for the first petabyte a month, $0.006 for the next four petabytes, and $0.004 after that. The tiers are counted across all your interface endpoints in the Region, not per endpoint.
Here is what that means for setups you are likely to build:
| Setup | Endpoint hours per month | Plus data |
|---|---|---|
| 1 interface endpoint, 1 AZ (dev) | about $7.30 | $0.01 per GB |
| 1 interface endpoint, 3 AZs | about $21.90 | $0.01 per GB |
| Private Fargate set: ecr.api, ecr.dkr, logs, secretsmanager (4 endpoints, 3 AZs) + S3 gateway | about $87.60 | image pulls and logs at $0.01 per GB; S3 layers free |
| Systems Manager set: ssm, ssmmessages, ec2messages (3 endpoints, 2 AZs) | about $43.80 | session traffic at $0.01 per GB |
| Gateway endpoints for S3 and DynamoDB | $0 | $0 |
Jake's production VPC was exactly the third row: four endpoints, three zones, $87.60 for a full month. The other $43.80 was the development VPC, whose two endpoints copied production's three zones. Ethan's first saving was to notice that development did not need them.
Endpoints vs NAT gateway: where the break-even is
Private subnets reach AWS services either through a NAT gateway or through endpoints, and the two price differently. A NAT gateway charges about $0.045 per hour plus $0.045 per GB it processes; an interface endpoint charges about $0.01 per hour per AZ plus $0.01 per GB. So the comparison has two parts:
- Per GB, endpoints are always cheaper: $0.01 against $0.045 saves $0.035 on every GB, or $35 per terabyte.
- Per hour, the endpoint adds cost unless it lets you remove the NAT gateway entirely. One endpoint in three zones costs about $21.90 a month, which the per-GB saving pays back once that service carries roughly 625 GB a month ($21.90 / $0.035).
That gives you three practical rules:
- S3 and DynamoDB: always use gateway endpoints. They are free and save NAT charges from the first byte.
- Heavy services such as ECR image pulls, CloudWatch Logs or Kinesis: add interface endpoints when their traffic passes a few hundred GB a month, or when the security team wants that traffic kept off the NAT path anyway.
- Workloads that need nothing from the internet: replace the NAT gateway completely with the handful of endpoints they use. Removing one NAT gateway per AZ saves its hourly charge as well, and private subnets with no route out are easier to defend.
Our NAT gateway bill guide shows how to find which services send the most traffic through NAT, which is the data you need to apply these rules.
Which endpoints private workloads actually need
Most surprise endpoint bills come from creating endpoints "just in case." These are the sets that real workloads need when they run in private subnets with no NAT gateway:
| Workload | Endpoints |
|---|---|
| ECS on Fargate pulling from ECR | ecr.api, ecr.dkr (interface), S3 (gateway, image layers), logs if you use awslogs, plus secretsmanager or ssm if tasks read secrets |
| Systems Manager Session Manager and patching | ssm, ssmmessages, ec2messages (interface), S3 (gateway) for patch baselines and logs |
| Lambda in a VPC calling DynamoDB and S3 | S3 and DynamoDB gateway endpoints, nothing else |
| EKS nodes in private subnets | ecr.api, ecr.dkr, S3 gateway, ec2, sts, logs, plus elasticloadbalancing if the load balancer controller runs |
| Apps calling Bedrock privately | bedrock-runtime (interface), and any agent or knowledge base endpoints you use |
If something is missing, the symptom is a timeout rather than an error, because the request has nowhere to go. Our guides on SSM Agent not online, ECS CannotPullContainerError and Lambda without internet walk through each case.
How interface endpoint DNS works, and why it matters for your bill
An interface endpoint only saves you money if your traffic actually uses it, and that depends on DNS. When you create an interface endpoint with private DNS enabled, AWS creates a hidden private hosted zone for the service's normal name, such as logs.us-east-1.amazonaws.com, so that inside your VPC the name resolves to the endpoint's private IP addresses instead of public ones. Your SDKs and CLI keep using the same names, and the traffic quietly moves off the NAT gateway.
Three settings have to line up for that to happen:
- The VPC needs DNS support and DNS hostnames turned on (
enableDnsSupportandenableDnsHostnames). Default VPCs have both; VPCs built from older templates sometimes have hostnames off, and private DNS cannot be enabled until you turn it on. - Your instances must use the VPC's resolver (the Amazon-provided DNS at the VPC base address plus two). If your servers use your own DNS servers, those servers must forward AWS service names to the VPC resolver, or the private names are never seen.
- Private DNS must be enabled on the endpoint. Without it, the endpoint still works, but only through its own long name, such as
vpce-0abc123-xyz.logs.us-east-1.vpce.amazonaws.com, and you have to configure every client to use that name.
To check from an instance, look up the service name: a private address (10.x, 172.16-31.x or 192.168.x) means the endpoint is in use; a public address means traffic is still heading for the NAT gateway.
nslookup secretsmanager.us-east-1.amazonaws.com # Address: 10.0.12.47 -> the interface endpoint, good # Address: 52.x.x.x -> public endpoint, still going through NAT
S3 has a special case. If you create an S3 interface endpoint with private DNS, you can choose to apply private DNS only to traffic arriving from outside the VPC (for example from on premises through a Route 53 Resolver inbound endpoint). That keeps clients inside the VPC on the free gateway endpoint while your data center uses the interface endpoint, which is exactly the split you want for cost.
Ethan found this one the hard way on another project: the endpoints had been created, the bill had not moved, and the servers were using a corporate DNS server that knew nothing about the private zones. One forwarding rule later, the NAT gateway's processed bytes dropped by two thirds.
Endpoint created, but traffic still goes through NAT
If your NAT gateway bill does not fall after you add endpoints, one of these is usually the reason. Work through them in order:
- The gateway endpoint is not on the right route table. Gateway endpoints act only on the route tables you attach them to. If your private subnets use three route tables and you attached one, two subnets still send S3 traffic to NAT. Check that the route table of every private subnet lists the S3 prefix list with the endpoint as its target.
- The bucket is in another Region. Gateway endpoints only reach S3 buckets in the same Region as the VPC. Requests to a bucket in another Region still take the NAT path, and also pay inter-Region transfer. Moving the data, or the workload, to the same Region is the only real fix.
- Private DNS is off, or custom DNS ignores it, as described above, so clients still resolve the public names.
- The traffic is not to AWS at all. Package mirrors, container images from Docker Hub, third-party APIs and software updates go through NAT whatever endpoints you have. VPC Flow Logs, filtered on the NAT gateway's network interface, show you where those bytes go.
- The endpoint policy or security group blocks requests, and the application falls back to a different path or simply retries. That shows up as errors rather than NAT traffic, but it is worth ruling out.
The surest test is the NAT gateway's BytesOutToDestination metric in CloudWatch before and after the change. If it does not move, your traffic is not using the endpoint, whatever the console says.
ECR VPC endpoint pricing, worked through
Container images are where endpoint pricing surprises people most, in both directions. A private ECS or EKS cluster pulling from Amazon ECR needs two interface endpoints, ecr.api for authentication and image metadata and ecr.dkr for the registry calls Docker makes, plus the S3 gateway endpoint. The S3 endpoint matters because ECR stores image layers in S3, and the layers are almost all of the bytes in a pull.
Take a cluster in three Availability Zones that pulls 2 TB of images a month, which is easy to reach with frequent deployments and a 1 GB image:
| Path | Hourly | Data | Monthly total |
|---|---|---|---|
| All through one NAT gateway | about $32.85 | 2,000 GB x $0.045 = $90 | about $123 |
| ecr.api + ecr.dkr in 3 AZs, layers through the S3 gateway endpoint | about $43.80 | a few GB of metadata at $0.01; layers free | about $44 |
| ECR endpoints but no S3 gateway endpoint (and a NAT gateway) | about $76.65 | layers still through NAT, about $90 | about $167 |
The last row is the trap: someone adds the two ECR endpoints, forgets the free S3 one, and ends up paying for both paths. And without a NAT gateway at all, the same mistake makes pulls fail, because the layer downloads have no way out. Our CannotPullContainerError guide shows the error that produces. Pull-heavy clusters should also look at image size: halving an image halves the data line, whichever path it takes.
S3 VPC endpoint pricing: gateway or interface?
S3 is the one service where you choose, and the price difference is large. The gateway endpoint is free for any amount of traffic. An S3 interface endpoint costs the normal interface rates: about $7.30 per AZ per month plus $0.01 per GB, so moving 10 TB a month through one adds about $100 in data processing alone.
So why do S3 interface endpoints exist? Because a gateway endpoint works only for traffic that starts inside the VPC and follows its route tables. Data centers over Direct Connect or VPN, other VPCs over Transit Gateway, and some managed services cannot use it. For those, the interface endpoint gives S3 a private IP address they can reach. The usual pattern is both: the gateway endpoint for everything inside the VPC, and an interface endpoint only for the traffic that cannot reach the gateway one. When both exist, clients inside the VPC keep using the gateway path unless you point them at the interface endpoint's DNS name, so the free path is not lost by adding the paid one.
Endpoint service pricing: publishing your own service
If you publish your own service through PrivateLink, the bill splits in a way that surprises providers. Consumers pay for their interface endpoints: the hourly charge per AZ and the per-GB processing. You, the provider, pay for the Network Load Balancer in front of your service (or a Gateway Load Balancer for network appliances), including its load balancer capacity units, plus whatever the service itself costs to run. There is no separate charge for creating the endpoint service.
Two details are worth checking before you offer a service this way:
- Availability Zones must line up. A consumer can only use the endpoint in zones where your load balancer also runs. Run your NLB in every zone your customers might use, or they will be unable to create endpoints there.
- Cross-Region access has its own charge. If you let consumers connect from other Regions, your side pays an hourly charge for each remote Region you enable, and traffic carries inter-Region data transfer charges on top of endpoint processing.
For SaaS vendors on AWS Marketplace, this is why a "PrivateLink option" is often listed as an enterprise feature: the vendor runs the NLB, and the customer pays the endpoint charges in their own account.
Finding endpoint costs in Cost Explorer and the pricing calculator
Endpoint charges appear under the Amazon Virtual Private Cloud service on your bill, not under the service you are connecting to. To see them in Cost Explorer:
- Open Cost Explorer and set the date range to the last full month.
- Filter Service to Amazon Virtual Private Cloud.
- Group by Usage type. Endpoint hours show as usage types containing
VpcEndpoint-Hours, and processing asVpcEndpoint-Bytes, each prefixed with a Region code. - To see which endpoint costs what, activate a cost allocation tag such as
NameorEnvironmenton your endpoints, then group by that tag. Tags only apply to costs from the day you activate them.
To estimate before you build, the AWS Pricing Calculator has a VPC section where you enter the number of interface endpoints, the AZs per endpoint and the GB processed. Quick mental math works too: $7.30 for each endpoint in each zone, plus a cent per GB.
Ethan's check for Jake took four minutes: group by usage type, then by the Name tag, and the development VPC's three-zone endpoints stood out at once.
Endpoint policies: the security part that costs nothing
Every endpoint can carry an endpoint policy, an IAM-style resource policy that limits what can be done through it. The default policy allows everything, which is fine for getting started, but tightening it is free and closes a real gap: without it, a compromised instance could copy data to any S3 bucket in the world through your endpoint, including one the attacker owns.
This policy on an S3 gateway endpoint allows access only to buckets owned by accounts in your AWS Organization (replace the organization ID with yours):
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "OnlyOurOrgBuckets",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "*",
"Condition": { "StringEquals": { "aws:ResourceOrgID": "o-exampleorgid" } }
}]
}
Test it before you tighten production: some AWS features read from AWS-owned buckets (for example, Amazon Linux package repositories and some Systems Manager documents), and a strict policy blocks them until you add those buckets. If requests start failing with AccessDenied after a policy change, our S3 VPC endpoint AccessDenied guide walks through the usual causes.
The endpoint costs nobody mentions
- Every VPC pays separately. Ten VPCs each with the same six endpoints means sixty endpoints. Centralizing them in a shared-services VPC reached over Transit Gateway cuts the count, though Transit Gateway adds its own attachment and data charges.
- Every AZ pays separately. The hourly charge is per AZ. Enabling all six zones of a large Region multiplies it by six.
- Cross-AZ traffic still applies. A client in one zone using an endpoint interface in another zone also pays normal inter-AZ data transfer; enable the endpoint in each zone your clients use, or keep clients zone-local. See our cross-AZ traffic guide.
- Cross-Region endpoints cost more. Where a service supports cross-Region PrivateLink connectivity, you also pay inter-Region data transfer, and the service provider pays an hourly charge per remote Region.
- Forgotten endpoints keep billing. An endpoint left behind after a test runs every hour until deleted.
- Resource endpoints are priced differently. The newer resource endpoints, which reach a specific resource such as a database by IP or DNS name, are billed per resource per hour (about $0.02 in US East) plus the same data tiers.
- The NAT gateway you keep has a public IPv4 charge. Each NAT gateway's Elastic IP counts as a public IPv4 address at $0.005 per hour, about $3.65 a month. Removing NAT gateways once endpoints cover your traffic saves that as well.
None of these is large alone. Together, in an account with many VPCs, they are why two teams running the "same" setup can see endpoint bills that differ by a factor of five.
How to keep the endpoint bill small
- Add gateway endpoints for S3 and DynamoDB everywhere. They are free and remove the largest NAT traffic in most accounts.
- Create only the interface endpoints your workloads call. Check CloudTrail or VPC Flow Logs for the services private resources actually use.
- Use fewer zones outside production. A development VPC in one or two zones halves or thirds the hourly cost.
- Share endpoints across VPCs through a central VPC and Route 53 private hosted zones when you run many VPCs.
- Delete unused endpoints. Filter Cost Explorer by the VpcEndpoint usage type and compare with the endpoints listed in each VPC.
- Keep the NAT gateway only if something truly needs the internet; otherwise remove it once the endpoints are in place.
"So the trick," Jake said, "is not to rent an office in every building for every visitor." "And to close the offices nobody visits," said Ethan.
A full monthly bill, before and after endpoints
Prices per endpoint are easy to quote; what you really want to know is what happens to your total. Here is a realistic small production setup in US East: an ECS service on Fargate in private subnets across three Availability Zones, one NAT gateway per zone for resilience, pulling about 1 TB of container images a month, sending 300 GB of logs to CloudWatch, reading and writing 2 TB to S3, and making light calls to Secrets Manager.
| Line | Before: everything through NAT | After: endpoints, no NAT |
|---|---|---|
| NAT gateway hours (3 x 730 h x $0.045) | about $98.55 | $0 |
| NAT data (3.3 TB x $0.045 per GB) | about $148.50 | $0 |
| Public IPv4 on the NAT gateways (3 x $3.65) | about $10.95 | $0 |
| Interface endpoints: ecr.api, ecr.dkr, logs, secretsmanager (4 x 3 AZs) | $0 | about $87.60 |
| Interface endpoint data (about 300 GB of logs plus a few GB of registry calls at $0.01) | $0 | about $3.10 |
| S3 gateway endpoint (image layers and app data) | $0 | $0 |
| Network total | about $258 | about $91 |
Two lessons hide in that table. First, the S3 gateway endpoint did most of the work: 2 TB of app data plus the image layers moved to a free path. Second, the saving only reached its full size because the NAT gateways could be removed entirely; if the service still needed the internet for a payment API, you would keep at least one NAT gateway, and the "after" column would rise by its hourly charge plus the internet-bound data. Run the same table with your own numbers from Cost Explorer before you decide which endpoints to add; it takes ten minutes and replaces guesswork with a figure you can defend.
Jake ran this table for his own account, with Ethan watching. His numbers were smaller, but the shape was the same, and for the first time he could explain each networking line on the bill to his co-founder.
A setup that works, end to end
# free gateway endpoints for S3 and DynamoDB on the private route tables aws ec2 create-vpc-endpoint --vpc-id vpc-0abc123 --vpc-endpoint-type Gateway \ --service-name com.amazonaws.us-east-1.s3 --route-table-ids rtb-0priv1 rtb-0priv2 aws ec2 create-vpc-endpoint --vpc-id vpc-0abc123 --vpc-endpoint-type Gateway \ --service-name com.amazonaws.us-east-1.dynamodb --route-table-ids rtb-0priv1 rtb-0priv2 # one interface endpoint with private DNS, in two subnets (two AZs), with a security group allowing 443 from the VPC aws ec2 create-vpc-endpoint --vpc-id vpc-0abc123 --vpc-endpoint-type Interface \ --service-name com.amazonaws.us-east-1.secretsmanager \ --subnet-ids subnet-0a1 subnet-0b2 --security-group-ids sg-0endpoints --private-dns-enabled # what endpoints exist, and in how many subnets each aws ec2 describe-vpc-endpoints --query "VpcEndpoints[].[ServiceName,VpcEndpointType,length(SubnetIds||\`[]\`)]" --output table
The endpoint's security group must allow HTTPS (TCP 443) from the resources that use it; a missing rule looks exactly like a missing endpoint. Gateway endpoints need no security group, but the route tables you list must be the ones your private subnets use. To confirm traffic took the endpoint, check that the NAT gateway's processed bytes drop, or that the service name resolves to a private IP from inside the VPC.
Ethan kept production's four endpoints in three zones, cut development's two to a single zone, and added the free DynamoDB gateway endpoint that had been missing all along. The next month's "VPC Endpoint Hours" line was about $102, and the NAT gateway line was lower again.
Many VPCs: shared endpoints vs one set per VPC
Once you run more than a handful of VPCs, the per-VPC model multiplies fast, and a central "shared services" VPC starts to look attractive. Here is the math for 20 VPCs that each need the same six interface endpoints:
- One set per VPC, two AZs each: 20 x 6 x 2 = 240 endpoint-AZ pairs, at about $7.30 each, is roughly $1,752 a month before data.
- One central set, three AZs: 6 x 3 = 18 pairs, roughly $131 a month, plus the cost of connecting the 20 VPCs to it. With Transit Gateway at about $0.05 per attachment per hour, 20 attachments add about $730 a month, plus $0.02 per GB through Transit Gateway.
So central endpoints save around $890 a month here if the VPCs need Transit Gateway only for this, and much more if they are already attached to it for other reasons, because then the attachment cost is already being paid. The trade-off is setup work: each spoke VPC needs Route 53 private hosted zones for the service names, shared or associated across accounts, so that names resolve to the central endpoints. Without that DNS step, the spokes simply keep using their NAT gateways.
Two cautions before you centralize. First, data now crosses Transit Gateway at $0.02 per GB in addition to the endpoint's $0.01, so a spoke that moves terabytes through one service may be cheaper with its own endpoint. Second, the endpoint policies on central endpoints apply to every spoke, so write them for the whole organization, not for one team. Many organizations end up with a mix: central endpoints for light, shared services such as Systems Manager and Secrets Manager, and local endpoints, plus the free S3 and DynamoDB gateways, in each VPC for the heavy traffic.
Endpoints in Terraform and CloudFormation: the defaults that bite
Most endpoints in real accounts are created by infrastructure code, and two defaults there cause most of the "we added endpoints and nothing changed" stories.
- Private DNS is off by default. In Terraform's
aws_vpc_endpoint,private_dns_enableddefaults to false, and CloudFormation'sPrivateDnsEnabledalso defaults to false. An interface endpoint created without it works only through its own long DNS name, so your SDKs keep calling the public name through NAT, and you pay for both. - Gateway endpoints need their route tables listed. Leave out
route_table_ids(Terraform) orRouteTableIds(CloudFormation) and you get an endpoint attached to nothing. Pass every private route table, including ones added later for new subnets.
# Terraform: one free gateway endpoint and one interface endpoint done right
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.us-east-1.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = aws_route_table.private[*].id
}
resource "aws_vpc_endpoint" "logs" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.us-east-1.logs"
vpc_endpoint_type = "Interface"
subnet_ids = var.env == "prod" ? aws_subnet.private[*].id : [aws_subnet.private[0].id]
security_group_ids = [aws_security_group.endpoints.id]
private_dns_enabled = true
}
The subnet_ids line shows the cheapest habit you can build into code: one subnet, and therefore one AZ, outside production; all zones in production. Across a dozen endpoints and several environments, that single conditional is often worth more each month than any other networking change you will make.
Tag every endpoint with its environment and owner in the same code, so the Cost Explorer grouping described above works from day one rather than after someone asks why the bill grew.
Does your Lambda function even need to be in a VPC?
A surprising number of endpoint bills come from Lambda functions that never needed a VPC. A function outside a VPC reaches S3, DynamoDB, SQS and every other AWS service over AWS's own network with no NAT gateway and no endpoints, and costs nothing extra for that access. You only need to attach a function to a VPC when it must reach something that lives inside one, such as an RDS database, an ElastiCache cluster or an internal load balancer.
Once a function is in a VPC, it loses that free route: every AWS service it calls now needs either a NAT gateway or an endpoint. So before you add endpoints for a function, ask whether it needs the VPC at all. If it only talks to DynamoDB and S3, take it out of the VPC and both the NAT path and the endpoint question disappear. If it needs the database and AWS services, the free gateway endpoints for S3 and DynamoDB plus one or two interface endpoints (often Secrets Manager for the database password) are usually enough. Our Lambda without internet guide covers the symptoms when one is missing.
Jake had two such functions: one resized images in S3, and one wrote order events to DynamoDB. Neither touched the database. Ethan moved both out of the VPC in an afternoon, and the endpoints he had been about to create for them were never needed.
For IT admins: endpoint governance
- Bake S3 and DynamoDB gateway endpoints into every VPC template.
- Standardize endpoint sets per workload type (ECS, EKS, SSM, Bedrock) instead of creating them ad hoc.
- Apply endpoint policies that limit endpoints to your organization's resources, for example with
aws:ResourceOrgID. - Tag endpoints with owner and environment, and alarm on endpoint hours in Cost Explorer or Budgets.
- Review quarterly for endpoints with no traffic and remove them.
- Decide where endpoints live in a multi-account setup. Either every VPC gets its own set (simple, costs more) or a networking account hosts shared endpoints (cheaper at scale, needs Transit Gateway and shared private hosted zones). Pick one model and write it down.
A useful quarterly check is a list of every interface endpoint with its zone count and last month's processed bytes. An endpoint with near-zero bytes for a full quarter is either a leftover or a service nobody calls from that VPC any more.
Frequently asked questions
How much does a VPC endpoint cost?
Gateway endpoints for S3 and DynamoDB are free. Interface endpoints cost about $0.01 per hour for each AZ they are enabled in, plus $0.01 per GB processed for the first petabyte a month in US East.
Are gateway endpoints free?
Yes. Gateway endpoints have no hourly or data processing charges.
What is AWS PrivateLink?
The technology behind interface endpoints. It places network interfaces with private IPs in your subnets so you can reach AWS services, partner services or your own services privately.
What is the difference between a gateway endpoint and an interface endpoint?
A gateway endpoint is a free route table target for S3 and DynamoDB. An interface endpoint is a paid network interface in your subnets that works for most services and can be reached from on premises and other networks.
How much does one interface endpoint cost per month?
About $7.30 per AZ per month before data, so about $21.90 for three AZs, plus $0.01 per GB processed.
Is a VPC endpoint cheaper than a NAT gateway?
Per GB, yes: $0.01 against about $0.045. Including the hourly charge, an interface endpoint in three AZs pays for itself at roughly 625 GB a month, and immediately if it lets you remove the NAT gateway.
Do I need a VPC endpoint for S3?
For private subnets, yes: the free gateway endpoint keeps S3 traffic off the NAT gateway. Use an S3 interface endpoint only for access from on premises or other networks.
Does a VPC endpoint charge when idle?
Interface endpoints do: the hourly charge runs for every hour they exist in each AZ. Gateway endpoints do not charge at all.
Which VPC endpoints does ECS Fargate need without a NAT gateway?
ecr.api and ecr.dkr interface endpoints, the S3 gateway endpoint for image layers, a logs endpoint for awslogs, and secretsmanager or ssm if tasks read secrets.
Which endpoints does Systems Manager need?
ssm, ssmmessages and ec2messages interface endpoints, plus the S3 gateway endpoint for some features.
Can I share VPC endpoints between VPCs?
Yes, by placing interface endpoints in a central VPC, connecting VPCs through Transit Gateway or peering, and sharing private hosted zones for the service names.
Do VPC endpoints work across Regions?
Gateway endpoints work only in their own Region. Some services support cross-Region PrivateLink connectivity for interface endpoints, with inter-Region data transfer charges.
Why is my VPC endpoint not working?
Common causes are a security group that blocks TCP 443, private DNS turned off, a gateway endpoint missing from the subnet's route table, or an endpoint policy that denies the request.
How do I see what VPC endpoints cost me?
Cost Explorer filtered to the VPC service and the VpcEndpoint usage types shows endpoint hours and data processed.
Can I publish my own service with PrivateLink?
Yes. Put it behind a Network Load Balancer, create a VPC endpoint service, and let other VPCs or accounts connect with interface endpoints.
Does a VPC endpoint cost money?
Interface endpoints do: about $0.01 per hour per AZ plus $0.01 per GB. Gateway endpoints for S3 and DynamoDB cost nothing.
How much do ECR VPC endpoints cost?
The two ECR interface endpoints in three AZs cost about $43.80 a month before data. Image layers come from S3, so add the free S3 gateway endpoint and most of the bytes cost nothing.
Who pays for a PrivateLink endpoint service?
Consumers pay their interface endpoint hours and data processing. The provider pays for the Network Load Balancer and the service behind it.
Where do I see VPC endpoint charges in Cost Explorer?
Filter the service to Amazon Virtual Private Cloud and group by usage type. Look for usage types containing VpcEndpoint-Hours and VpcEndpoint-Bytes.
Are centralized VPC endpoints cheaper?
Often, once you have many VPCs: one shared set replaces dozens of copies. Add Transit Gateway attachment and per-GB charges, plus private hosted zones for DNS, before deciding.
Is Terraform private_dns_enabled on by default?
No. It defaults to false, as does CloudFormation's PrivateDnsEnabled. Set it to true on interface endpoints or clients keep using the public names.
Is there a VPC endpoint pricing calculator?
Yes, the AWS Pricing Calculator has a VPC section for interface endpoints. Quick math: about $7.30 per endpoint per AZ per month, plus $0.01 per GB.
Why is traffic still going through my NAT gateway after adding endpoints?
Usually the gateway endpoint is missing from a private subnet's route table, the bucket is in another Region, private DNS is off, or custom DNS servers ignore the private zones.
Do VPC endpoints need DNS hostnames enabled?
Private DNS for interface endpoints needs both DNS support and DNS hostnames enabled on the VPC.
Do interface endpoints need a security group?
Yes. The endpoint's security group must allow inbound HTTPS from the clients that use it.
For readers preparing for an AWS certification
We have been covering AWS certifications alongside our fixes, so here is a short extra for readers studying for one. If you only came for the fix, you already have it; feel free to skip this part.
Exams that test this topic: Solutions Architect – Associate (SAA-C03) • Solutions Architect – Professional (SAP-C03 from November 17, 2026) • Security – Specialty (SCS-C03).
Here are the exam-style questions this topic tends to raise, with the reasoning you need to answer them:
1. Instances in private subnets send large volumes of data to S3 through a NAT gateway. What is the cheapest change?
Add an S3 gateway endpoint to the private route tables. Gateway endpoints have no hourly or data charges.
2. Which two services support gateway VPC endpoints?
Amazon S3 and Amazon DynamoDB.
3. On-premises servers connected over Direct Connect must reach S3 privately. Which endpoint type works?
An S3 interface endpoint (AWS PrivateLink). Gateway endpoints cannot be reached from on premises.
4. ECS tasks on Fargate in private subnets with no NAT gateway must pull images from ECR. Which endpoints are needed?
Interface endpoints for ecr.api and ecr.dkr, plus the S3 gateway endpoint for image layers, and a CloudWatch Logs endpoint if tasks use awslogs.
5. A company must stop instances from copying data to S3 buckets outside its organization. What enforces this at the network edge?
An endpoint policy on the S3 endpoint with a condition on aws:ResourceOrgID.
6. A team wants to offer its service privately to hundreds of customer VPCs with overlapping CIDR ranges. What should it use?
A VPC endpoint service (AWS PrivateLink) behind a Network Load Balancer. Consumers connect with interface endpoints, so no peering or CIDR planning is needed.
7. How are interface endpoints billed?
Per hour for each Availability Zone the endpoint is enabled in, plus a per-GB data processing charge.
8. Systems Manager Session Manager must work on instances with no internet access. Which interface endpoints are required?
ssm, ssmmessages and ec2messages.
Exam codes and dates change often. Our AWS certification changes page keeps track of what is current.
Jake now reads the "VPC Endpoint Hours" line as a sign that things are working, not as a mystery. He also has a rule for any new line on the bill: find the line it replaced. Usually there is one.
📌 If you keep one line from this page
Gateway endpoints for S3 and DynamoDB are free, interface endpoints cost about $0.01 per hour per AZ plus $0.01 per GB, and against a NAT gateway's $0.045 per GB they pay off at a few hundred GB a month or as soon as they let you drop NAT altogether.
$7.30 per AZ per month · fewer AZs in dev · delete idle endpoints · security group must allow 443.
Revision note. Written October 18, 2026. "A penny saved is a penny earned," the proverb says; a gateway endpoint saves the penny before you even notice it was being spent.