Handling Account Cancellation and Data Export in Custom SaaS
Cancellation and data export are features to design, not tickets to clear. Build the offboarding flow, retention window, and deletion run before launch.
Cancellation and data export are product features, not support procedures. Treat them the way you treat signup: a defined cancellation flow, a self-serve export that produces a usable file, a retention window with a published expiry date, and a deletion path that leaves an audit record. The build is small, typically two to four weeks of engineering, and it removes the need to pull customer data out of production tables by hand later.
What should happen the moment a customer cancels?
The account should stop being charged, access should end at the close of the paid period, and the data should enter a retention window with a visible expiry date. Nothing should be deleted yet.
Model cancellation as a state machine: a fixed list of account statuses and the transitions allowed between them. A workable set is active, canceling (billing stopped, access continues until period end), suspended (period over, data retained, login blocked), and deleted. Every transition writes an audit record, an append-only log entry naming who acted, when, and from which IP address.
Steps for the flow itself:
- Require an owner-level role, so a junior team member cannot cancel a company account by accident.
- Show the consequences before confirmation: the last billing date, whether the current period is refunded, and the exact date the data will be deleted.
- Offer the export at that moment, not later. Ask whether the customer wants to download it now or receive a link when it is ready.
- Capture a reason code. A short list of options is enough, and the aggregate counts tell you why accounts leave.
- Send the confirmation to an email address that survives the account, since the workspace login will eventually stop working.
- Schedule the deletion as a dated job instead of running it by hand. Manual deletion happens late, or twice.
An immediate cancellation option matters for a subset of customers. Some want access cut off within the hour, usually for security reasons after a staff change or a contract dispute. Support both paths and record which one was chosen.
Which export format should a custom SaaS product offer?
Offer a machine-readable archive such as CSV or JSON, one file per table, plus a human-readable summary. Machine-readable files keep migrations and integrations moving; the summary is what a finance or operations lead actually opens.
CSV stands for comma-separated values, a plain text table with one row per record. JSON is a structured text format with named fields, which is easier for another system to parse without manual mapping. Most customers ask for everything and then open one summary document.
| Format | Who it serves | Typical volume for 50,000 records | Build effort |
|---|---|---|---|
| CSV per table | Migrations, spreadsheet review, data teams | 5 to 50 MB | Low, reuses the existing query layer |
| JSON bundle | Developers importing into another system | 10 to 100 MB | Low to medium |
| PDF or HTML summary | Finance and operations leads | Under 5 MB | Medium, needs layout and templating work |
| Uploaded files and attachments | Anyone leaving with documents | 1 GB to 1 TB | High, needs a background job and signed links |
A signed link is a URL carrying a token and an expiry time, granting temporary download access without a login. Set that expiry somewhere between 24 and 72 hours, and log every download against the account.
Build exports as background jobs. A request timeout, the server-side limit on how long one web request may run, is often 30 to 60 seconds, and a full account archive will not finish inside that window. Queue the job, write the archive to object storage, then email the link when it is ready. Large accounts can take 10 to 30 minutes, so show progress or at least a rough estimate.
How long should you retain data after cancellation?
A retention window of 30 to 90 days is a common default, long enough for a customer to change their mind and short enough to honor deletion expectations. Publish the exact number in your terms.
Retention differs by data type, and a single blanket rule tends to fail an audit or annoy a customer.
| Data type | Typical retention after cancellation | Reasoning |
|---|---|---|
| Live application data | 30 to 90 days | Covers reactivation and a late export request |
| Backups | Matches the backup cycle, often 30 to 90 days | Restoring a large backup to delete one tenant can take a full day of engineering |
| Invoices and payment records | Several years, often five to seven | Tax and accounting rules usually outlast the customer relationship |
| Logs and analytics events | 30 to 90 days, or anonymized sooner | Debugging value drops quickly and the data is often personal |
Two terms matter here. A legal hold is a documented instruction to keep data past its normal expiry, usually because of a dispute or an audit. A suppression list is a short record of identifiers that must never be restored, so an old backup cannot bring a deleted account back into production. Keep that list indefinitely and store nothing in it beyond a hash, a one-way scrambled value that cannot be turned back into the original identifier.
Backups rarely need surgical deletion. Let them age out on their normal cycle and rely on the suppression list when a restore is unavoidable. Confirm your retention numbers with an accountant and a lawyer instead of copying another product's terms page.
How do you delete data without breaking related records?
Delete in dependency order or rely on cascading rules. Remove child rows such as sessions, invitations, and notifications first, then parent records, and keep a tombstone so the system knows the deletion happened.
A foreign key is a column that points at a row in another table, and referential integrity is the guarantee that those pointers never dangle. Cascading deletes are a database rule that removes dependent rows automatically when a parent is removed. They are convenient and dangerous, because one wrong foreign key can quietly empty a shared table.
How much work deletion is depends on how you isolated tenants in the first place. A multi-tenant system is one database serving many customer organizations, usually with a tenant_id column on every table.
| Isolation model | What deletion involves | Effort |
|---|---|---|
| Shared tables with tenant_id | Sweep every table, plus file storage, caches, and the search index | Medium, and easy to miss a table |
| Schema per tenant | Drop the schema in one statement, then delete files | Low |
| Database per tenant | Drop the database, then delete files | Low, at higher hosting cost |
If deletion is a priority and you are still choosing an architecture, per-tenant isolation pays for itself. If you already run shared tables, keep a written list of every table holding a tenant_id and test the sweep regularly. This plumbing is standard in custom SaaS platform development and cheap to add at build time, expensive to retrofit.
What else has to be cleaned up besides the database?
Caches, search indexes, job queues, analytics events, email lists, and third-party tools all hold copies. Treat the deletion run as a checklist across every system that ever received customer data.
- Application database, including soft-deleted rows. A soft delete is a flag such as deleted_at that hides a row without removing it, and those rows are still personal data.
- Object storage for uploads, generated exports, and report PDFs.
- Search index and cache layer, both of which may hold document text.
- Queues and event streams with pending or dead-lettered messages.
- Analytics, session replay, and error tracking tools.
- Email and marketing platforms, including any suppression lists inside those tools.
- Payment processor, where records are usually retained for tax reasons rather than deleted.
- Subprocessors, meaning third parties that process data on your behalf. Each has its own deletion schedule, often 30 to 90 days, so get the timing in writing.
When the run finishes, issue a short deletion certificate: what was removed, from which systems, and on what date. Enterprise buyers ask for that document during security reviews, and one page answers the question faster than a call.
Frequently asked questions
How long should a SaaS product keep data after a customer cancels?
A window of 30 to 90 days is a workable default for live application data, because it gives the customer time to export or reactivate. Backups usually follow their own cycle, and invoices are typically kept for several years because of tax rules, so the retention answer differs by data type.
What should a data export include for a cancelled SaaS account?
Include the account records themselves as CSV or JSON, one file per table, plus uploaded files and a human-readable summary of users, plan, and invoices. The structured files serve migrations and integrations, while the summary is what most departing customers actually open.
Does deleting a customer account remove their data from backups?
Usually not. Most teams delete from live systems immediately and let backups expire on their normal 30 to 90 day cycle, because restoring a large backup to remove one tenant can take a full day of engineering. A suppression list prevents that tenant from being restored into production.
Should customers be able to cancel an account without contacting support?
Yes, in most business software. A self-serve flow with a confirmation step and a clear deletion date removes the manual work of verifying identity over email and gives you consistent reason data, while a support-assisted path can stay available for large accounts and contract negotiations.