I built a Client VPN estimate in a spreadsheet last month, sent it to a client, and then revised it twice: once because I multiplied associations by subnets, and once because I used headcount instead of session data. The version that survived review rests on two hourly meters and a short list of side charges. You can rebuild it from the console and one log export, without a pricing calculator.

Two meters, and nothing else on the endpoint

AWS bills a Client VPN endpoint on association-hours and connection-hours. Association-hours tick for every target network attached to the endpoint, around the clock, whether or not anyone connects. Connection-hours tick per connected client, for as long as that session stays up.

MeterWhat increments itWhat does not change it
Association-hoursEach associated subnet or Transit Gateway attachment, per hour, 24/7 while attachedNumber of users, traffic volume
Connection-hoursEach active client session, per hourHow many subnets that client can reach

Two consequences fall straight out of that table. An endpoint with nobody on it still costs money, and one person running a laptop and a phone at the same time produces two connections.

Count associations in the console, not subnets in the VPC

Open VPC, then Client VPN endpoints, then your endpoint, then the Associations tab. Every row there is a subnet attachment, and that row count is your association multiplier. The number of application subnets sitting behind the VPC has nothing to do with it.

One association is enough to reach an authorized VPC network once the endpoint routes and authorization rules cover the destination. Extra associations buy Availability Zone resilience, not extra reach. A two-AZ design therefore doubles association-hours, while an eight-subnet application VPC multiplies nothing by eight.

Note the association type while you are on that page. A VPC-subnet association and a direct Transit Gateway association are different arrangements with different line items, so do not carry one model into the other's quote. And do not test the count by detaching things: removing the final target network terminates active sessions and blocks new connections until something is associated again.

Derive connection-hours from session data

Headcount is the wrong input, and it is wrong in both directions. Ten people who each keep three devices connected are thirty connections. A hundred people who each connect for twenty minutes a day produce nowhere near a hundred simultaneous sessions.

Client VPN connection logs record connect and disconnect events per client, which is exactly the pairing you need. Export a representative week, match the events, and total the durations:

connection-hours = sum of (disconnect_time - connect_time) per session
sessions         = one per client connection, not per person

Then correct for two habits. Sessions left connected through lunch, overnight or a laptop suspend that never tore down the tunnel still bill, and they are invisible in a headcount. Metering is also hourly, so budget a twenty-minute session as a full hour rather than assuming proportional billing; if the invoice comes in lower, treat it as margin rather than as a planning input.

Run the arithmetic with your Region's rates

Rates differ by Region, so pull them from the AWS VPN pricing page for the Region you are deploying into and paste them into the sheet as inputs. As an illustration only, take an association rate of $0.10 per hour and a connection-hour rate of $0.05, then price a 30-day month with two associations held all month and 100 people connecting for six hours on 20 workdays:

association-hours = 2 * 24 * 30     = 1,440
association fee   = 1,440 * 0.10    = 144.00

connection-hours  = 100 * 6 * 20    = 12,000
connection fee    = 12,000 * 0.05   = 600.00

Client VPN subtotal                 = 744.00

Now move one input at a time and watch which line reacts. Doubling the associations adds $144 here; doubling the average session length adds $600. That ratio usually settles the design argument for you: trim redundancy you cannot justify, or go after idle sessions, whichever number is larger. Write the Region and the rate date beside the result, because a quote without them cannot be reproduced six weeks later.

Add the charges the subtotal leaves out

The endpoint fee pays for the endpoint. Everything the traffic touches after that has its own meter, and those lines are where optimistic VPN estimates fall apart.

  • Internet egress for traffic that leaves through the endpoint, billed per GB.
  • Public IPv4 addresses, which carry their own hourly charge independent of the VPN.
  • CloudWatch Logs ingestion and storage for the connection logs you just exported.
  • Lambda invocations if you run a client-connect handler.
  • Directory Service or your SAML identity provider, if that is how users authenticate, plus ACM Private CA charges if you mint certificates there.
  • NAT Gateway hours and data processing, and Transit Gateway attachment hours plus data processing, whenever the path uses them.

None of these scale with the association count, which is why a per-user figure assembled only from endpoint fees looks fine on paper and then grows once real traffic appears. Put them on separate rows even when you have to estimate them, so the reader can see which parts are measured and which are guesses.

Check the sheet before you send it

Four checks catch the errors I actually made: the association count matches the Associations tab exactly, connection-hours came from paired log events rather than a headcount, the Region and rate date are written down, and every side charge has its own row. If any of the four is missing, you have a guess with formatting.

Pull the log export first. It is the one input you cannot reconstruct from memory later, and it also tells you whether the idle-session problem is worth fixing before the first invoice arrives.

ተዛማጅ ጽሑፎች