Account Deletion & Data Export: Ship GDPR/CCPA Without Breaking Your Database
Account Deletion & Export Strategy for Your New SaaS
Goal: Ship account deletion and data export flows that satisfy GDPR / CCPA / similar regulations, give customers a self-serve path, and don't break your foreign-key constraints, your audit trail, or your billing reconciliation. Avoid the failure modes where founders ship "email us to delete" (illegal in EU after 30 days; expensive in support time everywhere), hard-delete user rows and orphan every related record, or export "all user data" by dumping a JSON blob nobody can use.
Process: Follow this chat pattern with your AI coding tool such as Claude or v0.app. Pay attention to the notes in [brackets] and replace the bracketed text with your own content.
Timeframe: Soft-delete + 30-day cooling-off + permanent purge job shipped in week 1. Data export endpoint + portable JSON/CSV bundle in week 2. Self-serve UI + audit + customer docs in week 3. Quarterly retention review baked in.
Why Most Founder Deletion Flows Are Broken
Three failure modes hit founders the same way:
- "Email us to delete." Founder skips building the self-serve flow. EU customer requests deletion under GDPR Article 17. Support agent finds the user, tries to delete the row, hits a foreign-key violation on
posts, panics, escalates to engineering, two days pass, GDPR's 30-day window starts looking tight. Repeat 50 times in year two and the support cost dwarfs what building the feature would have taken. - Hard-delete that orphans relationships. Founder runs
DELETE FROM users WHERE id = ?. Cascades destroy posts, comments, audit logs, and invoices. Now collaborators see "[deleted user]" everywhere; the audit trail is broken; the billing reconciliation system can't link a refund to a user. Worse: if the cascade missed something (foreign-key NOT defined ON DELETE CASCADE), the data lingers in shadow tables nobody knows about. - Export as raw JSON dump. Founder ships
GET /api/me/exportreturning everything in their internal schema with internal IDs. Customer receives 8MB of{"_id": "uuid...", "createdAt": "2024-01-15T...", "isActive": true, "stripe_customer_id": "cus_..."}and has no idea what to do with it. Customer files complaint with regulator: "the export wasn't usable."
The version that works is structured: soft-delete with a cooling-off window, permanent purge as a scheduled job, well-formed exports as portable JSON+CSV bundles, audit of every delete/export, and clear customer docs explaining what gets deleted vs retained.
This guide assumes you have already done Authentication (deletion is user-scoped), have shipped Multi-Tenant Data Isolation (workspace deletions are different from user deletions), have shipped Audit Logs (every delete/export is a high-value audit event), have considered Roles & Permissions (RBAC) (admins can delete other users; users can delete themselves), and have a strategy for Email Deliverability (the confirmation emails matter).
1. Understand Your Legal Obligations First
Before writing code, know what regulations actually require. This is one of the few product areas where ignorance has fines attached.
Help me document the legal obligations for [my product].
The key regulations and what they require:
**GDPR (EU)**
- **Right to erasure (Article 17)**: customer can request deletion; you have 30 days to respond
- **Right to portability (Article 20)**: customer can request their data in a "structured, commonly used, and machine-readable format"
- **Right to access (Article 15)**: customer can request a copy of their personal data
- Applies to ANY company processing data of EU residents (regardless of company location)
- Fines: up to 4% of global revenue or €20M, whichever is greater
**CCPA / CPRA (California)**
- Similar to GDPR: right to delete, right to know, right to portability
- 45 days to respond (extendable to 90)
- Applies to companies meeting size thresholds (revenue, data volume) doing business in California
- Fines: $2,500-$7,500 per violation
**Other regulations to know about**:
- LGPD (Brazil) — similar to GDPR
- PIPEDA (Canada) — privacy framework
- VCDPA (Virginia), CPA (Colorado), TDPSA (Texas) — US state laws
- HIPAA (US healthcare) — separate; has its own deletion rules
- COPPA (US children) — additional restrictions
**What is "personal data"**:
- Direct identifiers: name, email, phone, IP address, account ID
- Indirect: purchase history, usage logs, communications, preferences
- Edge cases that ARE personal data: cookies, browsing patterns, IP-tied analytics
**What CAN be retained even after deletion**:
- Data needed for legal obligations (tax records, fraud prevention) — typically 7 years
- Data needed for legitimate interests (e.g., security audit logs, with anonymization)
- Aggregated statistics where the user can no longer be identified
- Document each retention reason in your privacy policy
**Document for my product**:
1. Which regulations apply (depends on customer geography and your size)
2. The legal basis for processing each data type
3. The retention periods per data type (and why)
4. The deletion-exception list (data you''ll retain post-deletion and the legal basis)
Output:
1. The regulations checklist
2. The retention table (data type → retention period → legal basis)
3. The deletion-exception list with citations
4. Whether to consult a privacy lawyer (almost always: yes for first version)
The biggest unforced error: assuming "we''re too small for GDPR." GDPR applies to any company with EU users, regardless of size. The €20M fine cap is theoretical for a 5-person startup, but the regulator can and does issue cease-and-desist orders that can shut down a SaaS effectively. Don''t skip this.
2. Distinguish User Deletion From Workspace Deletion
These are different operations with different blast radii. Don''t conflate them.
Help me design the deletion model.
**User deletion** (a single user leaving):
- The user removes their account
- Their personal data is purged (after cooling-off period)
- Their authored content stays (reattributed to "[deleted user]" or anonymized author)
- Workspaces they''re a member of continue without them
- Workspaces they own (sole owner): force ownership transfer or convert to workspace deletion
**Workspace deletion** (the whole tenant leaves):
- All users in the workspace lose access
- All content scoped to that workspace is purged
- Per-user data exports happen separately if requested
- Billing closed; subscription cancelled
**The decision tree**:
When a user clicks "Delete my account":
1. Are they the sole admin of any workspace?
- Yes: prompt them to either (a) transfer ownership to another admin or (b) delete the workspace
- No: proceed to user-level deletion
When a workspace admin clicks "Delete workspace":
1. Confirm they have authority (RBAC: admin role)
2. Show what will be deleted (member count, data volume, integrations, billing impact)
3. Require confirmation (typing the workspace name is the standard pattern)
4. Begin workspace-deletion flow (per next section)
**Critical implementation rules**:
1. **Two distinct flows.** Don''t reuse the same code path for "user leaves" vs "workspace deletes" — the data model is different.
2. **Last-admin protection.** Never let the last admin delete their own user without addressing the workspace.
3. **Multi-workspace users.** A user in 5 workspaces who deletes their account leaves all 5; their data per-workspace follows that workspace''s rules.
4. **Service accounts / bots.** Don''t expose the deletion flow to automation users; require admin handling.
**Don''t**:
- Make user deletion implicitly delete workspaces (terrible UX)
- Make workspace deletion silently leave users without notification
- Fail open: if the deletion logic errors midway, the user / workspace ends up in inconsistent state — be transactional
Output:
1. The user-deletion vs workspace-deletion logic
2. The decision tree code
3. The last-admin protection logic
4. The user-facing copy for each path
The single most-overlooked detail: the sole-admin case. A user who''s the only admin of three workspaces clicks "delete my account" and panics when they realize this also kills their team''s access. Surface the implication; let them choose. Don''t let UI surprise them with cascading deletes.
3. Soft-Delete With a Cooling-Off Period
Hard-delete on click is a regret factory. A 30-day cooling-off window prevents 90% of "I didn''t mean to delete!" support tickets.
Design the soft-delete + cooling-off pattern.
**The pattern**:
When a customer requests deletion:
1. Set `deletion_requested_at = NOW()` on the user / workspace record
2. Mark `status = ''pending_deletion''` (separate from active)
3. Disable login, API access, notifications
4. Show a "Your account is scheduled for deletion on [date]" message in any path that hits the account
5. Send email confirmation: "Your account will be permanently deleted on [date]. To cancel, click here."
6. Allow cancellation (one click) during the cooling-off window
7. After 30 days: the permanent-purge job runs (per next section)
**Schema additions**:
```sql
ALTER TABLE users
ADD COLUMN deletion_requested_at TIMESTAMP,
ADD COLUMN deletion_requested_by UUID REFERENCES users(id), -- self or admin
ADD COLUMN deletion_reason TEXT, -- optional: why?
ADD COLUMN deletion_scheduled_for TIMESTAMP, -- typically deletion_requested_at + 30d
ADD COLUMN deleted_at TIMESTAMP; -- the permanent-purge timestamp
ALTER TABLE workspaces
ADD COLUMN deletion_requested_at TIMESTAMP,
ADD COLUMN deletion_requested_by UUID REFERENCES users(id),
ADD COLUMN deletion_scheduled_for TIMESTAMP,
ADD COLUMN deleted_at TIMESTAMP;
Cooling-off window choice:
- 7 days: too short (users miss the email; impossible to recover from confused intent)
- 30 days: sweet spot for most products
- 90 days: too long (customers get nervous about whether deletion will actually happen)
- For paying customers: consider longer (60 days) to reduce panic-cancel churn
During the cooling-off window:
- Login: blocked, with a clear "Your account is scheduled for deletion" message + reactivation link
- API / webhook events: stopped immediately (don''t send events to a "deleted" account)
- Billing: cancel auto-renewal; refund prorated remainder if applicable
- Other users see the user as "[Pending deletion]" in member lists
Cancellation / reactivation flow:
- Magic-link from the confirmation email reactivates with one click
- If the user logs in via password during cooling-off: prompt "Reactivate? Or continue with deletion?"
- Reactivation clears the deletion fields and restores normal access
Audit:
- Per Audit Logs: log
account.deletion_requested,account.deletion_cancelled,account.permanently_deleted - Each entry includes who initiated and why (if reason was given)
Don''t:
- Skip cooling-off — accidental deletions destroy customer trust
- Allow reactivation past the scheduled date (after permanent purge, the data is gone)
- Hide the deletion UI behind opaque flows ("delete is in settings ↗ account ↗ advanced ↗ danger zone" but only after typing a confirmation phrase) — most users hate this
- Make cancellation harder than deletion was (asymmetry breeds resentment)
Output:
- The schema migration
- The deletion-request endpoint
- The cancellation endpoint
- The "blocked login" UI flow
- The confirmation + cancellation email templates
The biggest UX win: **a confirmation email with a one-click "I changed my mind" button.** The user who panic-deleted at 2am clicks the email at 9am and is restored before they''ve even had coffee. Without it, the same user files a support ticket explaining the panic-delete; you spend 45 minutes restoring; trust takes a hit.
---
## 4. Build the Permanent-Purge Job
After the cooling-off window expires, the data must actually be deleted. This is the part that gets hard.
Design the permanent-purge job.
The pattern:
A scheduled job (daily) runs:
- Query users where
deletion_scheduled_for < NOW() AND deleted_at IS NULL - For each user, run the per-user purge (steps below)
- Update
deleted_at = NOW() - Log to audit
- Send confirmation email: "Your account has been permanently deleted on [date]"
Per-user purge — what to delete:
| Data type | Action | Retention rationale |
|---|---|---|
User row in users table |
Anonymize: replace name with "Deleted User", email with deleted-{userId}@deleted.local, clear all PII |
Foreign-key references stay; user identity is gone |
| Authored content (posts, comments, etc.) | Anonymize the author reference; OPTIONAL: delete content if it''s clearly personal (private notes) | Workspace continuity; collaborators'' content stays usable |
| Personal settings, preferences | Hard-delete | No legal basis to retain |
| Files uploaded by user | Delete from object storage | No legal basis to retain |
| Sessions, refresh tokens | Hard-delete | Already invalidated at deletion-request time |
| API keys | Hard-delete | Already revoked at deletion-request time |
| Email subscription lists | Remove from all marketing/transactional lists | GDPR + CCPA require this |
| Audit log entries | KEEP, but anonymize PII fields (replace user_id with "deleted-{hash}") | Legitimate-interest retention for security |
| Billing records (invoices, payments) | KEEP for legal retention period (7 years for tax) | Tax law requires |
| Support tickets | Anonymize the user; keep the conversation | Legitimate interest for product / training |
Per-workspace purge — what to delete:
| Data type | Action |
|---|---|
| Workspace row | Hard-delete |
| All members of workspace | Per-user purge for each (or remove their workspace association) |
| All content scoped to workspace | Hard-delete |
| Files in workspace | Delete from object storage |
| Workspace integrations | Revoke, delete tokens |
| Workspace audit logs | KEEP, anonymized |
| Billing records | KEEP for legal retention |
Critical implementation rules:
- Run in a transaction or saga. Partial deletion is the worst possible state. Either everything purges, or nothing does (and an alert fires).
- Object storage is async. Files might take hours to fully delete. Track per-file deletion; verify completion before marking the user as fully purged.
- Cascade carefully.
ON DELETE CASCADEon foreign keys is dangerous if you have audit/legal data downstream. Use explicit code paths. - Rate-limit the job. Don''t purge 100K users in one hour; spread the load.
- Idempotent. Re-running the job should be safe (already-deleted users skip).
The "data we keep" disclosure:
In your privacy policy and the deletion confirmation email, state explicitly what you retain and why:
- "Audit logs containing references to your activity, anonymized"
- "Billing records (legally required for 7 years)"
- "Aggregated, non-identifying statistics"
Customers can request additional erasure of these via support; expect <5% to ever ask, and you handle case-by-case under the legal exemption.
Don''t:
- Hard-delete user rows that have foreign-key references — anonymize instead
- Skip object-storage cleanup (files persist in S3 / R2 even after the user row is gone)
- Forget to delete from third-party services (Sentry, PostHog, Stripe, marketing tools)
Output:
- The purge job code
- The per-data-type action map
- The third-party deletion checklist (every service you send data to)
- The retention disclosure for your privacy policy
The biggest hidden bug: **third-party services that still have the data.** You purged your DB, but Sentry still has the user''s session replays. PostHog has their event history. Mailchimp has them on a list. A complete deletion runs cleanup against every place data was sent. Build that checklist.
---
## 5. Build the Data Export Endpoint
Portability isn''t just a check-box; build it well and it doubles as a customer-trust feature.
Design the data export endpoint.
The pattern:
When a customer requests their data:
- Customer clicks "Export my data" in account settings
- Backend kicks off an async job
- Job collects all customer-owned data, formats it, packages it
- Job uploads the package to object storage (private; signed URL)
- Email sent: "Your data export is ready. Download here (link expires in 7 days)."
- Customer downloads; signed URL expires
The export format:
A ZIP file containing:
README.md— explains what''s in the export, what each file contains, what''s NOT includedaccount.json— user profile, settings, preferences (in human-readable JSON)account.csv— same data in CSV for spreadsheet users- One file per data type:
posts.json/posts.csvcomments.json/comments.csvfiles/— actual uploaded filesaudit-log.json— user''s own audit historybilling.json/billing.csv— invoices and payments- etc.
Format guidelines:
- Human-readable. Not internal column names. Use friendly labels like "Created at" not "created_at".
- Both JSON and CSV. JSON for completeness; CSV for non-technical users in Excel.
- Include uploaded files. Don''t just include URLs that''ll 404 after deletion.
- Document the schema. The README explains what each field means.
- UTF-8 encoded. Especially important for non-English content.
- Timestamps in ISO 8601. Universal format.
Storage and delivery:
CREATE TABLE data_exports (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
workspace_id UUID, -- NULL for user-only export
status TEXT NOT NULL DEFAULT ''pending'', -- pending / processing / ready / expired / failed
file_url TEXT, -- signed URL to the ZIP in object storage
file_size_bytes BIGINT,
expires_at TIMESTAMP, -- typically created_at + 7d
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
completed_at TIMESTAMP,
error_message TEXT
);
Critical implementation rules:
- Async, not sync. A user with 100K events / 1GB of files won''t complete in an HTTP request.
- Sign the download URL. Public URLs leak — use 7-day signed URLs with single-user access.
- Email the link, not the data. Email attachments break at 25MB; don''t even try.
- Authenticate the download. Even with a signed URL, require login to access the ZIP (defense in depth).
- Audit every export. Log who exported what when, from what IP.
- Rate-limit exports. One export per user per 24 hours is reasonable.
- Workspace exports vs user exports. Different endpoints; different scopes; only an admin can export workspace-level data.
Don''t:
- Dump the database. Customers don''t want internal IDs and audit timestamps; they want their stuff.
- Include other users'' data. An export of "your account" must NOT include posts from other workspace members.
- Skip the README. An archive without context is useless.
Output:
- The data_exports schema
- The export-build job code
- The README template
- The signed-URL delivery mechanism
- The email template
- The rate-limiter
The single biggest customer-trust signal: **a clean, well-formatted export.** A customer who downloads their export and immediately understands what''s in it walks away thinking "this company knows what they''re doing." A dump of internal JSON makes them wonder.
---
## 6. Build the Self-Serve UI
Make deletion and export self-serve. Email-to-support flows are slower for customers and more expensive for you.
Design the self-serve UI.
The page lives at /account/privacy (or /settings/privacy).
Section 1: Data Export
- Header: "Download your data"
- Description: "Get a copy of your data in JSON and CSV. Useful for backup, switching tools, or just having a copy."
- Button: "Request export"
- After click: "Your export is being prepared. We''ll email you when it''s ready (usually within 1 hour)."
- Recent exports list: shows last 3 with download links and expiration
Section 2: Account Deletion
- Header: "Delete your account"
- Description: "Permanently deletes your account and personal data after a 30-day cooling-off period."
- Button: "Delete my account" (red; destructive variant)
- On click: open confirmation modal
Confirmation modal:
- Headline: "This is permanent. Are you sure?"
- Show specifically what will happen:
- "Your profile and personal data will be deleted in 30 days"
- "Your contributions will be anonymized but kept (so collaborators don''t lose context)"
- "Workspaces you''re sole admin of: [list] — choose what to do with each"
- "Active subscriptions: [list] — will be cancelled"
- Reason field (optional): "Why are you leaving? (Optional)" — feedback for the team
- Confirmation: type "delete my account" to confirm
- Final button: "Confirm deletion"
Workspace deletion (admin only):
- Lives at
/workspace/[id]/settings/delete - Same pattern as account deletion
- Type the workspace name to confirm
- Disclose: "All [N] members will lose access. All [M] documents / files / etc. will be permanently deleted."
Cooling-off banner:
- After deletion is requested, every page in the app shows a banner: "Your account is scheduled for deletion on [date]. [Cancel deletion]."
- One-click cancel restores the account fully
Export results UI:
- A page at
/account/exportsshowing all past exports - Each row: date requested, status (pending / ready / expired / failed), download link, expiration
- Allow re-requesting an expired export
Don''t:
- Bury the deletion option ("Account → Settings → Advanced → Privacy → Delete" is hostile)
- Skip the friction (typing-to-confirm prevents fat-finger deletions)
- Make cancellation harder than the request (banner cancel must be one click)
Output:
- The privacy-page UI components
- The deletion-confirmation modal
- The cooling-off banner
- The exports-list page
- The accessible / keyboard-navigable controls
The single biggest indicator of regulatory friendliness: **the deletion option is in account settings, no more than 2 clicks deep.** Burying it is a red flag for regulators and a frustration for customers. Make it easy to find; make it hard to do by accident.
---
## 7. Audit Every Privacy Event
Privacy operations are the most-audited area of any product. Don''t skimp.
Design the audit log integration.
Per Audit Logs, log:
Deletion lifecycle:
account.deletion_requested— by whom, why (if reason given), scheduled dateaccount.deletion_cancelled— by whomaccount.permanently_deleted— by the system, whenworkspace.deletion_requested/workspace.deletion_cancelled/workspace.permanently_deleted
Export lifecycle:
data.export_requested— by whom, what scope (user vs workspace)data.export_completed— when, file sizedata.export_downloaded— when, from what IPdata.export_expired— automatic
Admin-initiated actions:
admin.user_deleted— when an admin removes another user (NOT self-deletion)admin.workspace_deleted— when an admin removes a workspaceadmin.data_exported— when an admin exports another user''s data (rare, sensitive)
Required fields in every audit entry:
- Actor (who initiated)
- Subject (who/what was affected)
- Timestamp
- IP address
- User agent
- Reason (if provided)
Retention of audit logs:
- Privacy-related audit entries: keep for 7 years (legal-defense purposes)
- Anonymize the actor / subject after the actor / subject is deleted, but keep the event
Customer-facing audit feed at /account/privacy-activity:
- Shows the user''s own privacy events
- "On [date], you requested an export. Status: [status]."
- "On [date], you requested account deletion. Status: scheduled / cancelled / completed."
Don''t:
- Allow audit logs to be edited or deleted (append-only)
- Log the data being deleted (no, your audit log shouldn''t have a copy of the deleted user''s passwords)
- Skip the "admin acted on user" entries (these are the most-scrutinized)
Output:
- The audit event schema
- The customer-facing privacy-activity feed
- The retention policy
- The runbook for regulator requests ("show me everything about user X")
The single highest-value audit query: **"who has been deleted and when?"** When a regulator asks "did you actually delete user X within 30 days?" you need to answer in 5 seconds with a date and a record. Make sure the audit shape supports that query.
---
## 8. Document for Customers
Privacy is one area where bad docs create real fines. Write the docs carefully.
Help me draft the customer-facing privacy documentation.
Sections (in your privacy policy AND a help-center article):
Data we collect
- Personal data: name, email, IP, etc.
- Usage data: events, page views, feature usage
- Content: what they''ve created in the product
- For each: legal basis (consent / contract / legitimate interest)
How long we keep it
- Per-data-type retention table
- Why we keep what we keep
- What''s deleted on account deletion vs retained (with legal basis)
How to delete your account
- Step-by-step UI walkthrough
- The 30-day cooling-off window explained
- What happens to your data
- What''s retained and why
- How to cancel during cooling-off
How to export your data
- Step-by-step UI walkthrough
- The format (JSON + CSV)
- What''s included / what''s not
- Email-delivered link with expiration
Workspace vs personal data
- Different deletion flows; different ownership
- Workspace admins control workspace data
- Members control their personal contributions
Subprocessors
- List every third party you send data to (Stripe, Sentry, PostHog, AWS, etc.)
- For each: what data, why, link to their privacy policy
Contact
- Privacy contact email (typically privacy@yoursite.com)
- DPO if applicable
Right-to-know responses
- What you''ll do if a customer asks for their data
- Timeline (within 30 days)
- Escalation path
Output:
- The privacy policy update
- The help-center articles for deletion and export
- The subprocessor list (kept current)
- The DPA template (Data Processing Agreement) for B2B customers
The single biggest enterprise-sales unlock: **a clean trust portal with subprocessors, DPA template, and security docs.** Enterprise procurement asks for these; founders who have them ready close deals; founders who scramble lose them. Build now; thank yourself later.
---
## 9. Handle the Edge Cases
Real customers surface edge cases. Plan for them.
The edge case checklist.
Edge case 1: User has multiple email addresses on file
- Pattern: deletion applies to the user_id, not the email
- All emails associated are removed from marketing lists
Edge case 2: User created data while at one company; switched companies
- Their personal data follows them; workspace data stays with the workspace
- Be clear in docs: "Content you created in [Workspace] belongs to [Workspace], not you"
Edge case 3: User invites a third party who never accepts
- Pending invite is personal data on the invitee
- On account deletion, cancel pending invites; remove personal-data references
Edge case 4: Backups
- "What about backups?" — your DB backups still have the user''s data
- Standard practice: state in policy that backup-retention is up to N days; data ages out
- Don''t actively delete from backups (operationally hard); document the retention
Edge case 5: Logs
- Server logs may contain user IPs, request paths with user IDs, etc.
- Document log retention (typically 90 days)
- After log retention expires, the data is gone
Edge case 6: Third-party caches / CDNs
- Cloudflare / Vercel may cache pages containing user data
- Document a cache retention period
- For high-sensitivity, set short cache TTLs
Edge case 7: User deletes account, then signs up again with same email
- Pattern: it''s a fresh account; nothing carries over
- Don''t auto-restore old data (the deletion was permanent for a reason)
Edge case 8: Deleted user''s payment method on file with Stripe
- Stripe customer record persists (legally required for refunds, chargebacks)
- Sever the link to the deleted user; document this in the privacy policy
Edge case 9: Right-to-know request from someone who isn''t a customer
- They received an email from a customer in your platform
- Their personal data is in your system, but they never created an account
- Verify their identity; provide whatever''s on file; document the process
Edge case 10: Court order / law enforcement
- A subpoena requires you to retain data despite a deletion request
- Pause the deletion; document the legal hold; follow your incident-response process
Output:
- Edge-case handling for each
- The customer-facing FAQ that addresses the obvious ones
- The internal runbook for the unusual ones
---
## 10. Quarterly Privacy Review
Privacy posture rots. Quarterly review keeps it healthy.
The quarterly review checklist.
Operational metrics:
- How many deletion requests this quarter? Trend?
- How many export requests? Trend?
- Average time from request to completion?
- Any deletions that missed the 30-day window? Why?
- Any audit-log gaps for privacy events?
Compliance metrics:
- Any new regulations applicable since last review?
- Any subprocessors added without DPA?
- Privacy policy update needed?
- Any customer complaints to regulators?
System health:
- Permanent-purge job running reliably?
- Any orphaned data in object storage?
- Any third-party services we send data to that we''re not deleting from?
Documentation:
- Privacy policy current?
- Subprocessors list current?
- Help-center articles match current UX?
Action items:
- 3 fixes to ship next quarter
- 1 process improvement
- 1 training topic for the team
Output:
- The quarterly snapshot
- Actions taken / planned
- Compliance posture for the period
---
## What "Done" Looks Like
A working account-deletion + data-export system in 2026 has:
- **Self-serve deletion** with a 30-day cooling-off window
- **Self-serve data export** in JSON + CSV with portable structure
- **Permanent purge job** that handles every data type and third-party service
- **User-deletion vs workspace-deletion** distinct flows
- **Last-admin protection** during user-deletion
- **Audit logs** for every privacy event with 7-year retention
- **Customer-facing privacy activity feed**
- **Privacy policy** with retention table and subprocessor list
- **DPA template** ready for B2B customers
- **Quarterly review** baked into the team rhythm
The hidden cost in privacy ops isn''t the deletion code — it''s **the third-party services that quietly retain data**. A complete deletion is a checklist of 10+ external services. Build the checklist; automate where possible; audit quarterly. The first fine you avoid pays for the work many times over.
---
## See Also
- [Multi-Tenant Data Isolation](multi-tenancy-chat.md) — workspace boundary informs deletion scope
- [Audit Logs](audit-logs-chat.md) — every deletion / export logged here
- [Roles & Permissions (RBAC)](roles-permissions-chat.md) — admin-vs-self-deletion permission paths
- [SSO & Enterprise Auth](sso-enterprise-auth-chat.md) — enterprise customers expect DPA + deletion SLAs
- [Email Deliverability](email-deliverability-chat.md) — confirmation emails matter
- [Cookie Consent & Privacy Banners](cookie-consent-chat.md) — companion compliance feature
- [Public API](public-api-chat.md) — your API may need a delete-via-API path for enterprise integrations
- [Authentication](https://www.vibereference.com/auth-and-payments/authentication) — sessions invalidated at deletion
- [File Storage Providers](https://www.vibereference.com/cloud-and-hosting/file-storage-providers) — file deletion is async and tricky
- [Background Jobs Providers](https://www.vibereference.com/backend-and-data/background-jobs-providers) — purge job and export job run here
[⬅️ Growth Overview](README.md)