---
title: Protect User Privacy with Notecard Location Fuzzing
description: Your product may need to know where it is, but your customers probably don't want it reporting their street address. Learn how Notecard can obfuscate location data.
source_url: https://dev.blues.io/blog/notecard-location-fuzzing-privacy/
canonical_url: https://dev.blues.io/blog/notecard-location-fuzzing-privacy/
markdown_url: https://dev.blues.io/blog/notecard-location-fuzzing-privacy.md
---

# Protect User Privacy with Notecard Location Fuzzing

![Protect User Privacy with Notecard Location Fuzzing banner](https://dev.blues.io/images/blog/posts/notecard-location-fuzzing-privacy/banner.png?v=917c6aca)

September 25, 2026

## Your product may need to know where it is, but your customers probably don't want it reporting their street address. Learn how Notecard can obfuscate location data.

- [Notecard](https://dev.blues.io/blog/tag/notecard)
- [Notehub](https://dev.blues.io/blog/tag/notehub)
- [GPS/GNSS](https://dev.blues.io/blog/tag/gps-gnss)
- [Security](https://dev.blues.io/blog/tag/security)

[![Rob Lauer](https://dev.blues.io/images/blog/authors/rob-lauer.jpg?v=57fb21a7)](https://dev.blues.io/blog/author/rob-lauer/)

[Rob LauerSenior Director of Developer Relations](https://dev.blues.io/blog/author/rob-lauer/)

Say you're building a residential air quality monitor (hey, like [Blues Airnote](https://shop.blues.com/products/airnote?utm_source=dev-blues\&utm_medium=web\&utm_campaign=store-link)). Your customers are likely to mount it on a porch railing or a fence post, it'll report AQI readings every hour, and your cloud app will plot every device on a public map so neighbors can watch wildfire smoke roll through town.

That public map needs each device's location. However, it does *not* need that location to be accurate to someone's front door.

*As an aside, this is what my Airnote dashboard looked like this summer as that aforementioned wildfire smoke hit us:*

![airnote dashboard](https://dev.blues.io/images/blog/posts/notecard-location-fuzzing-privacy/airnote-map.png?v=e63ed5dd)

The trouble is that a GPS/GNSS receiver under open sky routinely resolves a position to within a few meters. That's easily enough to pick out a single house. The same problem shows up across many different types of connected products: a vehicle's GPS coordinates can identify its driver, a wearable's coordinates can reveal where someone sleeps, and an unattended sensor's exact location can tell a vandal where to find it.

A common fix is to **strip a few decimal places in the cloud** before displaying anything. That certainly helps privacy on any public map, but the precise coordinates have still crossed the network, landed in your event store, and flowed into every log, backup, and downstream integration that touches the data.

All is not lost though, as [Blues Notecard](https://blues.com/products/notecard/) can perform this "fuzzing" of location coordinates **on the device** instead, with a single [environment variable](https://dev.blues.io/guides-and-tutorials/notecard-guides/understanding-environment-variables.md): `_gps_fuzz_degrees`.

![Two copies of the same neighborhood map. On the left, a precise GPS fix. On the right, with \_gps\_fuzz\_degrees set to 0.01, a grid covers the map and the reported coordinate marks only the southeast corner of a shaded grid cells.](https://dev.blues.io/images/blog/posts/notecard-location-fuzzing-privacy/fuzzing-hero-precise-vs-fuzzed.svg?v=6447a174)

## What "Location" Means to Notecard and Notehub

Before configuring anything, it's worth knowing where a Notecard-based device's location actually comes from, because there are three possible sources:

1. **GPS/GNSS.** Notecard models with a GNSS receiver (i.e. any Notecard with a cellular modem) compute a fix on the device, as does a Notecard with an [external GPS module](https://dev.blues.io/notecard/notecard-walkthrough/working-with-the-notecard-aux-pins.md#using-aux-serial-gps-mode) connected to its AUX pins. The fix shows up in `card.location` responses, in `_track.qo` Notes, and in the `where_*` fields Notehub appends to every event.
2. **Cell tower location.** Notecard reports the ID of the tower it's connected to, and Notehub looks up that tower's position (the `tower_*` fields).
3. **Triangulation.** If you enable it with `card.triangulate`, Notecard uploads nearby WiFi access point and cell tower scan data, and Notehub resolves an estimated location (the `tri_*` fields).

Notehub then picks the best available option and exposes it as the `best_*` fields (the full list is in [Data Notehub Appends to Events](https://dev.blues.io/notehub/notehub-walkthrough.md#data-notehub-appends-to-events)).

Notice the difference in those three options. The first source is **computed on the device**, while the other two are computed in Notehub from data the device sends. A useful privacy control has to cover both places, and `_gps_fuzz_degrees` does just that. Notecard applies it to GPS/GNSS coordinates before they leave the device, and **Notehub applies the same fuzzing calculation to the tower and triangulated locations** it computes.

![Data flow diagram showing the two places location fuzzing is applied](https://dev.blues.io/images/blog/posts/notecard-location-fuzzing-privacy/location-fuzzing-data-flow.svg?v=7e9a7428)

> **Note:**
>
> There are two potential gaps to keep in mind for your product design:
>
> 1. Fuzzing only covers the location Notecard itself determines. It's unlikely, but if your **host MCU supplies its own coordinates** (say, from a separate GPS module), Notecard stores them exactly as given, whether they're in a Note body or attached to the Note as location metadata.
>
> 2. Notecard still sends Notehub the **network data** it uses for location. The ID of the cell tower it's connected to goes up with each session (and routed events carry it as `tower_id`), and with triangulation enabled, Notecard firmware through v11.3.2 also uploads raw WiFi access point and cell tower scans. For the strictest designs, set the `_suppress_tower` and `_suppress_tri` environment variables.

## How Grid Snapping Works

The value you specify for `_gps_fuzz_degrees` is a grid size in decimal degrees. Every coordinate Notecard reports is "snapped" to a multiple of that value by dropping the extra precision. For example, with a value of `0.001`, device coordinates would appear like so:

| Real coordinate | Reported coordinate |
| --------------- | ------------------- |
| `42.5779`       | `42.577`            |
| `-70.8729`      | `-70.872`           |

To be clear, that's truncation, not rounding, so values always move *toward zero*. `42.5779` becomes `42.577` rather than `42.578`, and `-70.8729` becomes `-70.872` rather than `-70.873`. Notecard and Notehub use the same math, so a device's GPS, tower, and triangulated locations all land on the same grid.

The grid is measured in degrees, and a degree of longitude shrinks as you move away from the equator, so the cells are rectangles rather than squares. Here's what that looks like at 45° latitude (e.g. Minneapolis, Bordeaux, or Turin):

| `_gps_fuzz_degrees` | Cell size at 45° (N–S × E–W) | Roughly the scale of |
| ------------------- | ---------------------------- | -------------------- |
| `0.0001`            | 11 m × 8 m                   | A single building    |
| `0.001`             | 111 m × 79 m                 | A city block         |
| `0.01`              | 1.1 km × 0.79 km             | A neighborhood       |
| `0.1`               | 11 km × 7.9 km               | A small town         |

Now why would you want to use a fixed grid like this instead of random noise? The obvious alternative is adding a random offset to every fix. The problem is that a device that doesn't move keeps reporting, and averaging a few hundred noisy reports can lead you right back to the true position! A grid is deterministic, so there's nothing to average: every fix that lands in the same cell reports the same corner. The catch is a device sitting near a cell edge, where ordinary GPS jitter can flip it back and forth between two neighboring cells. That doesn't reveal the exact spot, but it does tell an observer the device is close to that line.

## Enabling Location Fuzzing

### Step 1: Pick a Grid Size

Ask yourself this question: "what's the smallest area my product *actually* needs to know about?"

For instance, a regional air quality map should work fine at `0.01`. Something like sales territory or regulatory reporting might only need `0.1`. If you can't say why you need a precise location, you probably don't need one!

Also consider where your devices will live. A `0.001` cell in a city might contain dozens of homes, but the same cell in farm country might contain exactly one, and a snapped coordinate that maps to one house is still a home address. If your devices ship to rural customers, size the grid for them, not for your downtown beta testers.

![Two maps share an identical grid of 0.001-degree cells, about 111 m by 79 m at 45 degrees latitude. In the urban map, one highlighted cell contains dozens of rowhouses. In the rural map, the highlighted cell contains a single farmhouse and barn, so a snapped coordinate still points to one home. An inset shows the same countryside under a coarser 0.01 grid, where one cell spans several farms.](https://dev.blues.io/images/blog/posts/notecard-location-fuzzing-privacy/fuzzing-density-urban-vs-rural.svg?v=12c3b4a4)

### Step 2: Set It in Firmware

Set the value from your host firmware with the [env.default](https://dev.blues.io/api-reference/notecard-api/env-requests.md#env-default) API. This way fuzzing is in effect from the device's first boot, before it has ever synced with Notehub:

```json
{
  "req": "env.default",
  "name": "_gps_fuzz_degrees",
  "text": "0.01"
}
```

Like every environment variable, the value is passed as a string in `text`.

> **Tip:**
>
> Send the command during setup, **before** you configure `card.location.mode` or add any Notes.

The ordering of these commands in firmware matters because **fuzzing isn't retroactive**. Notecard applies the grid at the moment it reads its location, and a Note captures its location when it's added. Anything queued before the setting took effect keeps whatever precision it had.

### Step 3: Mirror Preferences in Notehub

You can also set `_gps_fuzz_degrees` as a [project or fleet environment variable](https://dev.blues.io/guides-and-tutorials/notecard-guides/understanding-environment-variables.md#setting-a-fleet-variable) in Notehub, which is the easiest way to apply it to thousands of devices at once. Fleets also let you vary the policy, for example fuzzing every customer unit while leaving your own test devices at full precision.

If you rely on tower or triangulated locations, I'd set the same value in both places (on device and in Notehub). That way Notehub's side of the policy doesn't depend on when a device first reports its defaults.

> **Note:**
>
> In the [environment variable hierarchy](https://dev.blues.io/guides-and-tutorials/notecard-guides/understanding-environment-variables.md#the-hierarchy-of-environment-variables), device, fleet, and project variables in Notehub all take precedence over an `env.default` value. Anyone who can edit those variables can loosen (or remove) the fuzzing your firmware set. That's handy for fleet management, but it means your privacy guarantee is ultimately enforced by Notehub access control, not by the hardware.

### Step 4: Check the Output

After a GPS fix is made, a [card.location](https://dev.blues.io/api-reference/notecard-api/card-requests/latest.md#card-location) request will return lat/lon coordinates snapped to the `0.01` grid from Step 2:

```json
{
  "status": "GPS updated (58 sec, 41dB SNR, 9 sats) {gps-active} {gps}",
  "mode": "periodic",
  "lat": 42.57,
  "lon": -70.87,
  "time": 1598554399
}
```

In Notehub, the `where_*` fields on every event are derived from that reported point.

## Some Location Data Stays Precise

It's important to note that Notecard's internal motion detection and [geofence](https://dev.blues.io/notecard/notecard-walkthrough/time-and-location-requests.md#geofencing-with-the-notecard) logic keep working from the real GPS fix. If those features ran on the fuzzed location, a device parked near a boundary could appear to "move" a full grid step every time its fix jittered across the line, and a 100-meter fence would be meaningless inside a 1-kilometer cell. Because Notecard evaluates its geofence against the precise fix, you can still send an alert from a device whose reported location is only accurate to the neighborhood.

## Where to Fuzz Location: Device, Cloud, or App

Fuzzing on Notecard isn't the only way to reduce location precision, so it's worth comparing it to the alternatives:

| Approach                               | Precise location leaves the device? | Precision recoverable later? | Good fit for                                         |
| -------------------------------------- | ----------------------------------- | ---------------------------- | ---------------------------------------------------- |
| Suppress location (`_suppress_*`)      | No                                  | No                           | Products that don't need location                    |
| Fuzz on Notecard (`_gps_fuzz_degrees`) | No (GPS/GNSS)                       | No                           | Coarse location, minimized at the source             |
| Fuzz in a Notehub route or your app    | Yes                                 | Yes                          | Precise internally, coarse for customers or partners |
| Full precision                         | Yes                                 | N/A                          | Asset tracking, where precision *is* the product     |

Note that sometimes the right answer is no location at all! The `_suppress_where`, `_suppress_tower`, and `_suppress_tri` environment variables stop each category of location data from leaving Notecard entirely ([details here](https://dev.blues.io/notecard/notecard-walkthrough/time-and-location-requests.md#suppressing-location-data)).

Cloud-side fuzzing, using a [JSONata transform](https://dev.blues.io/guides-and-tutorials/notecard-guides/using-jsonata-to-transform-json-in-notehub.md) in a Notehub route or logic in your own app, is the right call when you genuinely need both views: precise for your own operations, coarse for a public map or a partner feed. Just be honest that the precise data then exists in Notehub and everywhere you route it, and your privacy story depends on securing all of it.

On-device fuzzing is the strongest option that still gives you a location. Precision you never collect can't leak, and "the device never sends it" is a lot easier to explain to a customer than a chain of access controls.

## Summary

If your product needs to know roughly where it is, but your customers would be uncomfortable with it knowing exactly where *they* are, `_gps_fuzz_degrees` is the simplest privacy control you can add. It's one environment variable, it covers GPS/GNSS on the device and tower and triangulated locations in Notehub, and it leaves geofencing and motion detection intact.

For the full reference, read [Location Privacy with GPS Fuzzing](https://dev.blues.io/notecard/notecard-walkthrough/time-and-location-requests.md#location-privacy-with-gps-fuzzing) in the Notecard walkthrough, and browse the [reserved environment variables](https://dev.blues.io/guides-and-tutorials/notecard-guides/understanding-environment-variables.md#reserved-environment-variables) for the other location controls mentioned here.

Happy hacking! 💙

## Frequently Asked Questions

**What is GPS fuzzing on Blues Notecard?**

GPS fuzzing is a privacy feature controlled by the `_gps_fuzz_degrees` reserved environment variable. Notecard snaps the GPS/GNSS location it determines to a grid of the size you specify, in decimal degrees, before that location leaves the device. Notehub applies the same grid to the cell tower and triangulated locations it computes, so all of a device's reported locations share the same reduced precision.

**How do I enable location fuzzing on a Notecard?**

Send an `env.default` request from your host firmware with `name` set to `_gps_fuzz_degrees` and `text` set to the grid size as a string, such as `"0.01"` for a cell roughly one kilometer across. You can also set the variable at the project, fleet, or device level in Notehub. Setting it in firmware ensures fuzzing is active from the device's first boot, before it has ever synced with Notehub.

**Does GPS fuzzing break geofencing or motion tracking?**

No. Fuzzing is applied when location data leaves Notecard. Notecard's internal geofence and motion detection logic continue to use the precise GPS fix, so a geofence stays accurate even when the reported coordinates are fuzzed.

**Where is the real location relative to a fuzzed coordinate?**

Notecard and Notehub truncate toward zero rather than rounding, so the reported coordinate is a corner of the grid cell, not its center. The real location lies between the reported value and one grid step farther from zero on each axis. For a device in North America (positive latitude, negative longitude), that means it is somewhere north and west of the reported point.

**Can I recover a device's precise location after enabling fuzzing?**

Not for data that was already reported. For the location Notecard determines itself, the extra precision is discarded on the device and never transmitted. You can turn fuzzing off for a single device going forward by setting a device-level `_gps_fuzz_degrees` variable to `0` in Notehub, which takes precedence over fleet, project, and `env.default` values.
