Asia VPNAsiaVPNGet app
All posts

Self-Hosting a VPN on AWS Lightsail: About That 1 TB

4 min read

Every guide to self-hosting a VPN on AWS eventually hits the same wall: EC2 charges for outbound bandwidth from the first byte, and a VPN is nothing but outbound bandwidth. A few evenings of video and your $4 instance has produced a $30 bill.

Lightsail exists to solve exactly that. It is the same EC2 hardware underneath, wrapped in a flat monthly price with a transfer allowance bundled in. For a personal VPN that difference is the whole story.

There is a catch in how the allowance is counted, and it is specific to VPNs. We will get to it - it is the reason this post exists.

The plans

Every Linux plan includes an allowance, and the small ones are the interesting ones:

Price/moRAMvCPUSSDTransfer
$50.5 GB220 GB1 TB
$71 GB240 GB2 TB
$122 GB260 GB3 TB
$244 GB280 GB4 TB

WireGuard on the $5 plan will saturate far more bandwidth than the allowance gives you. RAM is not the constraint here and neither is CPU. Transfer is.

The catch: a VPN pays for every byte twice

This is the part that surprises people, and AWS documents it plainly enough that there is no excuse for being surprised: both inbound and outbound transfer count toward your allowance.

For a web server that barely matters - requests in are tiny, pages out are not. For a VPN it matters enormously, because a VPN is a relay. When you stream a 1 GB video through it:

  1. 1 GB arrives at the instance from the internet - inbound, counted.
  2. 1 GB leaves the instance for your phone - outbound, counted.

That is 2 GB against a 1 TB allowance for 1 GB of actual viewing. So the honest figure for the $5 plan is roughly 500 GB of real traffic per month, not 1 TB.

The overage rules are kinder than the counting rules. If you go over, AWS bills only the excess outbound - inbound overage is never charged - starting at $0.09/GB and varying by region. So blowing through the allowance by 100 GB of browsing costs you roughly $4.50, not $9. Annoying, not catastrophic.

Budget on the halved number and you will not get a surprise.

1. Create the instance

In the Lightsail console: Create instance → pick your region → Linux/UnixOS OnlyUbuntu 24.04 LTS.

Region is the one decision with real consequences. Pick the region closest to you, not to the sites you visit - you are adding a hop, and the cost of that hop is the round trip to the instance. For most of Southeast Asia that means Singapore (ap-southeast-1). Tokyo (ap-northeast-1) is often better from northern Vietnam, and it is worth testing both rather than assuming.

Lightsail generates an SSH key per region and offers it as a download. Take it - you cannot download it again later.

2. Attach a static IP

By default a Lightsail instance's public IP changes when you stop and start it, which will silently break every client profile you have handed out.

NetworkingCreate static IP → attach it to the instance.

A static IP is free while it is attached to an instance. It starts costing money the moment it is not - including when you delete the instance and leave the IP sitting in your account. Delete the IP too when you are done.

3. Open the port - in the right firewall

This is where most Lightsail setups stall. Lightsail has its own firewall, in the instance's Networking tab. It is not the EC2 security group you may have read about, and ufw on the instance is a third, separate layer.

For WireGuard, add an IPv4 rule:

  • Application: Custom
  • Protocol: UDP
  • Port: 51820

For OpenVPN, 1194/UDP. Note that each instance has two firewalls - one for IPv4 and one for IPv6 - and a rule added to one does nothing for the other. If you intend to reach the VPN over IPv6, add it in both places.

Leave SSH (22/TCP) alone. Locking yourself out of a cloud instance you cannot attach a monitor to is a bad afternoon.

4. Install the VPN

Nothing here is Lightsail-specific. Both of the usual scripts work unchanged:

# WireGuard, via PiVPN - despite the name it targets Ubuntu/Debian VPS fine
curl -L https://install.pivpn.io | bash

# or OpenVPN
curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh
chmod +x openvpn-install.sh
./openvpn-install.sh interactive

The full walkthrough for each is in the OpenVPN on DigitalOcean and PiVPN guides - the client management, profile handling and revocation are identical wherever the box lives.

When the installer asks for the public IP, give it the static IP, not whatever the instance reports internally. Lightsail instances sit behind NAT and see a private address on their own interface; a profile built from that address will connect to nothing.

5. Watch the meter

Metrics tab on the instance, or the account-level billing page. Lightsail shows transfer used against the allowance for the current month, which is the number you actually care about. Check it after the first week and extrapolate - that tells you within a month whether $5 is your plan or whether you want the $7 one.

What this actually gets you

The same trade as any self-hosted VPN, with one AWS-flavoured wrinkle.

You get predictable cost. That is the real argument for Lightsail over EC2: you know in advance what the month costs, and the failure mode of going over is a few dollars rather than an incident.

You do not get anonymity. One IP, used by you alone, registered to your AWS account and your card. A commercial VPN's privacy comes from the crowd sharing an exit address; a private instance has no crowd. On fingerprinting grounds a solo datacentre IP is more identifying than your home connection.

You do not get streaming. AWS ranges are on every geo-blocking list there is, and have been for years.

You do not get to stop patching. apt upgrade, unattended-upgrades, key-only SSH. A VPN server nobody maintains is worse than no VPN server. The first 30 minutes is the whole list, done once.

Self-host when you want a machine that is yours, in a region you chose, at a price you can predict. Use a commercial VPN when what you actually want is to disappear into a crowd on hotel Wi-Fi. Those are different problems and one box does not solve both.


Cover image by Growtika on Unsplash.

Keep reading