Webhook, Apache Kafka, AWS SQS, and Postgres LISTEN/NOTIFY solve one production question: how does an external event start an AI agent run? The choice depends on delivery, ordering, replay, backpressure, and response latency. This comparison stays at that inbound trigger boundary; outbound result delivery and MCP tool calls are separate decisions.
Four inbound paths to the same agent run
All four are inbound connectors: an external event arrives, Connic parses it, and one run starts for every linked agent with the payload attached. The connector layer handles receiving the event, authenticating the source, and retrying or buffering where the protocol supports it. The agent can stay unchanged while the event path changes underneath it. See how inbound, outbound, and sync modes differ.
Webhook: synchronous HTTP push
A webhook connector gives your agent a URL. Any service that can make an HTTP request triggers one run for every linked agent by posting to it, authenticated with a shared secret in the X-Connic-Secret header. It is the direct HTTP option and the only one that can hand the result straight back: in sync mode the request blocks until the run finishes and returns its output, which is what a chat UI or a synchronous API call needs.
curl -X POST "<webhook-url>" \
-H "X-Connic-Secret: <your-secret-key>" \
-H "Content-Type: application/json" \
-d '{"order_id": "12345", "action": "review"}'Until Connic accepts the request, delivery belongs to the caller: retry transport failures and unsuccessful responses. In inbound mode, a successful response includes run IDs that Connic has created. Monitor those run IDs for dispatch or execution failure; the HTTP response does not prove that queue publication succeeded. The source still has no durable event log or ordering between concurrent calls. A caller that retries should send a stable event ID or idempotency key. The receiving agent or tool must persist processed IDs and check them before repeating a side effect; the webhook connector does not deduplicate arbitrary payloads. Follow the webhook sync setup for sync mode and review outbound signature verification.
Apache Kafka: streaming consumer
A Kafka connector subscribes to a topic as a consumer and starts one run for every linked agent on each message. The full Kafka context (topic, partition, offset, key) arrives under a _kafka field. Because Kafka is a durable, ordered log, this pattern preserves order within a partition and can replay retained history with a new consumer group configured to start at the earliest offset. Connic commits the offset after it creates a run for every linked agent. A restart before that commit can redeliver the message and duplicate a run already created; after the commit, a created run that fails before or during execution does not make Kafka redeliver the message.
{
"order_id": "12345",
"customer": "john@example.com",
"items": ["widget-a", "widget-b"],
"_kafka": {
"topic": "orders",
"partition": 0,
"offset": 1542,
"key": "order-12345"
}
}Consumers that share a group ID split partitions between them. Separate group IDs consume the same retained stream independently. Inside Connic, one connector fans each message out to every agent linked to that connector. Reach for Kafka when you already run it, when throughput is high, or when ordering and replay matter. The cost is operational: you need a cluster, and the connector is a consumer in it. Review the Kafka connector settings.
Postgres LISTEN/NOTIFY: in-database push
If the event you care about is a change in your database, you may not need a queue at all. The Postgres connector opens a persistent connection and listens on a channel; a trigger calls pg_notify when rows change, and each notification starts one run for every linked agent. There is no polling and no extra infrastructure: the database you already have becomes the event source.
-- Notify the agent whenever a customer row is inserted
CREATE OR REPLACE FUNCTION notify_new_customer()
RETURNS TRIGGER AS $$
BEGIN
PERFORM pg_notify(
'new_customers',
json_build_object('customer_id', NEW.id)::text
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER customer_insert_trigger
AFTER INSERT ON customers
FOR EACH ROW
EXECUTE FUNCTION notify_new_customer();NOTIFY keeps no replay log for a disconnected listener. A notification sent while the connector is disconnected is missed, and reconnecting does not recover it. PostgreSQL's documentation, checked in 2026, sets the default payload limit below 8000 bytes, so send an ID and let the agent fetch the full row. Check PostgreSQL's NOTIFY delivery and payload limits. Use LISTEN/NOTIFY for near-real-time reactions to data changes where an occasional miss during a reconnect is acceptable, and use Kafka or SQS when every change must be processed. If the database sits in a private network, route it through Bridge instead of exposing it. See how to reach private infrastructure through Bridge. Follow the Postgres LISTEN/NOTIFY setup.
AWS SQS: durable polled queue
An SQS connector polls a queue with long polling and starts one run for every linked agent per message. Messages persist until every linked run completes and the connector deletes them, so worker restarts and traffic spikes do not discard queued work. If a run fails, the message reappears after its visibility timeout and is retried; messages that fail repeatedly can be routed to a dead-letter queue you configure in AWS. Standard queues do not guarantee order, while FIFO queues preserve it within a message group.
This is the pattern for reliable asynchronous work that must survive failure without you building the retry machinery yourself. AWS documentation checked in 2026 allows a long poll to wait up to 20 seconds when the queue is empty; the request returns sooner when a message arrives. Review the AWS SQS long-poll limits. You also need an AWS account and credentials. Review the SQS queue and polling settings.
Side by side
Delivery, ordering, replay, backpressure, and latency distinguish these triggers:
| Dimension | Webhook | Kafka | Postgres | SQS |
|---|---|---|---|---|
| Trigger style | Synchronous HTTP push | Streaming consumer | In-database push (NOTIFY) | Polled queue |
| Delivery guarantee | Caller-controlled | Run creation before offset commit | At-most-once | At-least-once |
| Ordering | None | Per partition | Commit order while connected | None (FIFO: per group) |
| Buffering / replay | None | Durable log, replayable | No replay after disconnect | Durable queue, no replay |
| Backpressure | Caller rate limits/timeouts; accepted runs wait in Connic | Consumer lag | Server notification queue can fill; no consumer replay | Queue absorbs spikes |
| Typical latency | Direct request (can return result) | Near-real-time | Near-real-time | Long poll (returns on message) |
| Extra infrastructure | None | Kafka cluster | Reuse your database | AWS account + queue |
Choosing a pattern
Set up a webhook endpoint, Kafka consumer, SQS queue, or Postgres listener and link it to an agent.
Open the connector setup guides