VillageSQL is a drop-in replacement for MySQL with extensions.
All examples in this guide work on VillageSQL. Install Now →
vsql_http extension, triggers can send HTTP requests directly, so external systems get notified the moment a row changes, with no application-layer event publishing required.
Setup
Basic Webhook Trigger
AnAFTER INSERT trigger that POSTs a payload to a webhook endpoint:
@ignored — the trigger doesn’t use the response, but the assignment suppresses the “result not used” warning. NULL means the connection failed; the trigger completes either way and the INSERT goes through.
Controlling Timeouts
By default,vsql_http uses a 30-second timeout. A slow or unavailable webhook endpoint blocks the write for that long. Use http_request() with an options JSON to set a tighter deadline:
UPDATE and DELETE Triggers
The same pattern works for updates and deletes. UseOLD to include the previous values:
IF NEW.status != OLD.status guard avoids firing the webhook on UPDATE statements that don’t change the status — keeping webhook volume proportional to meaningful changes.
Authentication
Pass API keys or bearer tokens in theheaders_json argument of http_request():
Important Caveats
Triggers are synchronous. The HTTP call blocks until it completes or times out. A webhook endpoint that’s slow or down will hold up every write to that table. Always set a short timeout (2–5 seconds) and design the endpoint to respond immediately (queue the work, don’t process it inline). Failures are silent by default. If the HTTP call returns NULL (connection failure), the trigger doesn’t raise an error and the write succeeds. A non-2xx response also returns silently —http_post() returns JSON regardless of status code, and the trigger doesn’t inspect it. If reliable delivery matters, use a transactional outbox pattern instead: write events to an outbox table in the same transaction, then deliver them with a separate process.
Triggers fire once per row. FOR EACH ROW means a bulk UPDATE orders SET status = 'shipped' hits 1000 rows sends 1000 webhook calls. That can overload the endpoint and exhaust connection limits. For bulk operations, suppress the trigger or use the outbox pattern.
No retry logic. A failed request stays failed. Build retry and dead-letter handling in the receiving system or the outbox process, not in the trigger.
Troubleshooting
| Problem | Solution |
|---|---|
| Writes become slow | Webhook endpoint is slow — set a short timeout in http_request() options |
| Trigger body error on creation | Check DELIMITER $$ is set before CREATE TRIGGER |
| No webhook received | NULL return means connection failed — verify network access from server host |
| Too many webhook calls on bulk UPDATE | Guard with IF NEW.col != OLD.col or suppress trigger for batch operations |
Next Steps
- Making HTTP requests from SQL — full function reference including response parsing
- Enriching rows with API data — pull external data into your tables
- Triggers in MySQL — general trigger patterns and BEFORE vs AFTER semantics

