Every SaaS product hits the same wall:
- “We just need to POST to this webhook.”
- “We just need to push new customers into our CRM.”
- “We just need to notify a partner when an event happens.”
So you add a couple of HTTP calls, maybe a job queue, and it works… until it doesn’t.
The slow death by one-off integrations
A familiar progression:
1. Inline HTTP calls
You fire off requests to HubSpot, Salesforce, or a webhook inside your main request cycle.
- If the call is slow, your API is slow.
- If the call fails, you have to decide: retry? swallow? error?
2. Background jobs and queues
You add a queue (Bull, Sidekiq, SQS, etc.) and fork work into workers.
- Better latency, but now you own:
- retry policies
- backoff
- dead-letter queues
- poison messages
3. Each integration becomes its own mini-platform
Different auth, payloads, rate limits, and error semantics mean:
- per-integration code paths
- per-integration retry quirks
- per-integration dashboards or logs
Over time you’re not just maintaining your product—you’re maintaining a one-off integration platform.
What you really need: a dedicated integration layer
Step back and most integrations follow the same pattern:
1. Something happens in your app
e.g. lead.created, subscription.renewed, invoice.paid.
2. You emit an event with a clean payload.
3. Routing & fan-out decide:
- which destinations should receive it
- how the payload should be mapped
- when conditions should block or alter behavior
4. Delivery engine handles:
- queues & parallel fan-out
- retries & backoff
- rate limiting
- dead letters & observability
That’s what a universal integration layer (like Meshes) is built to do.
Instead of sprinkling webhook calls and queue logic all over your codebase, you:
- define event types (e.g.
lead.created) - configure rules and connections
- send events to one API, and let the integration layer handle the rest
