How Perch compares

Perch is one of seven clients for a self-hosted Hermes Agent. Below: what it measures at, how it lines up against each of the others on every axis that matters for a phone, and where it is behind. Perch numbers are read off measurement artefacts. Competitor cells are from each project's README as of 2026-09-10.

Measured

WhatPerchThe bar
Cold start to first frame777 msAndroid vitals flags ≥ 5,000 ms as excessive
Install size on Play23.4 MB · 13 s downloadPlay measured −1 % install conversion per +6 MB; 200 MB hard limit
Memory at idle145 MB RSSown gate: 180 MB
Session reconcile after reconnect, p95226 msown gate: 1,000 ms
Capability probe on connect45 msown gate: 600 ms
Approval round-trip, answered from the phone10 ms loopbackthe request itself expires at 300 s
Network traffic while backgrounded0 requests, 0 wakeups in a 121 s windowmeasured through a counting proxy the device is routed through, not asserted
Steady-state connections1hard cap 1
Foreground service while following a runself-stops at 30 min, one ongoing notification with StopAndroid's dataSync cap is 6 h rolling
Polling while a run is unsettledevery 2.5 s, foreground only; idle transcript re-read every 30 s; both stop on background
Stream livenessdeclared dead after 2 missed keepalives (60 s); reconnect backoff 0.5 → 30 s with 20 % jitter, 6 attempts
Third-party runtime dependencies4 (Sentry, marked, MMKV, safe-area) + 20 Expo modules; 0 icon fonts; 63 KB bundled assetsown gate: 8 / 22
Permissions in the shipped bundle27, all reviewed; none for storage, media, location, contacts or advertisingread from the AAB's merged manifest
Credentials in the JavaScript heap0; keys live in the hardware keystorehard zero, scanned every build
Tests1,054 unit + contract (90.9 % core coverage, 69 s) · 26 device flows · live-gateway suite · visual regression
Touch targets · body contrast · reduced motion44 dp · 5.77 : 1 · 100 % honouredWCAG AA is 4.5 : 1
Strings · locales · themes416 · English + Simplified Chinese · light, dark, OLED
Budgets enforced on every build63, 7 of them hard zeros; a budget is never raised to pass

Startup, memory and reconcile were taken on an API 36 emulator, which is where CI can take them. Background traffic was measured by routing the device through a proxy that counts request lines and open sockets. The counters were reset only after the app was off-screen.

Against every other client

Seven clients exist. Two are native iOS, two native Android, one a PWA behind a proxy, one an official Expo shell that wraps the desktop renderer in a WebView, and Perch. hermes-android is the strongest Android alternative; Hermex has the most stars and needs a separate third-party server.

Perchhermes-androidHy4ri/hermes-mobilegoncharik/hermes-mobileHermexShresthaYaju/hermes-mobileNous shell (PR)
StackExpo · RN + 2 Kotlin modulesFlutterKotlin · ComposeSwiftUI · TCASwiftUIPWA + Node proxyExpo shell · WebView
PlatformsAndroid · iOS · webAndroidAndroidiOS · iPadiOS 18+any browseriPhone verified
Talks toapi_server + dashboardapi_server + dashboarddashboard (9119)dashboard (9119)a separate hermes-webui serverdashboard via proxygateway via bridge
ReachLAN · Tailscale · public HTTPS · CGNAT, with 5 reachability verdictsLAN · Tailscale · HTTPS proxyLAN only by designprivate network / VPNtunnel or Tailscale ServeTailscale onlyURL + token
Authkey in hardware keystore · QR pairing · pairing approvalsAPI keybasic auth (admin/hermes default)basic · OAuth · token, KeychainpasswordTailscale identity headertoken stored locally
Streaming✓ SSE, frames as they arrive✓ SSE✓ WebSocket✓ WS✓ (desktop renderer)
Approvals from the phone✓ two-tap · risk-ordered inbox · stale decisions namednot documented
Approval survives a cold start recovered from the run idpartial ("durable turn recovery")no: lost if the phone is asleep, by its own README
Notified while the app is closed✓ your own ntfy topic · 30-min follow service · Android 16 Live Updates✓ background-turn notificationsforeground-service chat notifications✓ push (approvals, clarifications, errors)✓ push, 5 types
Offline cached transcripts · replaying outbox · idempotent resendlocal history DBstate restore after backgroundingcached sessions
Stop · steer · queue mid-run✓ ✓ ✓; the queue holds after a stop, and send-now stops firststopstop · steer
Fork a conversation✓ branch
Search✓ server FTS5 + instant local filter✓ on-device FTS5 + AI
Routines / cron✓ create · edit · pause · run-now · delete✓ CRUD✓ pause · resume · run
Skills✓ browse + togglebrowse✓ manageslash commandsbrowse
Bots / profiles✓ roster · create on the gateway · per-bot key✓ manage✓ multipleselectselect
Attachmentsphoto · PDF · text, 8 MiB, dashboard only10 files × 16 MiB✓ photos · PDF · camera
Voicepush-to-talk, on-device only; audio never leaves the phonedictation and read-aloud; where audio goes is not stateddictation, transcribed by the agent
Usage & contexttokens · cost · cache reads · context % with a real denominatoranalytics & billing✓ tokens · % · costread-only analytics
Tablet✓ two-pane ≥ 820 dp✓ iPad sidebarmaster-detail
Accessibility gated 44 dp · 130 % type · RTL · reduced motion
Second language✓ zh-Hans
Automated tests stated1,054 unit · 26 device flows · live gateway · visual900+ (v2.1.0)JUnit · Espresso · CI
DistributionPlay closed test · signed APK with published fingerprint · webGitHubF-Droid · ObtainiumTestFlightApp Storeself-hostunmerged
Published list of what it cannot do"MVP is feature-complete"✓ (limitations section)
Starsnew278124581.3k0

And the incumbent nobody lists: Telegram, through the gateway's own adapter. It wins on push: instant, everywhere, no setup. It loses on everything an approval needs: the exact command on screen, a fail-closed deadline shown as a countdown, a two-tap confirm, and a record of what was decided. That is the bar Perch sets itself.

Where Perch is behind

Not measured yet

Budgets exist for these; the numbers do not. Battery per hour of streaming and frame drops during a stream need a physical device, because an emulator renders through the host GPU. Crash-free sessions and ANR rate need real users, and the gates are set at 99.7 % and 0.2 % against Play's bad-behaviour lines of 98.91 % and 0.47 %. Memory at 10,000 messages is bounded (1,000 rendered rows, 50 per page) and unmeasured.

What it will not do

Privacy position in full: the privacy policy. Try it with no server at all — walkthrough mode renders every screen from captured responses.