ADB / Fastboot

ADB Port Forwarding and Reverse Tunneling Explained

Published: June 30, 2026 Applies to: Windows 10/11, macOS, Linux — Android 4.0 through Android 15

ADB is not just a command channel — it is also a network tunnel. The adb forward and adb reverse commands route TCP traffic between your PC and Android device through the ADB connection itself, bypassing the need for both ends to be on the same network or have open firewall ports between them.

What does adb forward do?

Port forwarding redirects traffic from a port on your PC to a port on the Android device. When you run adb forward tcp:8080 tcp:8080, any process that connects to localhost:8080 on your PC has its traffic transparently tunneled through ADB and delivered to port 8080 on the Android side. The device does not need a routable IP address from the PC's perspective — the ADB transport carries the data whether you are connected via USB or wireless ADB.

A typical scenario is a developer tool running on the PC that needs to communicate with a server process embedded inside an Android app. Without port forwarding, the PC would need to know the device's IP address and the device's firewall would need to allow inbound connections on that port. With adb forward, none of that is necessary:

adb forward tcp:8080 tcp:8080
# Any connection to http://localhost:8080 on the PC
# now reaches the HTTP server running on the Android device

What does adb reverse do?

Reverse tunneling goes in the opposite direction: a port on the Android device is forwarded to a port on your PC. When any process on the device connects to localhost:8081, ADB intercepts the connection and routes it to port 8081 on your development machine. This is exactly how React Native's Metro bundler works during development — the JavaScript bundle loader in the app calls localhost:8081, which reverse-forward delivers to the Metro server running on the PC:

adb reverse tcp:8081 tcp:8081
# Metro bundler on the PC is now reachable from the device
# at localhost:8081 as if it were a local service

A clean mental model: adb forward is PC-to-device (the PC initiates), and adb reverse is device-to-PC (the Android app initiates). Both work over the same ADB transport so no additional firewall rules or network configuration is needed on either end.

How do I list and remove forwarding rules?

Active rules accumulate in the ADB server's memory for the lifetime of the connection. To see what is currently forwarded, run:

adb forward --list
adb reverse --list

Each output line shows the device serial number, the local socket specification, and the remote socket specification. To remove a single rule by its local port:

adb forward --remove tcp:8080

To clear every forward rule at once for the connected device:

adb forward --remove-all

The same flags apply identically to adb reverse. When targeting a specific device in a multi-device setup, prepend the -s flag: adb -s 192.168.1.42:5555 forward --list.

What is a localabstract socket and when would I use it?

Besides TCP ports, ADB forwarding supports Unix abstract domain sockets through the localabstract: prefix. Abstract sockets are kernel-only constructs — they have no file on disk, they live only in the kernel's network namespace, and they are addressed by an arbitrary string name rather than a port number. Many Android system components and debuggers use abstract sockets internally because they are faster than TCP loopback and do not require any port number allocation.

The forwarding syntax replaces the port number with the socket name:

adb forward tcp:9229 localabstract:com.example.app.inspector

This is the mechanism behind JavaScript debugger attachment for Android WebViews. Chrome DevTools exposes each WebView's inspector as a localabstract socket, and the chrome://inspect page uses a forwarded TCP port to connect. To discover what abstract sockets a running app has open, inspect the kernel's socket table:

adb shell cat /proc/net/unix | grep com.example.app

Entries marked with type 0001 and a name beginning with @ are abstract sockets. The name without the @ prefix is what you pass to localabstract:.

How do I test a website on an Android browser while it runs on my PC?

If you are running a local development server on your PC (say, on port 3000) and want to view it in the Android browser without exposing the server to the network, use adb reverse:

adb reverse tcp:3000 tcp:3000

Now open http://localhost:3000 in the browser on the Android device. The Android browser connects to its own localhost, which ADB reverse-tunnels to port 3000 on the PC. This works for HTTPS too, though the browser will show a certificate warning for self-signed certs — you will need to add a security exception or use a tool like mkcert to generate a locally trusted certificate.

The same technique works for any protocol that runs over TCP: gRPC servers, GraphQL endpoints, WebSocket servers, and local mock APIs all become accessible on the device through a single reverse command. There is no practical limit to how many rules you can set up simultaneously, so you can forward multiple ports at once for complex development setups.

Do forwarding rules survive a disconnect or reboot?

No. All forward and reverse rules for a device are automatically cleared whenever the ADB connection drops — unplugging the USB cable, the device falling off wireless ADB, a reboot, or even a brief disconnection caused by the screen locking. This trips up many developers: they set up rules, the device sleeps, and their toolchain silently stops working.

The fix is to treat port rules as ephemeral setup steps and restore them in your project's startup script. A small shell script with adb wait-for-device at the top blocks until a device is ready, then applies rules reliably:

#!/bin/sh
adb wait-for-device
adb reverse tcp:8081 tcp:8081
adb reverse tcp:3000 tcp:3000
echo "Tunnels ready."

Run this script once at the start of a development session. If the device reconnects mid-session, run it again. The rules are cheap to set and take only a fraction of a second to apply.