AWSCost

AWS cost · Client VPN

AWS Client VPN costs $73/month per subnet

Client VPN has a per-connection charge, so it reads like a pay-for-what-you-use service. It is not. Most of the bill is the subnet you associated with the endpoint, and that charge runs every hour whether anyone connects or not.

Each associated subnet costs $0.10/hour in us-east-1 - about $73/month. Associate two for high availability and an endpoint nobody uses is $146/month. An endpoint with no associations bills nothing at all, which is why disassociating beats deleting.

What actually bills?

Two separate meters, and only one of them tracks usage:

WhatCostNote
One associated subnet~$73.00/month$0.10/association-hour, us-east-1
Two associations, the usual HA setup~$146.00/monththe charge is per subnet, not per endpoint
Each connected client$0.05/houronly while somebody is actually connected
An endpoint with no associations$0.00the endpoint alone bills nothing

AWS names the unit precisely in its own price list: a Client VPN Endpoint Association Hour. The association is what you are buying. The console never shows it as a line of its own.

Why an abandoned endpoint is invisible

Client VPN is usually built for something with an end date - a migration, an audit, a contractor who needs access for six weeks. The work finishes and people stop connecting. Nothing else changes: the endpoint stays available, the certificates stay valid, and the bill stays the same.

It is the same shape as a NAT gateway passing no traffic - a fixed hourly charge on a resource whose whole job is to sit and wait.

How to find one

List the endpoints, count the associations that are actually in the associated state, then check whether anyone connected. Read the peak rather than the average - a VPN used one hour a week averages near zero and is still in use:

# every Client VPN endpoint in the region
aws ec2 describe-client-vpn-endpoints \
  --query 'ClientVpnEndpoints[?Status.Code==`available`].{Id:ClientVpnEndpointId,Vpc:VpcId,Desc:Description}' \
  --output table

# the subnets that bill - only "associated" is charged
aws ec2 describe-client-vpn-target-networks \
  --client-vpn-endpoint-id cvpn-endpoint-0123456789abcdef0 \
  --query 'ClientVpnTargetNetworks[?Status.Code==`associated`].{Association:AssociationId,Subnet:TargetNetworkId}' \
  --output table

# peak connected clients over 14 days - a flat 0 means nobody connected
aws cloudwatch get-metric-statistics \
  --namespace AWS/ClientVPN --metric-name ActiveConnectionsCount \
  --dimensions Name=Endpoint,Value=cvpn-endpoint-0123456789abcdef0 \
  --start-time 2026-07-29T00:00:00Z \
  --end-time   2026-08-12T00:00:00Z \
  --period 86400 --statistics Maximum

One trap if you go looking in the API yourself: the endpoint object carries an inline list of associated networks, and that field is deprecated. The target-networks call above is the only source that tells the truth about what you are paying for.

What the fix costs

Deleting the endpoint deletes the access path with it. Rebuilding one means re-issuing certificates, re-authorizing the networks and pushing a new configuration file to every client - not a five-minute job, and not something to discover during an incident.

So make the reversible move first. Disassociate the subnet: the hourly charge stops, and the endpoint, its certificates and its authorization rules stay exactly where they are. If the VPN is deliberate break-glass access nobody has needed yet, that keeps it without paying to keep it warm.

# MUTATING - stops the association charge, keeps the endpoint intact
aws ec2 disassociate-client-vpn-target-network \
  --client-vpn-endpoint-id cvpn-endpoint-0123456789abcdef0 \
  --association-id cvpn-assoc-0123456789abcdef0

Re-associating later is one command, and clients keep working with the configuration they already have.

Want to know whether you are paying for a VPN nobody connects to? Connect your account read-only and see what it is wasting, in real dollars.

Connect your AWS

The role can only read - Get, Describe, List, nothing else. Read the exact permissions before you deploy it, and delete the stack whenever you want.

Frequently asked questions

How much does AWS Client VPN cost?+

$0.10 per hour for every subnet associated with the endpoint - about $73/month each in us-east-1 - plus $0.05 per hour for each connected client. The association charge runs whether anyone connects or not, so a two-subnet endpoint nobody uses is about $146/month.

Does a Client VPN endpoint cost money with nobody connected?+

Yes, if it has a subnet associated. The connection charge stops when the last client disconnects, but the association charge is billed by the hour for as long as the association exists. Zero connected clients is not zero cost.

Can I stop the charge without deleting the endpoint?+

Yes, and this is the part most people miss. An endpoint with no associated subnets bills nothing. Disassociating the subnet stops the meter while the endpoint, its certificates and its client configuration all survive - so re-enabling access later is one command instead of a rebuild.

Why is my Client VPN bill higher than one endpoint?+

Because the unit of cost is the subnet association. Associating a second subnet for high availability doubles the hourly charge, and the console shows one endpoint either way. Count associations, not endpoints.

Do associations that failed or are still setting up get charged?+

Only an association in the associated state bills. One still associating, or one that failed, is not charged - so read the status rather than counting rows.

How do I tell whether anyone uses the VPN?+

Look at the peak of the ActiveConnectionsCount metric over two weeks, not the average. Someone who connects for an hour a week averages close to zero but is genuinely using it. If the peak is zero across the whole window, nobody connected at all. If the metric returns nothing, treat that as unknown rather than as idle.

Related cost breakdowns

More AWS cost breakdowns