When a Supabase Database Webhook appears to do nothing, do not begin by rewriting the Edge Function or webhook handler.
First answer a more useful question: how far did the event actually travel?
A Database Webhook crosses several boundaries:
row change → database trigger → pg_net worker → HTTP request → receiving endpoint → authentication → handler logic → downstream side effect
A failure at any one of those points can look identical from the product UI. The user clicks Save, the database row changes, and the expected email, payment update, notification or automation never happens.
That is why I prefer boundary-first debugging for webhook systems. Find the last layer that definitely worked before changing code downstream.
1. Confirm the database event actually matches the webhook
Start with the boring checks because they eliminate a surprising amount of wasted debugging.
Supabase Database Webhooks can be attached to INSERT, UPDATE and DELETE events. Confirm the webhook is attached to the correct table and that the operation you are testing is one of the enabled events.
Supabase’s current Database Webhooks documentation explains that these webhooks are implemented as database triggers and use the pg_net extension for asynchronous HTTP requests.
That architecture has an important implication: the database mutation succeeding does not prove the remote action succeeded.
The row can be committed while the outbound HTTP request fails later.
If you are building payments, booking flows, onboarding or notification systems, do not model “database row saved” and “external side effect completed” as the same state.
2. Check whether the pg_net worker is alive
If the trigger exists but nothing appears to leave the database, inspect the worker before touching your application.
Supabase’s current webhook debugging guide recommends checking pg_stat_activity for the pg_net background worker:
select pid
from pg_stat_activity
where backend_type ilike '%pg_net%';
If that returns no worker PID, your receiving endpoint is not yet the main suspect.
For supported pg_net versions, Supabase documents net.worker_restart() as a way to restart the worker. Check the current documentation and your installed version before making infrastructure changes.
This is exactly the kind of failure an AI coding assistant can misdiagnose. If you tell it only “my webhook stopped working,” it may confidently rewrite the Edge Function even though the request never left Postgres.
3. Inspect the HTTP response history
Once you know pg_net is active, inspect what happened to outbound requests.
Supabase documents recent webhook response information in the net schema. Its troubleshooting guide uses net._http_response to find failed HTTP responses and transport errors.
A useful diagnostic query is:
select *
from net._http_response
where status_code >= 400
or error_msg is not null
order by created desc;
Do not treat every failure in that result the same way.
| Evidence | Likely boundary |
|---|---|
| No relevant request/response evidence | Trigger, worker or queue path |
| Timeout or connection error | Network or endpoint reachability |
| 401/403 | Endpoint authentication/authorization |
| 404 | Wrong URL, route or deployment |
| 500 | Receiver executed but failed |
| 2xx but side effect missing | Handler logic or downstream system |
The point is not the exact status code. The point is to stop debugging layers you have already proved are healthy.
4. Test the network path separately from your real handler
If you cannot tell whether pg_net itself can make outbound requests, test that boundary independently.
Supabase’s troubleshooting guide demonstrates sending a request to an echo endpoint with net.http_post() and then inspecting the response by request ID. That isolates the database networking layer from your own application code.
If a neutral endpoint works but your production endpoint fails, move your investigation toward DNS, TLS, firewall rules, routing, endpoint availability or authentication.
If the neutral request also fails, rewriting your business logic is unlikely to help.
5. Do not use localhost incorrectly in local development
Local webhook testing has a networking trap.
When Supabase runs locally, Postgres is inside Docker. localhost or 127.0.0.1 from that container refers to the container itself, not automatically to the web server running on your computer.
Supabase’s Database Webhooks documentation recommends host.docker.internal for reaching a service on the host in the common local setup.
So this:
http://localhost:3000/webhook
may fail even while the endpoint works perfectly in your browser.
That is a network-addressing problem, not an Edge Function bug.
6. If the request arrives, then inspect authentication
Once endpoint logs prove the request arrived, move to the auth boundary.
This matters particularly now because Supabase has introduced newer publishable and secret API keys alongside legacy keys. Its current API-key migration guide documents specific handling for pg_net and Database Webhooks, including differences between legacy bearer-key patterns and newer secret keys.
Do not blindly copy an old webhook header configuration into a new project.
Also avoid hardcoding privileged credentials in SQL or configuration where they can be exposed unnecessarily. Follow the current Supabase guidance for server-side secrets and Vault where appropriate.
If your webhook calls an Edge Function and receives a 401, use my separate guide on diagnosing Supabase Edge Function 401 errors. A 401 is a much narrower problem than “webhooks are broken.”
7. Verify the payload shape before blaming the database
Supabase’s documented webhook payload differs by operation.
An insert contains the new row in record. An update contains both record and old_record. A delete has record: null and puts the deleted row in old_record.
A handler that assumes payload.record always exists can therefore receive the webhook correctly and still fail on deletes.
Log enough metadata to answer:
- which event type arrived;
- which table produced it;
- whether
recordorold_recordis expected; - whether authentication passed;
- whether the handler reached its downstream action;
- whether that action succeeded.
Do not log secrets or sensitive payload fields just to make debugging easier.
8. Treat webhooks as a delivery system, not proof of business completion
The deeper production lesson is about state.
Suppose an order row changes to paid and a webhook is expected to create an invoice. If the webhook fails, the database may say the order is paid while the invoice is still missing.
For important workflows, model those facts separately.
For example:
payment confirmed
invoice pending
invoice generated
invoice delivery pending
invoice delivered
That gives you something observable and recoverable instead of one optimistic boolean pretending several distributed operations happened together.
It also makes retries safer. Before retrying a side effect, determine whether the first attempt partially succeeded. Payments, emails, receipts and external API calls should be designed with idempotency in mind where the downstream system supports it.
A practical debugging order
When a Supabase Database Webhook stops working, use this sequence:
- Confirm the table and INSERT/UPDATE/DELETE event.
- Confirm the trigger exists.
- Confirm the pg_net worker is active.
- Inspect recent
netresponses and errors. - Test outbound HTTP independently if necessary.
- Confirm the endpoint URL and reachability.
- Confirm the request appears in receiver logs.
- Then inspect authentication and headers.
- Validate the payload shape.
- Trace the downstream side effect and its state.
That order protects the evidence you need to diagnose the problem.
If you are preparing an AI-built product for real users, also work through my AI-built app production checklist. Webhook reliability is one example of the gap between a feature that works in a demo and a workflow that can be operated safely in production.
If your Supabase or AI-built MVP has reached the point where failures cross database, auth, function and payment boundaries, see my MVP development service or contact me. I can help trace the system before a small integration bug becomes a rewrite.



