🔥 LAUNCH SALE — up to +60% bonus traffic · Residential from $0.67/GB · code BACK15 Claim →
Log in Get proxies
PyProxy is back — buy residential, ISP, mobile & datacenter proxies directly, from $0.67/GB. Launch bonus up to +60%.
Guide · multi-instance emulators

Setting a proxy IP for multiple Android emulators

Running ten emulators behind one address defeats the purpose of running ten emulators. This is the practical way to give each instance its own exit IP — the command-line flag, the in-emulator setting, per-instance BlueStacks and LDPlayer, and the local-forwarder pattern that stops falling over once you pass three or four instances.

Why one address per instance is the whole point

An emulator instance is a device profile. It has its own Android ID, its own installed apps, its own logged-in accounts, its own cookie jar. What it does not have by default is its own network identity: every instance on the machine leaves through the host's single public IP.

To anything looking at the other end, that is one household with ten devices behaving in an unusually coordinated way. Give each instance its own residential exit address and each profile instead looks like a separate household on a separate consumer line. That is the difference the proxy is buying you — not anonymity in the abstract, but separation between profiles.

Two consequences follow, and they drive every technical decision below. First, the mapping between instance and address must be stable: an instance that changes address halfway through a session looks worse than one that never had a proxy at all. Second, the mapping must be distinct: two instances sharing an address are one profile as far as the target is concerned.

The Android Studio emulator: the -http-proxy flag

The AOSP emulator takes a proxy on the command line, which makes it the cleanest place to start because the setting belongs to that launch of that AVD and nothing else:

emulator -avd Pixel_6_API_34 -http-proxy http://127.0.0.1:20001
emulator -avd Pixel_6_API_34_b -http-proxy http://127.0.0.1:20002

Each command is a separate instance with a separate upstream. List your AVDs first with emulator -list-avds; note that one AVD cannot be booted twice concurrently unless you launch it in read-only mode, so in practice you clone the AVD once per profile.

The documented form of the flag includes credentials — http://user:pass@host:port — and this is where people lose an afternoon. Support for the authenticated form varies between emulator builds, and a password containing @, : or # breaks the parser silently: the emulator boots, the app has no network, and nothing in the log says why. If you are going to authenticate, test one instance in isolation before scripting ten.

The flag only affects HTTP and HTTPS traffic from the emulated system. It does not tunnel arbitrary sockets, and DNS handling depends on the build. Treat it as an app-level proxy, not a VPN.

Setting it from inside the running instance

The same emulator exposes the proxy in its own UI: the three dots beside the emulator window open Extended controls, and under Settings → Proxy you can clear "Use Android Studio HTTP proxy settings" and enter a host, port, username and password by hand. This is per-instance and survives a reboot of that instance, which makes it convenient when you are setting up profiles interactively rather than from a script.

You can also set it inside Android itself, which is the setting that actually matters to most apps: long-press the connected network under Settings → Network & internet → Internet (the emulator's network is usually called AndroidWifi), choose to modify it, and set a manual proxy host and port. On many builds this field accepts no credentials at all, which is another reason the forwarder pattern below exists.

BlueStacks and LDPlayer, per instance

Both are built around cloning. In BlueStacks you open the Multi-instance Manager and create or clone an instance; in LDPlayer the same job is done by the Multi-Player window. Each resulting instance is an independent virtual machine with its own storage and its own network stack, so per-instance proxying is possible — the question is only where you type the address.

Three places, in order of reliability:

One detail trips up nearly everyone the first time: 127.0.0.1 inside an emulated Android device is that device, not your PC. In the AOSP emulator the host is reachable at 10.0.2.2. BlueStacks and LDPlayer instances usually sit on a bridged or NAT'd adapter where the host is reachable at its LAN address instead, for example 192.168.1.20. If you set a proxy and get no traffic at all, this is the first thing to check.

The pattern that scales: one local port per instance

Everything above shares a weakness. The one field you reliably get is host and port, and the one thing that distinguishes one residential exit address from another is credentials. The fix is to move the credentials off the emulator: run a small forwarder on the host that listens on a different local port per instance, and have each port carry a different upstream username.

PyProxy uses a single gateway — gw.pyproxy.com on port 1111 — and the username carries the options, so the whole per-instance identity lives in one string. A session token in the username holds one exit address for about thirty minutes, which is what makes an instance keep the same address while it works. With gost:

gost -L http://:20001 -F "http://USERNAME-country-us-session-inst01:PASSWORD@gw.pyproxy.com:1111"
gost -L http://:20002 -F "http://USERNAME-country-us-session-inst02:PASSWORD@gw.pyproxy.com:1111"
gost -L http://:20003 -F "http://USERNAME-country-us-session-inst03:PASSWORD@gw.pyproxy.com:1111"

The same idea in a 3proxy config file, one chain per listener:

nserver 1.1.1.1
nscache 65536
auth none
allow *

parent 1000 http gw.pyproxy.com 1111 USERNAME-country-us-session-inst01 PASSWORD
proxy -p20001 -a
flush

parent 1000 http gw.pyproxy.com 1111 USERNAME-country-us-session-inst02 PASSWORD
proxy -p20002 -a
flush

Now instance one is -http-proxy http://10.0.2.2:20001, instance two is :20002, and no emulator ever sees a password. Three things get easier at once: the Android proxy field with no credential boxes is suddenly enough; you rotate an instance's address by editing one line on the host and restarting one listener; and your instance-to-address map is a text file you can read, rather than state hidden inside ten VMs.

Keep the session token tied to the instance name, as above. When you want that profile to move to a new address, change the token; when you want it to stay put, leave it. If you need the profiles in different countries, change -country-us on the relevant lines and nothing else.

Verifying each instance separately

A check from the host proves nothing about the emulators, so test each listener and then each instance. First the forwarder, from the host:

curl -x http://127.0.0.1:20001 -s https://httpbin.org/ip
curl -x http://127.0.0.1:20002 -s https://httpbin.org/ip

Two different addresses in the two responses means your credentials and tokens are wired up correctly. Then confirm the instances are really using them. List the running devices and drive each one by serial:

adb devices
adb -s emulator-5554 shell settings get global http_proxy
adb -s emulator-5554 shell am start -a android.intent.action.VIEW -d https://httpbin.org/ip
adb -s emulator-5556 shell am start -a android.intent.action.VIEW -d https://httpbin.org/ip

Read the address off the screen of each instance. What you are looking for is not merely "a proxy is working" but a different address in every window, and the same address still showing a few minutes later in the same window. If two windows agree, two of your profiles are one profile. If one window changes address mid-session, its session token is not being sent — check that the forwarder line for that port really contains it.

Finally, re-run the check after a reboot of one instance. Proxy settings applied inside Android persist; settings passed as a launch flag do not, so whatever script starts your instances has to pass the right port every time.

PyProxy residential starts at $0.67/GB with traffic that never expires. Link Telegram to a new account and the first gigabyte is free — no card, no deposit.
See proxy plans Get 1 GB free

Questions people ask

Can each Android emulator instance use a different proxy IP?

Yes. A proxy on Android is a per-network setting, and each emulator instance has its own virtual network stack, so instance one can leave through one address while instance two leaves through another. The practical difficulty is not the emulator, it is keeping the credentials for each instance separate and stable.

Does the emulator -http-proxy flag accept a username and password?

The documented form is http://user:password@host:port, but support varies between emulator builds and any special character in the password tends to break parsing silently. Pointing each instance at a different local port that already carries the credentials is far more reliable.

How long will one instance keep the same exit IP?

With a session token in the username a PyProxy exit address is held for about thirty minutes, which is long enough for an instance to finish a working session on one address. Change the token when you want a new address, keep it when you do not.

How do I check which IP a specific emulator is actually using?

Test from inside that instance, not from the host. Open httpbin.org/ip in the instance browser, or push the request through adb with the instance serial, for example adb -s emulator-5554 shell am start -a android.intent.action.VIEW -d https://httpbin.org/ip. Checking from the host only tests the host.