batchwatch

batchwatch › Data residency and transfer basis

Data residency and transfer basis

We know exactly what we hold, where it is processed, and what never reaches us — because the data model is deliberately narrow and we built it that way. This page states it plainly so a regulated buyer can answer their own compliance team without having to reverse-engineer our infrastructure.

This page answers one procurement question directly: where do the measurements live, and on what basis do they cross a border? Every technical claim was checked against the running code (src/), the schema (schema.sql) and the deployment config (wrangler.toml). It is the residency companion to DATA-PROCESSING.md and PRIVACY.md, which hold the full detail; this page does not repeat it, it points at it. It has not been reviewed by an external lawyer — if your process needs a counter-signed statement, write to hello@batchwatch.dev and we handle it as a contract, not as a web page.

We know exactly what we hold, where it is processed, and what never reaches us — because the data model is deliberately narrow and we built it that way. This page states it plainly so a regulated buyer can answer their own compliance team without having to reverse-engineer our infrastructure.


1. The short answer


2. Where the data physically lives

batchwatch is a single Cloudflare Worker backed by a single Cloudflare D1 database. There is no other datastore, no second cloud, and no on-premise component. That is the whole system, and it is small on purpose — a narrow surface is easier to reason about than a broad one.

Compute — Cloudflare Workers. Requests are served at Cloudflare's edge, close to the caller, wherever the caller is. The Worker code is src/; it is what gets deployed, with no hidden backend behind it.

Database — Cloudflare D1. Every measurement, key hash and counter lives in one D1 database, declared in wrangler.toml:

[[d1_databases]]
binding = "DB"
database_name = "batchwatch"
database_id = "cfc78264-b810-4ac9-af83-489ab11a43df"

D1 has one primary region that holds the authoritative copy; reads may be served from replicas nearer the caller.

The country code, and how it is derived. The one location-shaped field we store is call.region — a two-letter country code read from Cloudflare's cf-ipcountry edge header (src/index.js), which Cloudflare derives from the caller's IP at its edge. We store the country code, never the IP address. It is the contributor's own country, an attribute of the measurement row — it is not where the database lives.


3. The D1 primary region — stated as it is

The D1 primary region is not pinned in our configuration. wrangler.toml declares the database binding and id but sets no location_hint, so Cloudflare chose the primary region when the database was created. Because we do not assert a region we have not verified, this page does not claim an EU primary — see DATA-PROCESSING.md §5 and PRIVACY.md §9, which say the same thing.

This is a solvable, well-understood knob, not a limitation of the platform:

If an EU-primary guarantee is a hard requirement for your process, say so at hello@batchwatch.dev — it is a configuration we can commit to for a named customer, and §5 records it as an open decision so it is not lost.


4. The transfer basis

Cloudflare is a US-headquartered company operating a global network, so personal data may be processed outside the EEA. The lawful transfer mechanism is Cloudflare's Data Processing Addendum and its Standard Contractual Clauses, which govern transfers to the US and to Cloudflare's wider network.

Two things are true at once, and both are stated rather than one hidden behind the other:

For a buyer who needs the executed paperwork before onboarding, that is exactly the conversation hello@batchwatch.dev exists for — we would rather resolve it as a contract with a real customer than assert it is done when it is not.

5. Open decisions — for the operator, not the reader to guess

The residency and transfer story is truthful today. Three items still need a product or legal decision before this page can drop its qualifiers, and they are recorded here so they are decided on purpose rather than defaulted:

  1. D1 primary region — record, and decide whether to pin. Look up the current primary in the Cloudflare dashboard and write it into this page, DATA-PROCESSING.md §5 and PRIVACY.md §9. Then decide whether to pin an EU primary via location_hint (a recreate-and-reimport), or to keep the Cloudflare-chosen primary. Owner: operator.
  2. Counter-execute Cloudflare's DPA and SCCs, and do the transfer impact assessment. This is the paperwork that turns "the mechanism is the SCCs" into "the SCCs are in force". Owner: operator / legal.
  3. Retention periods. No automatic deletion is implemented in the code today — verified: there is no TTL, no scheduled purge and no DELETE statement in src/. Rolling query windows (30 days, 7 days, 1 hour) mean older rows stop influencing answers, but the rows are retained. Setting a retention bound for the trial and usage abuse-control records — and deciding the deliberately-unbounded term of the aggregate contribution — is a policy call, tracked in PRIVACY.md §6 and reflected in the licence term in TERMS.md §7. Owner: operator / legal.

Until each is settled, this page states the real position and does not overclaim. That is the point of writing it down: a buyer gets the truth, and the operator gets a short, closable list rather than an open-ended worry.

6. What a self-host or VPC deployment would answer — and why it is parked

A regulated buyer sometimes asks the stronger question: can the measurements never leave our infrastructure at all? — i.e. a self-host or VPC deployment of the prober. That option is parked: it is a platform build, and the decision (2026-08-29) is to answer the residency question with a page rather than shape the architecture around a customer we do not yet have. It reopens the moment a named customer needs it. For almost every buyer, the question underneath it — where does the data live and on what basis does it transfer? — is answered above, today, without one.

7. Contact

hello@batchwatch.dev · Stenager Consulting ApS, CVR 44456923, Stenagervaenget 45, 7100 Vejle, Denmark.