Data residency
This page covers where your data physically lives, what counts
as "customer data" for residency purposes, and how the
region account preference shapes routing.
The short answer
- Driftstack runs primarily in the EU (Hetzner Falkenstein / Nuremberg).
- Customer-facing API endpoints are served from the same EU region.
- The
regionpreference onPATCH /v1/account/me(us,eu, orapac) is currently informational — every request is served from EU regardless of the value stored. The field exists so customers signalling intent can record it now without needing a schema change later. - Object storage (R2) is geo-replicated across Cloudflare's EU + US regions; presigned URL access is location-agnostic.
What counts as customer data
| Category | Stored where | Notes |
|---|---|---|
| Account row (email, tier, slug, region pref, MFA secret) | Postgres (Neon, EU) | MFA secret AES-256 encrypted with MFA_ENCRYPTION_KEY |
| API keys (hashed) | Postgres (Neon, EU) | scrypt logN=15; plaintext never stored |
| Sessions metadata | Postgres (Neon, EU) | Lifecycle rows + events; no payload |
| Profile metadata | Postgres (Neon, EU) | Name, archetype, description only |
| Profile state blob (cookies, localStorage) | WebKit driver layer, EU host | Per-profile encrypted file on disk |
| Session recordings (WebM) | R2 (Cloudflare, EU + US replication) | Object-level S3-SSE; presigned URLs 1h TTL |
| Audit log entries | Postgres (Neon, EU) | Append-only; tier-dependent retention |
| Webhook deliveries | Postgres (Neon, EU) | Payload + response excerpt; 7-day retention |
| Stripe customer / payment data | Stripe (US) | We never see card numbers. Stripe customer_id is the linkage. |
| NowPayments order metadata | NowPayments (EU, Estonia) | We see payment_id + status only; on-chain data stays on-chain. |
| Cache (Redis) | Upstash (EU) | Auth cache, rate-limit counters, MFA-challenge tokens — all short-lived (≤5 min TTL). |
| Sentry error events | Sentry EU (ingest.de.sentry.io) | Code-level errors with redacted body fields. PII filter strips emails before send. |
| Email delivery (transactional) | Postmark (EU sending region) | Recipient address + template payload only. See /trust/sub-processors for the transfer-mechanism breakdown. |
What never leaves the EU
- Database content (Postgres, Neon EU).
- Cache content (Redis, Upstash EU).
- Profile state blobs on the driver host (EU).
- Session-execution traffic between the API server, the browser driver, and the customer's target URL.
What does leave the EU
- Recordings via R2: Cloudflare replicates across regions to minimise playback latency. If you require strict EU-only storage for recordings, contact us — we can configure your account with single-region (EU-only) R2.
- Stripe billing data: Stripe Payments Europe Ltd (Ireland) is the contracted entity. The PCI-DSS compliance contract is between you and Stripe; we only hold the customer_id linkage. Stripe may onward-transfer to sub-processors under SCCs + EU-US DPF — see /trust/sub-processors.
- Anthropic (bundled-LLM only): the bundled-LLM agent is opt-in. When enabled, prompts + completions traverse Anthropic (US) under SCCs + EU-US DPF. BYOK accounts bypass this entirely.
- MacStadium (session execution): the iPhone Safari driver fleet runs on MacStadium hardware (US). Session-execution traffic between the API server and the driver fleet uses Driftstack-managed VPN tunnels; contractual transfer is via SCCs + EU-US DPF.
The region account preference
Set on the account via PATCH /v1/account/me:
PATCH /v1/account/me
Authorization: Bearer ds_live_…
{ "region": "eu" }
Accepted values: us, eu,
apac, or null (unset).
Today: the field is informational. We surface it on the account-me response and use it as a tag in our observability stack so we can prioritise where to add PoPs.
Roadmap: once additional PoPs exist (planned
for US + APAC in 2026), API routing will land sessions for
region: us accounts on US infrastructure, and
region: apac on APAC. The account row will still
live in the EU primary; sessions + recordings will live in the
preferred region.
GDPR / DSAR / right-to-erasure
Customer accounts can be deleted on request. We hold a 30-day grace period for accidental delete recovery, after which the account row + all linked resources (sessions, profiles, recordings, audit log, webhook deliveries) are purged. Stripe + NowPayments customer references are removed from our side; their own retention policies govern what they keep beyond that.
Data subject access requests: [email protected].
Subprocessor list
Up-to-date subprocessor list with regions, purpose, and DPA links: /legal/sub-processors.
Support
Residency / compliance questions: [email protected].