You know the drill. A former user emails your DPO inbox. Per Article 15 of the GDPR, they want a complete copy of every personal datum you hold on them. They want it within thirty days. They want it to include the source, the purpose, the recipients with whom you've shared it, and the logic of any automated decisions. They have a lawyer.
Your data is in fifteen places — Postgres, S3, Snowflake, Salesforce, Zendesk, Mixpanel, Stripe, your own product database, your CRM, your support tool. Even the engineer who built the integration to Klaviyo three years ago doesn't remember which field carries the consent flag. Reconciling all of it by hand takes two senior engineers about a week. Outside privacy counsel bills six hundred euros an hour. If you miss one source, the Data Protection Authority can fine you up to four percent of global revenue.
The math says one DSAR costs about €35,000. Big EU companies field a hundred or more a year. That's a real engineering team's budget, gone to evidence reconciliation.
What the engineering work actually is
If you trace what makes a DSAR slow, it's the same three things every time:
- Subject reconstruction. "Find every record about this person." Trivial if your data is in one graph, very hard if it's in fifteen systems with subtle ID mismatches.
- Purpose binding evidence. "Prove you used my data only for what you said." This requires per-read annotation at the point of access — almost no production stack has it.
- Automated decision lineage. Article 22 lets the user demand the logic behind any automated decision that affected them. Most ML systems can't produce this — the model card lives in MLflow, the input features live in a feature store, the rule that fired isn't logged.
If you had a single bitemporal graph that stored all of it natively, none of this would be hard. You'd write one Cypher query.
The one-query answer
MATCH (u:User)
WHERE u.email = $subject
OPTIONAL MATCH (u)-[:PROFILE_ATTR]->(p)
OPTIONAL MATCH (u)-[:GENERATED]->(e:Event)
OPTIONAL MATCH (u)-[:AUTOMATED_DECISION]->(d:Decision)
OPTIONAL MATCH (u)-[:SHARED_WITH]->(proc:Processor)
RETURN u, collect(p), collect(e), collect(d), collect(proc)
That's the whole reconstruction. Every profile attribute. Every event the user generated. Every automated decision that touched their profile. Every downstream processor we shared it with. With AT RECORDED, you can run the same query at any point in the past — useful when the lawyer asks what did you know about my client on March 15?
The Article 5(1)(b) purpose-binding proof is one more procedure: db.aclEvents returns every read of the user's data with its declared purpose. Marketing reads tagged "marketing." Billing reads tagged "billing." If any read happened outside its declared purpose, the chain shows it.
Article 22 — the right-to-explanation — is a graph walk. db.derivedFrom on the decision node returns every input that fed it: the user's profile, the model version, the firm's policy in force, the events from the past week. Every input cryptographically signed at the moment it was captured.
Article 17 — the right to erasure — is the hardest GDPR primitive to ship correctly. You can't delete the data without breaking the audit log the DPA needs to verify your compliance. So you don't delete. You crypto-shred. The user's per-subject AES key is destroyed in the HSM. The data becomes ciphertext that no one — including you — can read. The audit chain stays intact. The user gets a signed certificate. The DPA can still verify Article 30.
The numbers
InvariantDB customers running the Article 15 query above answer DSARs in about 60 seconds. That's not an exaggeration — it's the actual single-query latency, including the Article 22 lineage walk and the Article 5(1)(b) purpose-binding chain verification. The DPA fine risk goes from up to 4% of global revenue to zero.
You can run it yourself in the live walkthrough — pick the Privacy tab and watch the whole flow. Onyx narration, ninety seconds.