The Long Version
Privacy Policy.
Last updated: 17 August 2026
Who and what
Stray is an activity tracker for Android and iOS (package
be.grunt.stray), published by Grunt SRL,
Rue du Couvent 20, 1332 Rixensart, Belgium, VAT BE 0738.575.618.
It records runs, walks, hikes and rides.
Throughout this policy, a run means any recording Stray makes, whichever of those you chose. Nothing below applies to one kind and not another.
Contact: stray@grunt.be
The core statement
Stray collects no personal data. There are no accounts, no sign-up, and no login. Every run stays on the device that recorded it. The developer cannot see user data, because it is never transmitted.
How this is enforced
Everything below this section is the precise version. This one is the plain one: not what Stray promises, but what actually stops it. A promise is a sentence someone wrote. Each of these is a mechanism that has to be deliberately removed before the promise can break.
Your runs are encrypted on your phone
The database is stored encrypted, and the key lives in the phone's own secure store — the iOS Keychain or the Android Keystore — not in the app. If someone copies the file off your device, it reads as noise; it does not even announce itself as a database. This has been true on every install since version 0.25.5, and it is not a paid feature.
Your runs are kept out of backups
Photos and messages ride your iCloud or Google backup. Your runs deliberately do not, and neither do they travel in a phone-to-phone transfer when you set up a new handset. This is the one we went and checked rather than assumed: in August 2026 a full encrypted backup of a device running Stray was taken and its contents listed — 82,938 files, of which 32 belonged to Stray, and the run database was not among them.
The app can reach exactly one address, and only when you tap
Downloading an offline map is the only thing Stray uses the network for. The app checks the full address of the server it is about to contact — not just that it starts with the right name, which is the trick that fools most such checks — and refuses everything else. A separate check runs every time the app is built and fails the build outright if any other address appears anywhere in the code.
The voice speaks from your phone, or not at all
Android's speech engines offer network voices alongside on-device ones, and letting the phone choose would put an internet request in the middle of your run. Stray only ever speaks through a voice that works offline. Where a phone has none, it stays quiet and says so. The test we hold it to is a whole run in airplane mode — it still has to talk.
A setting that could hold a location is refused as you write it
Settings live in a small file that is included in an iCloud backup, so the rule is that nothing locational may go in it. That rule is not a review someone does later — the app rejects the write itself, so the mistake surfaces on a developer's machine rather than in a stranger's backup. This exists because it once went wrong: a coordinate was sitting in that file, and a security audit found it.
There is no analytics code, and the build fails if any appears
No Firebase, no Crashlytics, no Sentry, no advertising SDK — and rather than trusting ourselves to keep it that way, an automated check looks for them by name every time the app is built and refuses to produce a build if one has been added. The same check confirms no advertising ID is requested.
None of this makes Stray unbreakable, and it is not claimed to. What it means is narrower and more useful: the promise on the front page is wired into how the app is built, so breaking it takes a deliberate act rather than an oversight.
What is stored, and where
Stored locally on the device, in an app-private SQLite database and preferences store:
- GPS coordinates recorded during a run, plus derived route, distance, pace, splits, elevation
- Run date, duration, and the target you picked for that run
- A working copy of the run currently in progress, so a crash or a force-quit mid-run does not lose it. It is cleared once the finished run is safely stored
- Offline map areas you downloaded — the map tiles themselves, and for each area a centre point, a radius and a date, so the app knows which areas it already holds. A centre point is a coordinate: it is roughly where you asked for a map, which is usually roughly where you run
- App settings: language, theme, units, whether the voice is on, which voice you picked, and the target you last armed
The database is encrypted on the device. Since version 0.25.5 it is stored with SQLCipher, and the key is held in the iOS Keychain or the Android Keystore rather than in the app. Copied off the phone, the file is unreadable — it does not even identify itself as a database.
This data never leaves the device. There is no cloud sync, no backup to the developer's servers, and no export to third parties.
Backups and moving to a new phone
Your runs are deliberately excluded from the backup systems built into both platforms, so they do not travel to a cloud account or to a new handset:
-
Android — automatic cloud backup is disabled
(
allowBackup="false"), and all five data domains are additionally excluded from both Google's cloud backup and Android 12's phone-to-phone transfer. The second is a separate channel that the first setting does not clearly govern, so it is named explicitly. - iOS — the folder holding the database is marked as excluded from iCloud and iTunes/Finder backups, and it is marked on the folder rather than on the file, so the database's temporary companion files are covered too.
The honest consequence, and the honest caveat. The consequence: a new phone starts with an empty history. That is the trade — export a GPX and import it on the other device to carry runs across. The caveat: on iOS the small settings file is included in an iCloud backup. It holds your theme, units, language, voice choice and armed target, and never a location — the app refuses to store a coordinate there at all — but that is a rule the app keeps, not something the platform enforces for it.
Location
- Continuous location is used only while a run is active, and only after you start one. Stray does not request the "all the time" / background location permission, and nothing tracks you between runs.
- While a run records, a persistent notification is shown, and tracking continues with the screen off. Stray uses a foreground service for this, which is why that notification exists — it is what keeps the recording alive.
- One exception, and it is not a run: when you ask for an offline map of the area around you — on THE GRID, or on the setup card that offers the same thing — Stray takes a single position fix so the download is centred where you are rather than somewhere else. It reads one fix, then stops. That fix is not written down; what is saved is the map area you chose, as a centre point and a radius, so the app knows which areas it already holds.
- Location data is used solely to draw the route and compute run statistics on-device.
- Location is never transmitted, shared, or sold.
Network use — the single exception
Stray makes no network requests while recording, and has no analytics or telemetry.
The one exception is offline map downloads, which only
happen when you explicitly tap to download a map region. That request
goes to build.protomaps.com (Protomaps) and transmits the
coordinates of the map region you chose, so the server can return the map
tiles for that area. It does not include any run data, location history,
or device identifier. The downloaded map is then stored on-device and
used offline.
Stray may offer that download at two other moments — during first-time setup, and after importing GPX files whose routes fall outside the areas you already have. In both cases it is an offer: nothing is fetched until you tap.
This is the only outbound request the app makes. Worth knowing: choosing a region reveals to that server roughly which area you are interested in.
Permissions, and why each exists
Android
| Permission | Why |
|---|---|
| Fine / coarse location | Record the route while a run is active |
| Foreground service, and foreground service (location) | Keep recording with the screen off |
| Notifications | Show the "run in progress" notification |
| Promoted notifications | Show the live run in the status bar and on the lock screen on Android 16 |
| Internet | User-initiated offline map region download only |
| Network state | A reachability check, from the location library Stray builds on |
| Wake lock | Prevent the device sleeping mid-run |
Three permissions that used to arrive from libraries Stray depends on — fingerprint, biometric, and "run at boot" — are explicitly stripped out of the app, because Stray uses none of them. An app claiming nothing leaves your phone should not be asking for your fingerprint. There is also no advertising ID.
iOS
| Permission | Why |
|---|---|
| Location, while using the app | Record the route while a run is active. Stray does not ask for the "always" permission |
| Background mode: location | Keep measuring the run when the screen goes off or you switch app — without it the run stops mid-way |
| Background mode: audio | Speak your splits while the screen is off. iOS refuses to start speech in the background without it. Stray plays audio and never records any — there is no microphone permission |
Features that touch your data, and what they do with it
The spoken splits
Stray can call out your splits as you run. The speech is generated on the device by the phone's own voice engine, and only ever by a voice that works without a connection — Stray will not use a network voice even when the phone offers one. This is audio out only: there is no microphone permission, nothing is listened to, and nothing is recorded.
The lock screen and the status bar
While a run is going, Stray shows the live distance, pace and time on the Lock Screen and Dynamic Island on iOS, and in the status bar and lock screen on Android. That is drawn by the operating system from figures the app hands it directly on the same phone. Nothing is sent anywhere, and nothing about it persists once the run ends.
Exporting and importing GPX
Any run can be exported as a GPX file — a plain, open format every other fitness platform reads, so your history is never locked in here. The file is written to the app's temporary storage, handed to the system share sheet, and deleted the next time the app starts. Where you send it is entirely your decision, and it is the one way run data deliberately leaves the phone.
GPX files can also be imported, which is how you carry a history to a new phone. Imported files are read on the device and turned into runs like any other; nothing about an import is transmitted.
Retention and deletion
Data is kept until you delete it. Individual runs can be deleted in the app, downloaded map areas can be deleted from THE GRID, and uninstalling Stray removes the database and every run with it. Deletions overwrite the data rather than merely unlinking it. Since nothing is transmitted, there is nothing for the developer to delete on request.
Third parties, ads, children
No advertising, no third-party analytics SDKs, no data brokers, no sale or sharing of personal information. Stray is not directed at children under 13.
This website
The same standard applies to grunt.be itself, including this
page and the Stray pages. They are plain static files.
- No cookies. Nothing is written to your browser's storage, so there is no consent banner — there is nothing to consent to.
- No analytics and no advertising. No Google Analytics, no Google Ads, no Meta pixel, no tracking pixels of any kind, and no third-party tags.
-
No third-party requests at all. Fonts are self-hosted
rather than loaded from Google Fonts, and every image, stylesheet and
script is served from
grunt.be. Loading these pages sends your browser to no other company's server. - Nothing to submit. There are no forms, no newsletter, no sign-up, and no account.
One honest caveat: the site is hosted by Netlify, and like any web host it necessarily receives the IP address of each request in order to send the page back. That is ordinary server operation, not analytics — it is not used to profile visitors, and it is not combined with any app data, because the app sends none.
GDPR
Grunt SRL is established in Belgium, and the General Data Protection Regulation (EU) 2016/679 applies.
Because all processing happens locally on your own device and no personal data is transmitted to or held by the publisher, the publisher holds no user data to access, rectify, port, or erase. You retain full control through the app itself: the runs on your device are yours to view, export, or delete at any time.
Questions can go to stray@grunt.be. You also have the right to lodge a complaint with the Belgian supervisory authority, the Autorité de protection des données (autoriteprotectiondonnees.be).
Changes
Material changes will be reflected on this page, with an updated date at the top.