batchwatch

batchwatch › Data Processing

Data Processing

Version 0.1 · draft of 25 August 2026 · companion to PRIVACY.md

Draft. Not legal advice. Written by the developer who built the service, not by a lawyer. It is accurate about the system — every technical claim was checked against src/ and schema.sql — but an Art. 28 agreement is a contract, and this one has not been drafted or reviewed by anyone qualified to draft one. Do not sign or publish this before a lawyer has reviewed it.

Placeholders in [SQUARE BRACKETS] must be filled in before use.

Version 0.1 · draft of 25 August 2026 · companion to PRIVACY.md


1. Read this first: we are usually not your processor

The front page links to a "data processing agreement", and customers' procurement teams will ask for one. But the honest analysis is that for almost everything batchwatch does, we are a controller in our own right, not a processor acting on your instructions.

The reasoning:

So the instrument you actually need from us is a controller-to-controller data sharing statement, which is §§2–8 below. §9 is a fallback Art. 28 processor annex that engages only in the narrow case described there.

Getting this the wrong way round matters. Signing a standard Art. 28 processor DPA would describe a relationship that does not exist, oblige us to "process only on documented instructions" while we plainly do not, and oblige us to "delete or return all personal data at the end of the provision of services" — which directly contradicts the perpetual aggregate licence the terms take. A lawyer must confirm the characterisation before anything is signed.


2. What personal data is actually involved

Most of what we hold is not personal data at all: token counts, model names, timestamps, and durations describing machine behaviour.

The parts that are, or may be:

DataWhy it may be personal data
trial.identity = ip:<salted SHA-256>Pseudonymised IP address. We hold the salt, so re-identification is trivially possible for us. See PRIVACY.md §4
usage.identity = newkey:<salted SHA-256>Same construction, used for the key-creation limit
api_key.labelFree text chosen by the key holder. Intended for prod-pipeline-style notes, but nothing stops a personal name
call.model, call.endpointFree text from the submitter. Intended for model names and API paths; stored verbatim
api_key + call rows togetherWhere a key belongs to a sole trader or an individual developer, the pattern of that key's activity is data about them
call.regionCountry code only. Not identifying alone; an attribute of a key's record when combined

Categories of data subject: developers and operators who create API keys or call the API; visitors to the dashboard (at the Cloudflare edge only). No end users of your applications — nothing about them ever reaches us.

No special categories (Art. 9) and no criminal-offence data are involved, intended or foreseeable.

What is never received: prompts, completions, system prompts, tool definitions, function schemas, provider API keys, end-user identifiers, request IDs. The client library reads timing and token counts off the job and never touches the payload; it is open source, ~90 lines, and that is the point of publishing it.


3. Nature, purpose and duration

Nature: collection, storage, aggregation and publication of queue-time measurements; authentication of API keys; counting of trial calls and quota.

Purpose: operating batchwatch — building a public dataset of LLM batch API queue times, answering queries against it, and commercialising access to the aggregate.

Duration: for as long as the service operates. No automatic deletion is implemented in the code today — verified: there is no TTL, no scheduled purge, and no DELETE statement anywhere in src/. Rolling query windows (30 days, 7 days, 1 hour) mean older rows stop influencing answers, but they are retained. Setting and implementing retention periods for trial and usage is an open item, recorded in PRIVACY.md §6.


4. Security measures actually in place

Stated as what exists, not as what a template would claim.

In place:

Not in place — state these honestly to any customer who asks:


5. Sub-processors

Sub-processorRoleLocation
Cloudflare, Inc.Compute (Workers), database (D1), CDN and edge terminationUS-headquartered, global network. Database region: see below

Cloudflare is the only sub-processor. There are no others — no analytics vendor, no email provider in the request path, no hosting beyond Cloudflare.

The D1 region is not pinned in our configuration. wrangler.toml declares the binding and the database id but no location_hint; the primary region was chosen by Cloudflare at creation time. This must be looked up in the Cloudflare dashboard and stated here before this document is given to anyone. Do not assert an EU region until it has been checked. If an EU primary is required for a customer, D1 supports a location hint at database creation and moving would mean recreating the database.

Before launch:

Our prober calls OpenAI, Anthropic and Google using our own API keys and our own toy jobs (8 tokens in, 5 out). Those providers are not sub-processors of anyone's data: no customer data is sent to them, ever.


6. International transfers

Cloudflare is a US company operating a global network, so personal data may be processed outside the EEA. The basis is Cloudflare's DPA and SCCs, which must be executed. A transfer impact assessment should be done as part of that, and is not done yet.


7. Data subject requests

We handle requests directly, as controller — see PRIVACY.md §7, which sets out exactly what can and cannot be deleted and why.

The one point worth repeating here, because it surprises people: we cannot action a deletion request for measurements submitted without an API key. key_id is NULL on those rows and nothing links them to a person. Art. 11 GDPR applies. If deletability matters to you, submit with a key.

There is no self-service route for export or deletion. Both are manual operations by the operator. Key revocation is the one thing you can do yourself, and it does not by itself delete measurements.


8. Personal data breach

If we become aware of a breach affecting personal data we hold, we will notify affected controllers and, where required, Datatilsynet, without undue delay and in any event within 72 hours of becoming aware.

Realistically, the breach scenarios worth naming are:

  1. Compromise of the Cloudflare account. This is the whole system.
  2. Disclosure of TRIAL_SALT, which would make the stored IP hashes brute-forceable back to addresses — the exact risk the salt exists to prevent.
  3. Database exfiltration. Contents would be measurement metadata, token hashes (not usable to authenticate), key labels and salted IP hashes. No prompts, no completions, no provider credentials, no email addresses, no passwords — because none of those are ever collected.

9. Fallback: Art. 28 processor terms

These terms apply only if, and only to the extent that, we in fact process personal data on your documented instructions — realistically only where you have placed personal data into the free-text model, endpoint or key label fields, which ACCEPTABLE-USE.md §2.9 asks you not to do.

Where they apply, we will:

  1. Process that data only on your documented instructions, including as to transfers, unless required otherwise by EU or Member State law.
  2. Ensure persons authorised to process it are bound by confidentiality.
  3. Apply the measures described in §4.
  4. Not engage a sub-processor other than those in §5 without prior notice and an opportunity to object.
  5. Assist you, so far as reasonably possible, with data subject requests and with Arts. 32–36 obligations.
  6. Notify you without undue delay on becoming aware of a breach affecting that data.
  7. At your choice, delete or return that data at the end of the provision of the service, and delete existing copies unless retention is required by law.
  8. Make available the information reasonably necessary to demonstrate compliance and allow audits — see the limits below.

Audit: as a single-operator service, we cannot host an on-site audit. We will answer a written security questionnaire and provide the Cloudflare DPA and any Cloudflare compliance reports we are permitted to pass on.

Scope limit that must be preserved in any negotiated version: clause 7 above (delete or return) applies only to data processed on your instructions under this §9. It does not apply to the measurements you contributed. Those are covered by the perpetual aggregate licence in TERMS.md §7, which is a controller-to-controller arrangement, not a processing instruction. Any customer redline that extends the deletion obligation across that boundary changes the product's foundation and must be escalated, not accepted.


10. Contact

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

No Data Protection Officer is appointed. Whether one is required under Art. 37 should be assessed: the trigger to examine is "regular and systematic monitoring of data subjects on a large scale", and the argument that it does not apply is that we monitor queues, not people, and hold per-person data only as bounded, salted hashes for abuse control. That argument should be confirmed by a lawyer and written down, not assumed.


Open items before this document leaves the building

  1. Confirm the controller/processor characterisation in §1. Everything else depends on it.
  2. Establish and state the D1 primary region. §5.
  3. Execute the Cloudflare DPA and SCCs, and do a transfer impact assessment. §§5–6.
  4. Set and implement retention periods, at minimum for trial and usage. §3.
  5. Decide the sub-processor change notice period. §5.
  6. Assess the DPO trigger and record the conclusion. §10.
  7. Fill in every [SQUARE BRACKET].