How we actually run InternetIncome
This guide comes from a live rig, not theory: a GMKtec K12 mini PC with 128 GB of RAM, holding around 3,500 concurrent IPs on static ISP SOCKS5 lines. InternetIncome is a nice project when you run it with the right expectations, and most write-ups skip the part that matters: which apps actually pay, what the hardware really needs, and what months of app traffic do to an IP's reputation.
Static ISP lines fit this job because the exit IP stays put. Income apps want stable, residential-looking exits they can pair with a device for weeks. A rotating pool looks like churn to them, and churn does not get credited.
RAM is the real bottleneck
The apps are memory hungry, and the browser-based ones are the worst offenders by far. CPU barely matters. Our K12 spends most of the day half idle on CPU while memory sits high, and we sized the box for RAM without regretting it once.
One well-stocked mini PC also beats a fleet of small VPSes for this: fewer hosts to babysit, one network path to debug, one place to read logs. If you are sizing from scratch, think 64 to 128 GB of RAM, modest CPU, wired network.
InternetIncome runs each app in its own Docker container. Credentials go in properties.conf, proxies go in proxies.txt, one line per container, and most apps only credit one device per IP anyway. Keep a small mapping file beside them: container, proxy label, IP, launch time. When a slot quietly stops crediting three weeks from now, that file is the difference between a five-minute fix and an evening of guessing.
Lines and smoke test
A static ISP line is a raw assigned IP, not a gateway hostname, and running income apps through a rotating gateway defeats the purpose. Each static ISP order ships as its own raw IP with a random port and its own user:pass, different per order. That raw line is exactly what goes into proxies.txt as a SOCKS5 URI, one per container:
socks5://USER:PASS@203.0.113.25:48211
socks5://USER:PASS@198.51.100.7:51904
Those IPs and ports are examples; yours arrive with the order. If an app only takes host, port, username, and password fields, split the same line into those fields.
Test every line from the machine that will run the containers before you pair anything (use socks5h in curl if you want DNS resolved through the proxy during the test):
curl -x socks5://USER:PASS@203.0.113.25:48211 https://example.com -I
| Check | Pass condition | Failure meaning |
|---|---|---|
| Connect | HTTP headers return | Proxy, firewall, or auth failed. |
| Geo | Expected country appears | Wrong pool or wrong routing label. |
| Stability | Same slot stays reachable | Host or app is killing the session. |
| Credits | App credits match activity | The app may not value that traffic. |
Which apps actually earn
After months on this rig, the field sorts itself out pretty clearly:
| App | Verdict | Notes |
|---|---|---|
| EarnApp | Best earner | Strict on IP reputation, and strict on how many IPs one account can hold (see below). |
| Honeygain | Strong, if accepted | The IP acceptance check is the gate. Once a line is in, it earns well. |
| EarnFM | Most consistent | Rarely spikes, rarely dies. A good baseline for every slot. |
| TraffMonetizer | Alright | Accepts nearly everything. Useful for lines the pickier apps reject. |
| eBesucher | Meh outside Germany | Very strict with non-German IPs. Skip it unless your lines are German. |
| Adnade | Nice, but heavy | Browser-based and extremely resource intensive. In our experience earnings also flattened right after they became meaningful, and other operators report the same pattern. |
| IPRoyal Pawns | Short-lived | Degrades IP reputation fast. Whatever it pays now, the line pays for later. |
One hard constraint to plan around: EarnApp does not like InternetIncome-style setups. Accounts holding more than a handful of linked IPs (operators commonly report the 5 to 9 range) tend to get reviewed, and reviews tend to end in removal. Treat that as a ceiling per account and size the rest of the rig with other apps, rather than betting 3,500 lines on the one platform that will not take them.
IP reputation is the budget you are actually spending
Every app you stack on a line spends the same currency: that IP's reputation. The problem is the apps do not pay equally for what they spend. IPRoyal burns a line fast. Even the polite apps add up over months. And the app that pays best, EarnApp, is also the most sensitive to reputation, so stacking everything on every line eventually locks your best lines out of your best payer.
Short run, stacking feels free: every extra app is extra profit on bandwidth you were already paying for. Long run, the lines tick over EarnApp's tolerance and the ceiling of the whole rig drops. If we rebuilt today, we would seriously consider running EarnApp on clean, dedicated lines, with at most one gentle app like EarnFM beside it, and keep the accept-everything apps on lines whose reputation we have already written off.
Why app credits never match the proxy meter
No income app credits what the proxy meter bills. The app is not cheating you. It credits only the traffic it values, while the meter also sees DNS, TLS setup, redirects, retries, failed loads, and idle keepalives. A gap is normal. A gap that keeps growing is not.
Compare credited value against proxy usage daily for the first weeks of any new slot. If one app consumes far more bandwidth than it credits, retire that slot. A stable proxy cannot fix a bad earning ratio.
The daily earning-ratio check
Write down opening proxy usage, closing proxy usage, app credit, and uptime per slot. The point is not just catching losers; it is finding which slots deserve more lines. Scale what earns.
| Field | Why it matters |
|---|---|
| Opening GB | Baseline for real cost. |
| Closing GB | Shows silent background traffic. |
| App credit | Shows whether traffic was valued. |
| Restart count | Catches unstable host or app behavior. |
The dashboard can look busy while the earning ratio is bad. Your own log catches that before the dashboard shows it.
Retire slots without drama
Retire a slot when credit stays flat while proxy usage climbs, when the app keeps reconnecting without useful work, or when it needs babysitting every few hours. A good-looking IP on a bad slot is still a bad slot, and its reputation is being spent either way.
When you change anything, restart cleanly: stop the app, change the line, start it, confirm fresh traffic. And keep it to one change per restart. Changing the proxy, the app version, the host, and the account at the same time makes every failure ambiguous.