Soft Delete vs Hard Delete: Designing Data Lifecycle in Supabase
When to soft delete and when to hard delete in Supabase: the is_deleted pattern, deleted_at timestamps, filtering queries, and restoring records.

How to Implement Soft Delete in Supabase with PostgreSQL**
Introduction :
Imagine an administrator accidentally deletes 10,000 customer records from a production database. With a hard delete, those records are permanently removed and may be extremely difficult to recover. In Supabase, implementing a soft-delete approach allows records to be marked as deleted instead of being permanently removed. This makes it possible to restore the data when needed and provides an additional layer of protection against accidental deletion. Hard deletes, however, permanently remove records and should be used when data no longer needs to be retained.
For implementing soft delete functionality, you don’t need to create a new database; instead, you can update the existing record to mark it as deleted rather than permanently removing it. This approach keeps the data available in the database while indicating that it is no longer active. It also raises an important question: if data is accidentally deleted from the database, can we recover it? With soft delete, the answer is yes, because the data remains stored and can be restored when needed.
Hard delete vs Soft delete :
When data is permanently removed from the database, it is hard deleted and is difficult to recover. With soft delete, instead of removing the data, we mark it as deleted while keeping it in the database. This allows us to easily restore deleted data when needed by running a database query.
Problem :
When we run a query to delete data from the database, we may permanently delete that data. If it is accidentally deleted by someone, what can we do? We may face data loss because we cannot recover the data once it has been permanently deleted.
Solution :
By implementing soft delete functionality, when we need to delete data, we do not send a DELETE query to the database. Instead, we send an UPDATE query and mark the data as deleted.
So, when we need to recover the deleted data, we send an UPDATE query again and mark it as not deleted.
We can implement flag and time stamps for Delete Fields :
Flag Functionality : We create a Boolean field for each record to determine whether it has been deleted.
Delete Timestamps : we create a deleted_at Field for each data and assign value when we perform the delete operation, so we easily determine when data was deleted ? (Ex. deleted_at : 2026-08-22 14:04:00 )
Prerequisites :
- Supabase Account: you must have a supabase working Account
- PostgreSQL Basics: Must have basic knowledge about how postgreSQL Works and can Write a Query of CRUD.
- Application Framework: Basic knowledge of connecting an application to Supabase.
Steps For Implementation:
**Step 1 : Create Database Table
**
- Create a new Table for store data or use Existing Table & Ensure that Table Have Delete Fields. (Ensure that Table have Field of Soft Delete )
Step 2: Add the deleted_at Column
- Add a nullable deleted_at timestamp column to your database table. This flags rows as removed without erasing them
**Step 3 : Create Active Data rows
**
- Create Some Data in tables, so we have active data which we used for Delete Operation. Active data Must have that Delete Field Null.
**Step 4 : Trigger a Soft Delete Query
**
- When we have active data, execute a soft delete query by updating the delete field, such as setting deleted_at to the current timestamp.
Step 5 : Check Table for Deleted Data
- Now look at the table. We should find that some data has values in the delete fields. When we fetch active data, we must ensure that these delete fields are checked for NULL.
**Common Problems / Errors :
**
- Forgot to Filter : When fetching active data, make sure to filter records using the appropriate delete field.
- Updated Data Is Not Being Saved : When we Execute the delete query, then we have sent a mismatched field for the execution so our data is not updated and when we have fetched Active data then we have shown Deleted Data too.
Best Practices :
- Database Schema Design : Make sure that we have created a Schema of Delete Fields whichever you use flag or timestamps.
(ex. is_deleted : Boolean, deleted_at : Date)
- Indexing and Performance : Add an appropriate index to fields such as deleted_at when filtering large tables to improve query performance.
Performance Issue :
**
- Query Optimization without Indexing : Without proper indexing, queries that fetch active records may need to scan many rows instead of efficiently using an index.
When Should You Use It :
- Accidental Deletion : When data is accidentally deleted, soft delete allows us to restore it easily.
- Multiple Developers Working on the Same Database: When multiple developers work on the same database, soft delete can help reduce the risk of accidental data loss.
- Fewer Dependencies : Use soft delete when the data has fewer dependencies and deleting a record does not negatively affect related data.
FAQ :
- Can I restore a soft-deleted record easily?
Yes. Because the records are not deleted from the database, they are only hidden.
- **When Should You Use Soft Delete?
**Use soft delete when you need to recover accidentally deleted data or maintain historical records.
- **When Should You Avoid Soft Delete?
Avoid soft delete when data must be permanently removed or retaining deleted data creates security, privacy, or storage concerns.
**
- Does Supabase have a native "one-click" soft delete toggle?
No. Supabase does not provide a one-click soft-delete toggle; you need to implement the soft-delete logic yourself, typically using a deleted_at column.
- **Do soft-deleted rows count toward my Supabase storage limits?
**Yes. Because soft-deleted rows are never removed from the underlying Postgres database, they still consume database disk space.
Best Recommendation :
**
- For most Supabase applications where accidental deletion is a concern, using a deleted_at timestamp provides a simple way to mark records as deleted while keeping them available for recovery.**
**
Conclusion :
Implementing soft delete in Supabase offers two major benefits:
- Better Data Recovery:
If data is deleted accidentally, we can restore it by updating the record and removing its deleted status.
- Safer Data Lifecycle Management :
To restore deleted data, execute an UPDATE query with the appropriate filter and set the deleted_at value back to NULL.

Aarav Sharma
Lead Software Engineer
Aarav leads product engineering at Matlab Infotech, where he has shipped mobile and web platforms across healthcare, fintech, and SaaS. He writes about pragmatic engineering and shipping fast without cutting corners.


