VPN memory use on OpenWrt: measured on 128 MB
What a VPN adds to a 128 MB OpenWrt router: RAM held by a userspace client and by OpenVPN, the WireGuard kernel module, and how to read free.
Key takeaways
- 4.2 to 4.3 MB of resident memory is what the ForestVPN router client process held for 120 seconds in its tunnel-core shape on a 128 MB OpenWrt 25.12.5 virtual machine.
- OpenVPN (openvpn-openssl 2.7.7) held 5.3 to 5.5 MB of resident memory as a process, and its tun and ovpn kernel modules sit outside that figure.
- Kernel WireGuard has no process at all: its cost is the 61440-byte wireguard module plus helper modules, and the interface itself moved MemAvailable by less than the run-to-run noise.
- MemAvailable on the guest drifted by several MB with nothing of ours running, so three alternating cycles are the evidence and no single before-and-after pair is.
On this page (5)
On a small OpenWrt virtual machine, the ForestVPN router client process and OpenVPN each held a few megabytes of resident memory. Kernel WireGuard has no process to measure at all.
Most "OpenWrt VPN memory" searches ask whether a small router has room for a VPN. None of the results we could read gives a measured per-component figure, so this page gives one table. Each number says which image, memory cap, package version and day it came from. We also say what the run could not see.
How much memory does a VPN use on 128 MB OpenWrt?
On one 128 MB virtual machine, each userspace piece held between 4.2 and 5.5 MB resident, and the kernel pieces were measured separately because a process table cannot show them. Here is what ran, and under what conditions.
How this was tested
- Product
- OpenWrt 25.12.5 r33051-f5dae5ece4, x86/64, kernel 6.12.94, apk-tools 3.0.5
- Version
- fv 0.3.10 (our client binary built from source), openvpn-openssl 2.7.7-r1, kmod-wireguard 6.12.94-r1 with wireguard-tools 1.0.20260223-r1
- System
- QEMU virtual machine, 128 MB, MemTotal 107760 kB, TCG emulation
- Checked
- Runs
- 3
Not tested
The run was on 2026-10-16 with LuCI (OpenWrt's web interface), uhttpd, dnsmasq and the SSH server running. The only WAN traffic was package downloads from the OpenWrt feed and unanswered handshake attempts to the lab gateway 10.0.2.2 (OpenVPN on port 1194, WireGuard on port 51820, and the fv peer). The client was a static binary built from the same source and with the same features as the router package, not taken from the installed package. No account, no ForestVPN server and no tunnel peer was reached; a packet capture on the WAN side during the fv up run found no packet naming ForestVPN. The OpenVPN client pointed at a port nobody serves, with dummy credentials and a dummy fingerprint. The WireGuard interface had one peer that never answers. Not measured: a connected tunnel under load, CPU, flash use, throughput, any ARM or MIPS device, any real router.
| Component | What was running | VmRSS (kB) | RssAnon (kB) | RssFile (kB) | Kernel side |
|---|---|---|---|---|---|
ForestVPN client, fv run | Tunnel core, one peer that never answers | 4192 to 4320 | 928 | 3264 to 3392 | Interface fvpn0 |
ForestVPN client, fv up | Account agent, catalog unreachable | 4764 to 4804 | 940 to 980 | 3824 | None measured |
| OpenVPN, openvpn-openssl | Client, server never answers | 5296 to 5456 | 1332 to 1336 | 3956 to 4116 | tun 45056 bytes, ovpn 53248 bytes |
| Kernel WireGuard | Interface wg9, one peer that never answers | No process | None | None | wireguard 61440 bytes plus helper modules |
For scale, the same guest held uhttpd at 1664 kB, rpcd at 1920 kB, dnsmasq at 1200 kB and dropbear at 888 kB of resident memory after boot.
Show the data
| dropbear | 888 kB |
|---|---|
| dnsmasq | 1200 kB |
| uhttpd | 1664 kB |
| rpcd | 1920 kB |
| fv run | 4320 kB |
| fv up | 4864 kB |
| openvpn | 5456 kB |
Both ForestVPN rows are one binary in two shapes:
fv runis the tunnel core.fv upis the account agent that registers the router with ForestVPN.
An earlier run on 2026-10-04, on x86_64 OpenWrt 24.10 with an older build, printed about 4.1 to 4.2 MB for fv run and 4.3 MB for fv up (that run recorded 4104 to 4168 kB and 4308 kB).
Today the run shape sits at about the same size, while the up shape rose from 4.3 to 4.8 MB. The growth is in file-backed pages: RssFile went from 3376 to 3824 kB, and the binary from 4,229,592 to 4,717,984 bytes.
What did the ForestVPN client hold over 120 seconds?
Our client, the ForestVPN router client (package forestvpn, binary fv, interface fvpn0), held 4.2 MB resident at ten seconds and 4.3 MB from twenty seconds on, flat to the end of the two minutes. The anonymous part, the memory only this process owns, stayed at 928 kB for the whole window.
Most of the rest, about 3.3 MB, is file-backed, and that part is mostly the program itself. The kernel documentation defines RssFile as the resident file mappings, and the client is a single static binary of 4,717,984 bytes, so most of its resident size is the file mapped into memory. That is why a VmRSS figure overstates what the process holds privately.
MemAvailable, the kernel's estimate of memory a new program could use without swapping, gives one noisy pair and no more. It read:
- 22384 kB just before the client started.
- 17664 kB ten seconds after, a drop of about 4.7 MB.
- 19492 kB at 120 seconds, 2.9 MB below the start.
We dropped no caches for these samples and ran no cycles, so that pair can neither confirm nor refute the RssAnon reading.
The fv up shape stayed at 4.8 MB, with a peak of 4864 kB. Its anonymous part crept from 940 to 980 kB while it retried an unreachable catalog.
One caveat: we measured a build from the same source and features, not the installed package, so treat these numbers as those of the binary.
How much memory does OpenVPN use on OpenWrt?
OpenVPN's process held 5.3 to 5.5 MB resident across three start-and-stop cycles: 5456, 5296 and 5344 kB. About 1.3 MB of that was anonymous, memory the process wrote to itself, and 4.0 to 4.1 MB was file-backed.
OpenVPN is a separate userspace daemon that opens a TUN device, a virtual network interface the kernel hands to a program, as the OpenVPN reference manual describes.
Installing openvpn-openssl pulled in libopenssl3 and the kernel modules tun and ovpn. Those modules never show up in the process's VmRSS.
It never finished a TLS handshake here. A session that has authenticated, pushed routes and carried traffic may well hold more, and we make no claim about it.
IVPN's OpenWrt guide, written for OpenWrt 23.05.5, walks through a similar OpenVPN setup and gives no memory figure, which is the gap this table fills for one configuration.
What does kernel WireGuard cost if it has no process?
Kernel WireGuard costs a module and an interface, and on this guest the interface's cost was smaller than the noise.
We installed kmod-wireguard and wireguard-tools with apk, OpenWrt's package manager since 25.12 (opkg on 24.10 and older), loaded the module before the first cycle so it was present in both states, then switched the wg9 interface on and off three times. The module's own cost comes from its lsmod size, given below. With no process to read, MemAvailable is the only gauge, so each state is the median of three samples.
| Cycle | OpenVPN off (kB) | OpenVPN on (kB) | Drop (kB) | wg off (kB) | wg interface on (kB) | Drop (kB) |
|---|---|---|---|---|---|---|
| 1 | 42384 | 35268 | 7116 | 43776 | 42000 | 1776 |
| 2 | 38928 | 32036 | 6892 | 42708 | 40612 | 2096 |
| 3 | 39672 | 35404 | 4268 | 41480 | 40896 | 584 |
OpenVPN's drop of 4.3 to 7.1 MB is the same order as its 5.3 MB resident size, within this run's noise.
The WireGuard drops of 0.6 to 2.1 MB cannot be told apart from the baseline, which slid from 43776 kB to 41480 kB across the three cycles with no change on our side. The module itself is 61440 bytes, with ChaCha20-Poly1305 and Curve25519 helper modules beside it, and the WireGuard install page lists OpenWrt among its platforms.
Both are small. This run cannot rank them to the megabyte.
Why does MemAvailable on OpenWrt look so low?
Because the kernel, the page cache, the in-memory filesystems and the router's own daemons are already in memory before any VPN arrives. Our guest reported 107760 kB total and 25908 to 26076 kB available in three readings after boot, with LuCI, uhttpd, dnsmasq and the SSH server running. /tmp is a tmpfs, so files written there sit in RAM too.
A reading of 26 MB available does not mean the rest is wasted. It is the kernel's estimate of what a new program could use without swapping.
The baseline moved by several MB with nothing of ours running: between the OpenVPN cycles, the off state alone swung from about 39 to 42 MB. The after-boot reading and the cycle run's off states come from different boots and conditions (caches were dropped before each cycle sample), and this run does not explain the gap. One pair of readings proves nothing here, which is why the cycles above are the evidence.
How do you read free, MemAvailable and VmRSS on OpenWrt?
Read MemAvailable for the whole system and VmRSS for one process, and expect them to disagree. The kernel documentation describes MemAvailable as an estimate of memory available for starting new applications without swapping, computed from free memory, reclaimable slab, file cache and the low watermarks. free prints the same figure in its available column.
By that documentation a process's VmRSS is the sum of RssAnon, RssFile and RssShmem. Shared file pages count in every process that maps them, and kernel modules count in none.
These commands, or close to them, ran on the guest. BusyBox's pidof can return several PIDs, hence the cut.
free
grep -E 'MemTotal|MemFree|MemAvailable|Buffers|Cached' /proc/meminfo
p=$(pidof uhttpd | cut -d' ' -f1)
grep -E 'VmHWM|VmRSS|RssAnon|RssFile' /proc/$p/status
lsmod | grep -E '^(wireguard|tun|ovpn) 'For a before-and-after comparison, flush the page cache first, as we did before every MemAvailable sample in the on/off cycles, and repeat in cycles.
sync; echo 3 > /proc/sys/vm/drop_cachesCan a 128 MB router run a VPN client?
On memory alone, our run says the client process is a small part of the guest's memory, and OpenVPN is close to it in size. That is one image, on x86 emulation, with the router doing nothing else.
The run cannot answer two things.
Smaller router: we ran nothing on 64 MB, so there is no verdict here, and ForestVPN's install help lists 128 MB for its MIPS builds and says the installer refuses a router with too little memory or storage before changing anything.
Busier router: one also running a large blocklist, a second VPN or extra LuCI apps will have less room than our guest did.
Memory is also not the only limit. Flash decides whether a package installs at all, and CPU decides how fast it moves packets. We have a dated throughput comparison for other hardware in our CPU-cycle post and none for OpenWrt. For the wider choice between a hand-built tunnel and a managed one, see the OpenWrt WireGuard guide; the MikroTik versus OpenWrt comparison covers the other router platform.
How much memory does a VPN use under load, or on ARM and MIPS routers?
This run cannot say: a connected tunnel under load, CPU, flash use and throughput were not measured, and neither was any real router, any ARM or MIPS CPU, or the installed forestvpn package.
The arm64 image of this release did not boot at the same memory cap in our lab, so there is no arm64 figure and the x86 numbers must not be carried over to one. A binary's memory use differs by architecture, and QEMU's emulated CPU and kernel allocation are not a router's.
Every peer and server in the run was unreachable on purpose, so no handshake completed. Memory during a live, busy tunnel is the number most readers want, and it is the one missing. If a tunnel stops carrying traffic on your router, the no-internet troubleshooting post is the better place to start.
Which VPN should you run on a small OpenWrt router?
Pick on the work each one leaves you, because all three were small next to the guest's total memory. Kernel WireGuard adds a module you may already have installed, and the two userspace programs both fit comfortably in this run.
What differs is the job around the tunnel. A hand-built WireGuard or OpenVPN setup needs its own firewall zone and kill switch; the ForestVPN client brings its own, described on the kill switch page, with its limits on the trust and limits page and the device modes page.
The kill switch is never absolute: it covers the devices ForestVPN protects, not the router's own traffic and not devices on Direct, and under Standard protected devices go direct in the cases that page lists. Its help page says it is not yet verified on hardware as a whole, and the install steps are not yet verified on hardware. Install availability for your firmware is on the install page.
Questions and answers
How much RAM does a VPN need on OpenWrt?
In our run on a 128 MB OpenWrt 25.12.5 virtual machine, the VPN processes held between about 4 and 5.5 MB of resident memory each, and the kernel WireGuard module added no process. Treat that as one data point for one image on x86 emulation, not as a rule for every router.
Can a 128 MB router run a VPN client?
The memory the client and OpenVPN held in our run is small next to 128 MB. Whether a particular router has room also depends on flash storage, your other packages and the CPU, which we did not measure.
Is 64 MB enough for a VPN on OpenWrt?
We did not run anything on 64 MB, so this article gives no verdict for it. ForestVPN's own router help states 128 MB for the MIPS builds.
Why does MemAvailable on OpenWrt look so low?
Right after boot, with LuCI, uhttpd, dnsmasq and the SSH server running, our 128 MB guest reported about 26 MB available out of 107760 kB of total memory. The kernel, its caches and the in-memory filesystems take their share before any VPN is installed.
How do I measure a process's memory on OpenWrt?
Read /proc/PID/status and look at VmRSS, RssAnon and RssFile. BusyBox pidof can print more than one PID, so cut the first. For kernel modules that have no process, compare MemAvailable in /proc/meminfo with and without the module, several times.
How much memory does OpenVPN use compared with WireGuard on OpenWrt?
In this run the OpenVPN process held 5.3 to 5.5 MB resident and kernel WireGuard had no process, only a 61440-byte module and helpers. That is a statement about one lab configuration; it is not a general ranking of the two.
What does a connected tunnel under load use?
We did not measure it. Every run here used a peer or server that never answered, so no handshake completed and no traffic flowed.
Sources
- The /proc filesystem (Linux kernel documentation) (read October 16, 2026)
- WireGuard installation (read October 16, 2026)
- OpenVPN 2.6 reference manual (read October 16, 2026)
- IVPN: OpenWrt OpenVPN setup guide (read October 16, 2026)
How this was made
Drafted with AI assistance from a lab run we made on 2026-10-16 on a 128 MB OpenWrt 25.12.5 virtual machine, with the raw numbers kept, checked by automated gates and an editor.