---
title: "Restore and export one tenant alone · Agent Wranglers"
url: https://agentwranglers.se/playbook/data/multi-tenancy/per-tenant-restore
id: DAT-71
level: Recommended
updated: 2026-10-22
tokens: 858
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Restore and export one tenant alone

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Multi-tenancy](https://agentwranglers.se/playbook/data/multi-tenancy.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: DAT-71
- Level: Recommended
- Chapter: [Multi-tenancy](https://agentwranglers.se/playbook/data/multi-tenancy.md)
- Rule: Keep a tested script that exports one tenant's data from every store, and one that restores a single tenant from backup without changing other tenants.
- Check: A test compares the export script's table list with every table that has a `tenant_id` column, and they match. Each quarter, restore one test tenant from a backup at least a day old into staging. Its row counts match the backup, and a second tenant's row counts do not change.
- How: With shared tables, a whole-database restore would roll back every customer to fix one. Restore the backup into a scratch database instead. Then copy only the rows with that tenant's ID back, table by table in foreign key order, inside one transaction. Copy files from the tenant's storage prefix too. The same table list drives the export, which also serves an owner's request for the organisation's data, as [Let people export their data themselves](https://agentwranglers.se/playbook/accounts/profile-and-account-lifecycle/self-service-export.md) notes. Generate the table list from the schema, so a new table with a tenant column cannot be forgotten. Run it on the schedule of [Prove restores work](https://agentwranglers.se/playbook/data/backups-and-recovery/restore-tests.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### SQL example

```sql
-- Every table that holds tenant data, for the export and restore scripts
SELECT table_name FROM information_schema.columns
WHERE column_name = 'tenant_id' AND table_schema = 'public'
ORDER BY table_name;
```

## Sources

- [OWASP Multi-Tenant Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Multi_Tenant_Security_Cheat_Sheet.html)
- [Data Act Chapter VI on switching between services](https://eur-lex.europa.eu/eli/reg/2023/2854/oj)

## Related rules

- ACC-55 [Let people export their data themselves](https://agentwranglers.se/playbook/accounts/profile-and-account-lifecycle/self-service-export.md) in Accounts and identity
- DAT-28 [Prove restores work](https://agentwranglers.se/playbook/data/backups-and-recovery/restore-tests.md) in Data and databases

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/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/per-tenant-restore">Agent Wranglers data and databases playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Put the tenant on every log line and trace](https://agentwranglers.se/playbook/data/multi-tenancy/tenant-in-logs.md)
- Next: [Delete every copy of a tenant when the contract ends](https://agentwranglers.se/playbook/data/multi-tenancy/tenant-offboarding.md)
- [Multi-tenancy](https://agentwranglers.se/playbook/data/multi-tenancy.md)
