Custom Middleware vs Message Gateway: Which Wins
Full control, or zero code — decide before six months in.
- The demo is a weekend; the maintenance is forever.
- "Just build it" is 200 happy-path lines — 2,000 once concurrency shows up.
- Middleware: no per-message fee, real upkeep. Gateway: a service cost, ~0 engineering.
The problem
- Raw inbound messages are messy, and your agent pays for it.
- You have two honest ways to clean them before the LLM — and they trade opposite things.
- Pick wrong and you either maintain plumbing forever or hit a config wall on logic that's truly yours.
The solution
Both intercept the message, filter the junk, and forward something clean — they differ in who writes and maintains the logic.
- Custom middleware: your code → total control, total ownership.
- Message gateway: a service you point your webhook at → zero code, one dependency.
Build when the filtering logic is your product. Configure when it's plumbing you want gone, not owned.
Many teams run both: a gateway for the standard filtering, a thin slice of custom logic for the one thing that's theirs.
Every team that ships an AI agent eventually hits the same wall: the raw inbound messages are messy, and the agent pays for it. You have two honest ways to clean them up before the LLM — write custom middleware yourself, or put a message gateway in front. This is a fair comparison of what each one actually costs, where each one wins, and how to decide without regretting it in six months.
The decision, stated plainly
Custom middleware is your own code (an Express layer, a Cloudflare Worker, a Lambda) that you build, host, and keep running. A message gateway is a prebuilt service you point your webhook at; you configure rules instead of writing them. The right answer depends on how custom your filtering really is, and how much maintenance you want to own.
Option 1: custom middleware — full control, full ownership
Custom middleware wins when your filtering logic is genuinely unique. You hold every decision — exactly how deduplication hashes a payload, how long the merge window stays open, what “spam” means for your product. Nothing is hidden behind someone else’s config. The cost is everything that comes with owning code:
- You build the hard parts yourself. Deduplication, a time-windowed buffer to merge fragments, rate limiting, retries — none of it comes out of the box.
- You keep it running. Deploys, monitoring, the 3am page when the buffer leaks memory, the edge cases you discover in production.
- State is on you. Merging burst messages means holding them somewhere for a few seconds; that’s a stateful service, not a pure function, and stateful is where the bugs live.
Option 2: message gateway — zero code, external dependency
A message gateway wins when your filtering is standard — dedupe, merge fragments, rate-limit, route by keyword — and you’d rather configure it than maintain it. You change your webhook URL once and define rules; the common problems are already solved and kept running for you. The honest trade-offs:
- It’s a dependency you don’t control. Another hop in the path, another service whose uptime matters to yours.
- Config has limits. If your logic is truly exotic, rules may not express it — exactly the case where middleware wins.
- You trust someone else’s implementation. The upside is you don’t maintain it; the downside is you can’t rewrite it.
Option 1 (middleware) vs Option 2 (gateway)
Neither is wrong — one trades time for control, the other control for time:
| Custom middleware | Message gateway | |
|---|---|---|
| Time to first filter | ✕Days to weeks | ✓A URL change |
| Control over logic | ✓Total | ~Within config |
| Dedup / merge / rate-limit | ✕You write it | ✓Out of the box |
| Ongoing maintenance | ✕Yours forever | ✓Managed |
| External dependency | ✓None | ~One more hop |
| Fits truly exotic logic | ✓Anything | ~Config limits |
When each one is the right call
Pick custom middleware when the filtering itself is a differentiator — bespoke scoring, a model-based classifier you own, logic so specific no config could express it. If engineering time is cheaper to you than a dependency, build it.
Pick a message gateway when the filtering is table stakes you want off your plate — the same dedup, merge, and rate-limit every agent needs. If you’d rather spend that engineering time on the agent instead of the plumbing in front of it, configure it. For standard filtering, filtering input before it hits the LLM is usually cheaper to configure than to build and keep running. It’s the heart of message quality for AI agents.
If the gateway side sounds like you, here’s the short version of how to set it up: configure the plumbing instead of owning it →.
Either way — go get clean messages to your agent.
Thanks for reading. 👋
Orlando. -
Orlando Quijada
Technologist with 15+ years of experience. Developer, SaaS tester, and AI collaboration & optimization specialist. Currently contributing at portarus.com.
Written on