DAT-72Required
Delete every copy of a tenant when the contract ends
When a customer leaves, return or delete their data in every store within the period your contract states. Backups holding it expire on their normal schedule.
How to do it
You often process personal data for a business customer. GDPR Article 28(3)(g) then makes you delete or return it when the service ends, as the customer chooses. Build one offboarding job that walks the same store list as the export. It covers database rows, files under the tenant's prefix, search and vector indexes, caches, queues and analytics. Drop a tenant's schema or database whole. Send the customer a final export first when they ask for one. Record the deletion, with counts per store, as evidence. Backups are not edited. They age out as backup retention sets. Keep the deleted tenant IDs in a deletion list, and re-run offboarding for each one after any restore. Other personal data follows Delete old data automatically. Fine-tuned models trained on that customer's data are deleted too, as Keep each customer's data in its own fine-tuned model says.
Examples
JavaScript example
const TENANT_STORES = [deleteRows, deleteFiles, deleteSearchDocuments, deleteVectors, deleteCacheKeys, deleteAnalytics];
export async function offboardTenant(tenantId) {
const counts = {};
for (const deleteFrom of TENANT_STORES) counts[deleteFrom.name] = await deleteFrom(tenantId);
await deletionLog.insert({ tenantId, counts, deletedAt: new Date() });
return counts;
}
Python example
TENANT_STORES = [delete_rows, delete_files, delete_search_documents, delete_vectors, delete_cache_keys, delete_analytics]
def offboard_tenant(tenant_id: int) -> dict[str, int]:
counts = {delete_from.__name__: delete_from(tenant_id) for delete_from in TENANT_STORES}
deletion_log.insert(tenant_id=tenant_id, counts=counts, deleted_at=datetime.now(timezone.utc))
return counts
How to check
An end-to-end test creates a tenant with data in every store and runs offboarding. It then finds 0 rows, 0 objects and 0 index hits for that tenant ID. Restore a backup taken before the deletion into staging, run the restore script with its deletion list step, and the tenant is gone again.
Sources
Related rules
- OPS-46 Keep backups for a set time in Operations and observability
- DAT-31 Delete old data automatically in Data and databases
- AIF-58 Keep each customer's data in its own fine-tuned model in AI features
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/data/multi-tenancy/tenant-offboarding">Agent Wranglers data and databases playbook</a>. In code you write, add a comment next to it with the same link.