< Back to all hacks

#25 Static IP + GMS Kill

Debloat
Problem
GMS uses 270 MB but killing it breaks WiFi. Need a way to kill GMS safely.
Solution
With static IP configured, route is proto static — doesn't depend on GMS. Kill works! But GMS respawns in ~2 min.
Lesson
am force-stop from Termux (uid 10001) fails — FORCE_STOP_PACKAGES permission denied. Only works from ADB shell (uid 2000).

Context

Google Play Services (com.google.android.gms) is the single largest memory consumer on Android, using approximately 270 MB of RAM across its various persistent processes: GmsCore, GmsCoreService, NetworkLocationService, and others. On a 1 GB device like the Moto E2, that is over a quarter of total physical memory consumed by a service the OpenClaw gateway never uses.

The obvious fix is to kill it. But here is the trap: on a default Android WiFi configuration, the device obtains its IP address, DNS servers, and default route via DHCP. The DHCP client is managed by GMS through its network scoring and connectivity framework. Kill GMS, and within seconds the DHCP lease renewal fails, the route table entry disappears, and the device loses network connectivity. This was discovered the hard way in Hack #24 (Don't Kill GMS).

The breakthrough was realizing that Android's WiFi settings allow configuring a static IP. With a static IP, the kernel route table entry has proto static instead of proto dhcp. The route no longer depends on any userspace daemon for renewal. GMS can be killed without losing connectivity.

Implementation

First, configure static IP in Android WiFi settings:

Settings -> WiFi -> Long-press network -> Modify -> Show advanced
IP settings: Static
IP address: 192.168.1.14
Gateway: 192.168.1.254
Network prefix length: 24
DNS 1: 8.8.8.8
DNS 2: 8.8.4.4

Verify the static configuration is active:

# From ADB shell:
settings get global wifi_static_ip          # Returns: 1
settings get global wifi_static_ip_address  # Returns: 192.168.1.14

# Check route table — should show proto static:
ip route show
# 192.168.1.0/24 dev wlan0 proto static scope link
# default via 192.168.1.254 dev wlan0 proto static

Now kill GMS safely:

# MUST run from ADB shell (uid 2000), NOT from Termux SSH:
am force-stop com.google.android.gms

# Verify connectivity survived:
ping -c 3 8.8.8.8
# PING 8.8.8.8: 3 packets transmitted, 3 received, 0% loss

# Check RAM freed:
cat /proc/meminfo | grep MemFree
# MemFree jumps from ~53 MB to ~126 MB

Verification

# Confirm GMS processes are gone:
ps | grep gms
# Should return nothing (or just the grep itself)

# Confirm route table is intact:
ip route show | grep "proto static"
# Should show default route and subnet route

# Confirm gateway can reach the internet:
curl -s http://localhost:9000/api/status | grep -o '"online":[a-z]*'
# Expected: "online":true

# Monitor for GMS respawn:
watch -n 10 'ps | grep -c gms'
# Will go from 0 back to 3-5 within ~2 minutes

Gotchas

  • GMS respawns within approximately 2 minutes. Android's init system and various broadcast receivers (CONNECTIVITY_CHANGE, BOOT_COMPLETED residual) trigger GMS restart. There is no way to prevent respawn without root-level pm disable
  • am force-stop from Termux SSH fails silently. Termux runs as uid 10001 (untrusted_app SELinux domain) which lacks the FORCE_STOP_PACKAGES permission. The command appears to succeed but does nothing. Must use ADB shell (uid 2000, shell domain) which has this permission
  • Static IP means no automatic DNS from the router. If your upstream DNS changes, you must update it manually in WiFi settings
  • If the phone roams to a different WiFi network, the static IP config may cause a conflict. The phone will connect but have the wrong IP for that network
  • The 270 MB freed is temporary due to respawn. For permanent GMS removal, combine with pm disable (Hack #26) via Dirty COW root
  • Static IP survives reboots. The WiFi settings persist in /data/misc/wifi/wpa_supplicant.conf

Result

ModeGMS RAMTotal UsedTotal Free
Default (GMS running)~270 MB~522 MB~398 MB (43%)
After am force-stop0 MB~263 MB~657 MB (71%)
After respawn (~2 min)~270 MB~522 MB~398 MB (43%)
pm disable (permanent)0 MB~263 MB~657 MB (71%)

The static IP discovery was critical for understanding the GMS dependency chain. Even though the kill itself is temporary without root, it proved that WiFi can function independently of GMS. This validated the aggressive debloat strategy in Hack #26, where GMS is permanently disabled via Dirty COW. The static IP remains in production as the network configuration for PocketClaw.