Delete data
Delete rows that match the chained filters.
Delete rows via DELETE. Chain at least one filter to scope which rows are removed, then call .execute. PostgREST refuses an unfiltered DELETE unless you opt in explicitly via max_affected.
Signature
supabase.from(table).delete(count: nil, returning: "representation")delete takes no positional argument — the rows-to-delete are determined entirely by the filters you chain after it.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
count | String | Optional | One of "exact", "planned", "estimated". Adds Prefer: count=... so APIResponse#count is populated from the Content-Range header. |
returning | String | Optional | "representation" (default) returns the deleted rows; "minimal" returns no body, which is faster for fire-and-forget deletes. |
Returns
A chainable builder that mixes in FilterMixin — chain filters to scope the delete, then call .execute to fire the request and receive an APIResponse.
Example — delete one row by primary key
response = supabase
.from("countries")
.delete
.eq("id", 250)
.execute
response.data # => [{ "id" => 250, "name" => "Wakanda", ... }]Example — bulk delete with a compound filter
response = supabase
.from("sessions")
.delete
.lte("expires_at", Time.now.utc.iso8601)
.eq("revoked", false)
.execute
response.data.length # => however many rows were deletedExample — fire-and-forget delete
returning: "minimal" returns no body, so data is []. Use this when you don't need the deleted rows back.
supabase
.from("audit_log")
.delete(returning: "minimal")
.lt("created_at", "2025-01-01")
.executeExample — count what was deleted
response = supabase
.from("sessions")
.delete(count: "exact")
.lte("expires_at", Time.now.utc.iso8601)
.execute
response.count # => N rows deletedExample — guard a wide delete with max_affected
max_affected(N) adds Prefer: handling=strict,max-affected=N. PostgREST refuses the delete (returning 400) if the row count would exceed N. Use this any time the filter could match more rows than you intend to remove.
supabase
.from("login_attempts")
.delete
.eq("ip", "203.0.113.7")
.max_affected(1_000)
.executeExample — delete with in_ (multiple primary keys)
supabase
.from("countries")
.delete
.in_("id", [250, 251, 252])
.executePostgREST refuses unfiltered deletes (no eq/in_/etc. on the chain) unless max_affected is set.