⏱️ Reading time: 14 min

A GrapheneOS user on a Pixel 8 had been running the system for a year when they noticed something odd: Osmand, their mapping app, ran noticeably slower than on any other Android device. It wasn’t a bug in the app: it was one of the layers of GrapheneOS sandboxing checking every memory allocation before handing it over.

📑 En este artículo
  1. TL;DR
  2. What Is GrapheneOS Sandboxing?
  3. Why It Matters
  4. How GrapheneOS’s Permission Architecture Works
    1. Storage Scopes: Less Than Full Storage Permission
    2. Per-App Internet Permission: Cutting Network Access Without Uninstalling
    3. Sandboxed Google Play: Google’s Services Without System Privileges
    4. Hardened Malloc: The Layer That Hits Performance the Most
  5. Practical Examples: When GrapheneOS Sandboxing Is Noticeable
  6. Real-World Use Cases
  7. Common Mistakes and Best Practices
  8. Comparison With Alternatives
  9. Going Deeper: What Hardened Malloc Does Under the Hood
  10. Frequently Asked Questions
    1. Does GrapheneOS’s Internet Permission Block Wi-Fi and Mobile Data Equally?
    2. How Do I Know If the Hardened Memory Allocator Is Slowing Down a Specific App?
    3. Does Sandboxed Google Play Need System Privileges on GrapheneOS?
    4. Can I Disable hardened_malloc for a Single App on GrapheneOS?
    5. Does Storage Scopes Replace Android’s Storage Permissions?
    6. Does GrapheneOS Work on Any Phone?
  11. References

That specific anecdote is just the tip of the iceberg. GrapheneOS wraps every app in layers of isolation (memory, storage, network, and Google Play), and each layer comes with a performance cost. Understanding that model, not just the case of one slow app, is what lets you decide when it’s worth paying that cost.

TL;DR

  • GrapheneOS sandboxing adds hardened malloc, Storage Scopes, and Internet permission, with a performance cost.
  • Osmand runs slower on GrapheneOS because hardened malloc checks every memory allocation the map makes.
  • Storage Scopes limits which folders each app can see without granting full storage permission.
  • Sandboxed Google Play runs without system privileges and translates calls through a compatibility layer.
  • Disabling per-app memory protection regains speed at the cost of less hardening.

What Is GrapheneOS Sandboxing?

GrapheneOS sandboxing is the set of isolation mechanisms that this Android-based operating system adds on top of each app’s standard sandbox: a hardened memory allocator, granular storage and Internet permissions, and an unprivileged version of Google Play Services.

Its goal is to reduce the attack surface of every installed application, without relying on the developer having written flawless code. Each layer works independently: you can disable one without touching the others, and that’s key to the rest of this article.

Why It Matters

Most mobile operating systems trust apps to behave well. Standard Android already sandboxes every app with its own Linux UID, but GrapheneOS adds extra layers designed for the worst-case scenario: a malicious app, a compromised one, or simply one with an exploitable bug.

That matters because a phone’s threat model has changed. Checking permissions at install time is no longer enough: a zero-day exploit in an image or mapping library can execute arbitrary code without the user doing anything. GrapheneOS’s memory protections, like hardened_malloc, exist so that exploit fails before it gains control over the process.

That cost is real, and it’s the central topic of this article: every extra check consumes CPU cycles. In apps with intensive memory usage patterns, like a map renderer loading and discarding thousands of tiles per minute, that cost shows. The real decision isn’t security yes or no, but how much security each specific app needs.

How GrapheneOS’s Permission Architecture Works

Isolation isn’t a single feature: it’s four separate mechanisms that any user can turn on or off per app, from each application’s info screen.

Storage Scopes: Less Than Full Storage Permission

Regular Android offers two options for storage: full access or none. Storage Scopes adds a middle ground: when an app requests file access, GrapheneOS can show it only a specific folder instead of the phone’s entire storage. The app behaves as if that folder were the only storage that exists.

This reduces the damage if a malicious app tries to read photos, documents, or backups from other apps: even with permission granted, it only sees what the scope allows it to see.

Per-App Internet Permission: Cutting Network Access Without Uninstalling

GrapheneOS adds an additional Internet permission that doesn’t exist as such in standard Android. Disabling it for an app cuts off its access to network sockets at the kernel level: the app stays installed and works with local data, but it can’t connect to the internet even if its code tries to.

It’s useful for apps that don’t need to be online (a calculator, a local photo editor) which, if compromised, shouldn’t be able to exfiltrate anything.

Sandboxed Google Play: Google’s Services Without System Privileges

On standard Android, Google Play Services runs with elevated privileges: it can access data and permissions no other app has. GrapheneOS installs Google Play as a normal app, sandboxed just like any other, and adds a compatibility layer that translates the calls apps make expecting to find the system’s privileged Play Services.

The result is that most apps relying on Google Play (push notifications, maps, sign-in) work the same, but Google Play no longer has a privileged position from which to monitor the rest of the phone.

Hardened Malloc: The Layer That Hits Performance the Most

The fourth layer is the one behind the anecdote that opens this article. GrapheneOS replaces Android’s standard memory allocator with hardened_malloc, an allocator designed to detect memory corruption (use-after-free, heap overflows) before an attacker can exploit them.

By default it runs on every app in the system. But GrapheneOS lets you add, per app, an even stricter extra layer of memory protection, under App Settings > Exploit protection. That extra layer is exactly the one a user reported was slowing down Osmand on their Pixel 8.

LayerWhat it controlsPerformance costAdjustable per app
hardened_malloc (strict mode)Every memory allocation and deallocationNoticeable in apps with many allocations (maps, games)Yes, in Exploit protection
Storage ScopesWhich folders an app with storage permission can seeMinimalYes, the scope is set per app
Internet permissionWhether the process can open internet socketsNone if allowedYes, Internet permission in app info
Sandboxed Google PlayGoogle Play framework privilegesExtra latency on calls translated by the compatibility layerNot individually

flowchart TD
A["App installed on GrapheneOS"] --> B["Android sandbox: process with its own UID"]
B --> C["Storage Scopes: sees only one folder, not all storage"]
B --> D["Internet permission: can block internet sockets"]
B --> E["Sandboxed Google Play: no system privileges"]
B --> F["hardened_malloc: validates every memory allocation"]
GrapheneOS replaces privileged Play Services with a sandboxed version that has no special access to the rest of the system. Foto de Rami Al-zayat en Unsplash

Practical Examples: When GrapheneOS Sandboxing Is Noticeable

The case documented on the WirelessMoves blog is the clearest example. Osmand, the OpenStreetMap-based mapping app, draws the map by constantly loading and discarding tile data as the user scrolls or zooms. Each of those tiles goes through a memory allocation, and with the protection enabled, every allocation goes through hardened_malloc‘s extra checks.

sequenceDiagram
participant App as Osmand
participant Mem as hardened_malloc
App->>Mem: requests memory for a map tile
Mem->>Mem: adds guard pages and checks the size
Mem-->>App: hands over the validated memory block
Note over App,Mem: the cycle repeats thousands of times while scrolling

The user who reported the case fixed it from Settings: they long-pressed the Osmand icon, went into App info, scrolled down to Exploit protection, and specifically disabled the hardened memory allocator, leaving the other protections on. After restarting Osmand, the app felt as fast as on any other Android device again.

A comment on the same blog adds another case: Waze noticeably draining battery on a Pixel 10a running GrapheneOS while running in Android Auto, with the phone heating up. It’s the same pattern: an app with intensive CPU and memory usage running into extra verification layers, this time with an impact on power consumption instead of visual smoothness.

⚠️ Heads up: disabling the hardened memory allocator for a specific app reduces its protection against memory bug exploitation for that particular app. It doesn’t affect the rest of the system, but it does affect that app.

Real-World Use Cases

Not every user profile needs the same configuration. A journalist or activist handling sensitive information in countries with state surveillance benefits from leaving all protections on, even if that means the browser or messaging client run a bit slower: the speed cost is low compared to the risk of a successful exploit.

A user who just wants reasonable privacy against ad tracking, but uses apps with maps, photo editing, or games with heavy graphics engines, gains more by adjusting case by case: keep Storage Scopes and Internet permission on at all times (their cost is nearly zero), and reserve disabling the hardened memory allocator for the two or three apps that genuinely need it.

For developers testing their own apps on GrapheneOS before publishing, the isolation works as a testbed: if an app breaks with Storage Scopes enabled, it’s likely assuming full storage access instead of requesting specific files, something Android also started restricting with Scoped Storage starting with Android 11.

Common Mistakes and Best Practices

  • Disabling all protections at once: turning off the hardened memory allocator for every app instead of just the slow one undoes much of the value of installing GrapheneOS in the first place.
  • Confusing the Internet permission with a full firewall: it blocks the app’s outgoing sockets, but doesn’t replace a system-level firewall or filter by domain or IP address.
  • Assuming Sandboxed Google Play is the same as not having Google Play at all: it’s still the same Google code running on the phone, just without system privileges. If you’re worried about Google’s tracking itself, the alternative is not installing Play at all.
  • Not reviewing what scope you gave each app: over time, apps accumulate access to folders they no longer need; it’s worth reviewing Storage Scopes periodically, just like you would review camera or microphone permissions.
  • Misdiagnosing a slow app: before assuming it’s a bug in the app, try disabling the hardened memory allocator just for that app and compare. If the problem disappears, you’ve found the cause.

Comparison With Alternatives

GrapheneOS isn’t the only option for those seeking more control than stock Android. The difference lies in how much isolation depth each project adds and how far it goes with Google Play.

SystemApp sandboxingGoogle PlayWhen it’s the right fit
Stock Android (Pixel, Samsung)Standard AOSP sandbox, no extra layersWith system privilegesYou prioritize full compatibility over additional hardening
GrapheneOShardened_malloc, Storage Scopes, Internet permission, sandboxed PlayOptional, runs as a normal appYou prioritize exploit resistance and granular per-app control
LineageOSStandard AOSP sandbox plus LineageOS’s own privacy controlsVia microG or unsandboxed PlayYou want ROM freedom without adopting GrapheneOS’s full hardening
CalyxOSBuilds on part of GrapheneOS’s hardened_malloc workMicroG by default, Play optionalYou want similar privacy with a more guided initial setup

The real tradeoff isn’t whether to use GrapheneOS or not, but how much granular isolation you need to control yourself. LineageOS and CalyxOS make more automatic, less configurable decisions; GrapheneOS gives you the dial for each layer, with the tradeoff that you’re also the one who has to adjust it when an app gets slow.

hardened_malloc separates allocations by size and adds guard pages to stop memory corruption before an exploit can use it. Foto de Christian Wiediger en Unsplash

Going Deeper: What Hardened Malloc Does Under the Hood

The standard memory allocator in most systems (based on dlmalloc or jemalloc variants) prioritizes speed: it reuses freed memory blocks as soon as possible and doesn’t check much beyond whether the pointer exists. That leaves an entire family of exploitable bugs open: use-after-free, double-free, and heap overflows that write past the allocated block.

hardened_malloc, the project GrapheneOS maintains, tackles those bugs with several combined techniques: it separates allocations by size into distinct regions to prevent a small overflow from corrupting another allocation’s metadata, adds guard pages around large allocations that cause an overflow to trigger an immediate crash instead of silent corruption, and quarantines freed memory for a while before reusing it, so a use-after-free has a better chance of failing visibly instead of executing attacker code.

On the Pixel 8 and later models, GrapheneOS can also rely on Memory Tagging Extension (MTE), an ARM hardware feature that tags each memory block with a tag of a few bits and checks on every access that the pointer uses the correct tag. It’s the same family of protection hardened_malloc implements in software, but resolved in silicon, with a lower CPU cost than the purely software-based version.

flowchart TD
A["App requests memory"] --> B["hardened_malloc separates by allocation size"]
B --> C["Adds guard pages around the block"]
C --> D["If the chip has MTE, tags the block with a hardware tag"]
D --> E["Every access checks the tag before reading or writing"]
E --> F{"Does the tag mismatch?"}
F -->|"Yes"| G["The process crashes in a controlled way"]
F -->|"No"| H["The access proceeds normally"]

That’s the technical reason why the performance impact isn’t uniform: a phone with MTE pays a lower cost for this protection than one without that hardware, and an app that makes few large allocations (a PDF reader) notices it far less than one that makes thousands of small allocations per second (a map renderer or a game engine).

There’s no direct way to measure from the outside how much overhead hardened_malloc adds to a specific app without native Android profiling tools; the practical way to check is the one the original reporter used: disable the extra protection for that app and compare smoothness before and after.

Your next step: go to Settings > Apps, pick the app you suspect is slower, open Exploit protection, and disable only the hardened memory allocator to compare it against its current behavior.

📬 Get new articles by email

We only email about big articles (1-2 a month).

Frequently Asked Questions

Does GrapheneOS’s Internet Permission Block Wi-Fi and Mobile Data Equally?

Yes. GrapheneOS’s Internet permission cuts off socket access at the system level, regardless of whether the connection is Wi-Fi, mobile data, or VPN. If the app doesn’t have the permission, it can’t open any outgoing connection by any means.

How Do I Know If the Hardened Memory Allocator Is Slowing Down a Specific App?

Temporarily disable it for that app in App Settings > Exploit protection and compare. If smoothness improves noticeably, as in the Osmand case documented by WirelessMoves, you’ve identified the cause.

Does Sandboxed Google Play Need System Privileges on GrapheneOS?

No. Unlike stock Android, GrapheneOS installs Google Play Services as just another sandboxed app, with no privileged access to the rest of the system, and uses a compatibility layer to respond to the calls apps expect from a privileged Play Services.

Can I Disable hardened_malloc for a Single App on GrapheneOS?

You can disable the extra layer of memory protection, the hardened memory allocator, per app from Exploit protection. The base level of hardened_malloc stays active across the whole system; what gets turned off is the stricter mode for that specific app.

Does Storage Scopes Replace Android’s Storage Permissions?

It complements them. Storage Scopes kicks in once an app already has storage permission granted, and restricts that permission to a specific folder instead of leaving it open to the entire device.

Does GrapheneOS Work on Any Phone?

No: it’s only officially compatible with Google Pixel phones, because it depends on hardware security features from that line, like verified boot and, on recent models, Memory Tagging Extension, which other manufacturers don’t expose in the same way.

References

  • WirelessMoves: the original post documenting the case of Osmand running slow on GrapheneOS and how disabling the hardened memory allocator fixes it.
  • GrapheneOS Features: official documentation for Storage Scopes, the per-app Internet permission, and Sandboxed Google Play.
  • GrapheneOS/hardened_malloc on GitHub: source code and technical documentation for the hardened memory allocator.
  • Android Developers: Scoped Storage: Google’s official documentation on the storage restrictions Android introduced starting with version 11.

📱 Enjoying this content? Follow @programacion on Telegram for daily tech content in Spanish: quick summaries, fresh content every day.

Featured image: Foto de Kedibone Isaac Makhumisane en Unsplash

Did it work for you? Got a different error? Say so below: questions get answered and help the next reader.

Leave a comment
Categories: Tech NewsTutorials

Andrés Morales

Developer and AI researcher. Writes about language models, frameworks, developer tooling, and open source releases. Covers ML papers, the tech startup ecosystem, and programming trends.

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *

You can include code inside <code>…</code> or, for several lines, <pre><code>…</code></pre>.

This site uses Akismet to reduce spam. Learn how your comment data is processed.