Blog

Android in the cloud for developers and testers: Redroid with GPU rendering

We ran Android 14 in Docker (Redroid) on a Linux server with a shared Intel UHD 770 and compared GPU and software rendering: 58 fps instead of 7 on a 3D shader, 60 fps instead of 19 in a 3D game, and under 5 % CPU instead of 95 %.

Android in the cloud for developers and testers: Redroid with GPU rendering

An Android device that is always on, reachable with ADB from your laptop or your CI, and that you can reset in seconds: that is what Redroid gives you on a Linux server. Redroid (“remote Android”) runs a full Android system in a Docker container, without a virtual machine inside the server. It is useful to test your app on a clean Android, to run automated UI tests (Appium, uiautomator, Espresso), or to keep an Android-only app running 24/7.

The question for this article is simple: what does the GPU change? Redroid can draw the screen with the server’s GPU (through Mesa) or with the CPU only (software rendering). We ran the same tests on the same server in both modes.

SuperTuxKart (free, from F-Droid) in Redroid, recorded with scrcpy on the same server: GPU rendering at the top (59 fps), software rendering at the bottom (16 fps). 5 seconds.

Results at a glance

  • Simple apps are smooth either way: scrolling Android’s Settings ran at 60 fps with 1 slow frame out of about 1,045 in both modes. But software rendering used 4 times more CPU (17.3 % of the server instead of 4.2 %).
  • Anything 3D needs the GPU: a raymarching shader ran at 58.4 fps on the GPU against 7.2 fps in software, and the SuperTuxKart game at 60 fps against 19 fps.
  • The GPU frees the CPU: with the GPU, Android used under 5 % of the server’s CPU in every test. In software mode, 3D work took 95 to 98 % of the 4 vCPU, leaving nothing for your tests.
  • Boot is not faster with the GPU: Android was ready in about 13 s in GPU mode and 7 s in software mode.
  • iGPU Start is enough for one Android instance; choose iGPU Power to run several in parallel or to test 3D apps and games.

Test setup

ItemValue
ServerDebian 13, Linux 7.3, Intel UHD 770 (shared GPU), 4 vCPU, 10 GB of RAM
AndroidRedroid, official image redroid/redroid:14.0.0-latest (Android 14, x86_64), Docker 29.9
Screen1080×1920 at 420 dpi, 60 Hz (games switch to 1920×1080 landscape)
GPU renderingredroid_gpu_mode=host: Mesa 24.0.8, “Mesa Intel UHD Graphics 770”, OpenGL ES 3.2
Software renderingredroid_gpu_mode=guest: ANGLE on SwiftShader (CPU), OpenGL ES 3.1
AppsAndroid Settings, Shader Editor 2.36.3 and SuperTuxKart 1.4 (both open source, from F-Droid)
Measuresframe rate per layer from SurfaceFlinger (dumpsys SurfaceFlinger --timestats), jank from dumpsys gfxinfo, CPU of the whole server from /proc/stat
Viewingscrcpy 5.0.1 (official release), adb exec-out screencap for screenshots

Each measure lasted 10 to 20 seconds. CPU figures are a share of the whole server (4 vCPU = 100 %).

1. Everyday UI: smooth in both modes, but not at the same cost

We opened Android’s Settings and scrolled up and down 20 times with adb shell input swipe, then read Android’s own frame report with adb shell dumpsys gfxinfo com.android.settings:

Settings, 20 swipesGPUSoftware
Frames drawn1,0451,047
Janky frames1 (0.10 %)1 (0.10 %)
Frame time, 50th / 90th / 99th percentile17 / 18 / 18 ms17 / 17 / 18 ms
Server CPU4.2 %17.3 %

For a normal app with lists, buttons and text, the CPU of a modern server is fast enough to draw the screen by itself. The difference is the price: software rendering made the whole server about four times busier. When your tests run several instances or record the screen, that CPU is missing elsewhere.

2. 3D: where the GPU makes the difference

We used two open-source apps from F-Droid: Shader Editor, which draws a GLSL shader full screen and shows its frame rate, and SuperTuxKart, a 3D kart racing game. In Shader Editor we ran the default shader (very light) and a raymarching scene (spheres, soft shadows, fog) that we wrote for this test.

Frames per second (CPU of the server)GPUSoftware
Shader Editor, default shader60.0 fps (4.0 %)60.1 fps (64.4 %)
Shader Editor, raymarching shader58.4 fps (1.8 %)7.2 fps (98.1 %)
SuperTuxKart tutorial, 1920×108060.0 fps (4.7 %)19.2 fps (95.2 %)
SuperTuxKart while driving, recorded by scrcpy59.2 fps16.1 fps
Bar chart: frames per second in Redroid with GPU rendering and with software rendering, for a raymarching shader, SuperTuxKart and a simple shader
Frames per second, GPU (green) against software rendering (orange). Even the light shader that reaches 60 fps in software mode costs 64 % of the server's CPU.
Bar chart: server CPU use in Redroid with GPU rendering and with software rendering, for four workloads
CPU use of the whole server (4 vCPU) during the same tests: under 5 % with the GPU, up to 98 % in software mode.

With the GPU, the 3D scenes stay at the screen’s 60 fps and the CPU is almost idle. In software mode the four vCPU are full and the frame rate falls to 7 to 19 fps: a game is no longer playable, and a UI test running at the same time would be slowed down too. While a game was running, the Redroid container used about 1.4 GB of RAM in both modes, and Docker counted 10 % of one core with the GPU against 381 % (almost four cores) in software mode.

The raymarching shader in Shader Editor on Redroid: 56 fps with the GPU on the left, 7 fps in software mode on the right
The same raymarching shader in Shader Editor, captured with adb exec-out screencap: GPU on the left (the app shows 56 fps), software on the right (7 fps). The image is identical, only the speed changes.

3. Boot time

We timed docker run until Android reported sys.boot_completed=1, three times per mode, with an empty data folder each time:

Boot to “ready”Run 1Run 2Run 3
GPU12.7 s13.3 s12.8 s
Software7.0 s6.5 s7.0 s

GPU mode starts about 6 seconds slower, because the graphics driver is loaded and set up at boot. For a CI job that starts a fresh Android for each run, count about 13 seconds before adb can install your app.

4. Viewing and controlling Android from your computer

Redroid has no screen of its own: you use it like a phone plugged in with a USB cable, through ADB.

  • Screenshots: adb exec-out screencap -p > screen.png, the method we used for the images above.
  • Live screen, mouse and keyboard: scrcpy (open source, by Genymobile) shows the Android screen in a window and sends your clicks and keys. It works through ADB, so it works with Redroid. On the server we used it without a window to record the videos of this article: scrcpy -s 127.0.0.1:5555 --no-window --no-audio --record=run.mp4 --time-limit=7.
  • UI automation: adb shell input (taps, swipes, text) drove every test of this article, and adb shell uiautomator dump returns the screen’s view tree. Appium (UiAutomator2 driver), Espresso and Maestro connect to an ADB device in the same way; we did not run them in this test.

Never open the ADB port to the Internet: Redroid’s ADB has no password and gives full control of the Android system. We publish it on the server’s local address only (-p 127.0.0.1:5555:5555) and reach it through an SSH tunnel:

# on your computer
ssh -N -L 5555:127.0.0.1:5555 you@<server> &
adb connect 127.0.0.1:5555
scrcpy -s 127.0.0.1:5555
SuperTuxKart running in Redroid with GPU rendering at 1920×1080, screenshot taken with adb
SuperTuxKart's tutorial in Redroid with GPU rendering, at 1920×1080 and 60 fps.

5. What to know before you start

  • This is x86_64 Android. Apps written in Java or Kotlin run as they are. Apps and games with native code built only for ARM (many games) need a translation layer: the Redroid image announces ARM support (arm64-v8a) through such a layer, but we did not test ARM-only apps, and they will be slower and may fail.
  • No Google Play Store. The official image has no Google services. Install your own APKs with adb install, or open-source apps from F-Droid as we did. Apps that need Google Play services will not work as they are.
  • For testing and automation, not for faking phones. Redroid tells apps it is a virtual device. It is meant for development, testing and running your own tools, not to run many “phones” for multiple accounts, which most app terms forbid.
  • No camera, GPS or SIM. Sensors are missing or simulated; test them on a real device.

6. Which plan?

With the GPU, one Android instance used under 5 % of our 4 vCPU and about 1.4 GB of RAM, even in a 3D game. iGPU Start (2 vCPU, 8 GB of RAM, €14.99 per month excl. VAT) is enough for one Android instance with your test tools next to it. iGPU Power (4 vCPU, 14 GB of RAM, twice the GPU share of Start, €29.99 per month excl. VAT) is the better choice to run several Android instances in parallel (one per test job), to test 3D apps and games, or to record the screen during tests. iGPU Pro (6 vCPU, 14 GB, Perf 3, €44.99) adds more GPU and CPU for larger test farms.

Without a GPU, the same server would have to give its whole CPU to drawing as soon as an app uses 3D.

7. Set it up on a Linux GPU server

Want it ready to use? Ask for it by email when you order (contact@linuxgpu.eu): we can deliver the server with Redroid already installed and set up for GPU rendering. You only connect with ADB through SSH and install your app.

To do it yourself on Debian 13:

  1. Load Android’s binder driver (part of the Debian kernel) and keep it at boot:

    echo "options binder_linux devices=binder,hwbinder,vndbinder" > /etc/modprobe.d/binder.conf
    echo binder_linux > /etc/modules-load.d/binder.conf
    modprobe binder_linux
  2. Install Docker and ADB (apt install docker.io adb), then start Redroid with GPU rendering:

    docker run -d --name redroid --privileged \
      -v ~/redroid-data:/data -p 127.0.0.1:5555:5555 \
      redroid/redroid:14.0.0-latest \
      androidboot.redroid_gpu_mode=host \
      androidboot.redroid_gpu_node=/dev/dri/renderD128 \
      androidboot.redroid_width=1080 androidboot.redroid_height=1920 \
      androidboot.redroid_dpi=420 androidboot.redroid_fps=60
  3. Check that Android uses the GPU: adb connect 127.0.0.1:5555 && adb shell dumpsys SurfaceFlinger | grep GLES should show “Mesa Intel(R) UHD Graphics 770”. “SwiftShader” means software rendering.

  4. Connect from your computer through the SSH tunnel above, install your APK with adb install, and start your tests.

To reset Android to a clean state, remove the container and its data folder and start it again.

For browser tests on the same kind of server, read GPU-accelerated Selenium and Playwright tests and Chrome with GPU on a headless Linux server. To understand how a container uses the GPU of a virtual machine, see GPU cloud: VM or container, dedicated or shared GPU.

Try it

See the plans: iGPU Start is €14.99 and iGPU Power €29.99 per month excl. VAT.