Every builder does it once. You want to know when someone pays, so you point a Discord webhook at a private channel and POST a message from your server. Payment lands, phone buzzes, little green embed. It costs nothing and it works the same day you think of it.
As a day-one hack, it is genuinely good. This post is about what happens after day one.
The webhook that 429s at the worst moment
Discord webhooks are rate limited to roughly 30 messages a minute per channel. On a normal Tuesday you never notice. Then you launch. Product Hunt, a tweet that lands, a newsletter mention, and suddenly your app is emitting hundreds of events an hour.
Discord starts answering 429 Too Many Requests. Your fire-and-forget helper does what it was built to do: it fails quietly and moves on. The events from the biggest hour of your product's life are the ones that never made it to the channel.
The feed did not degrade gracefully. It degraded invisibly.
An error at 2 PM is gone by 2:40
Even when every message arrives, a chat channel is the wrong shape for events. The one card that mattered, a checkout.session.completed that failed verification, scrolls away under forty signup notifications. There is no filter for failures, no per-user history, no way to search "everything that happened to richard@piedpiper.com this week." Your agent cannot query a chat scrollback either.
And somewhere around week two, you mute the channel. Everyone does. Sixty buzzes a day trains you to stop looking, which is the exact opposite of what an alert channel is for.
A quiet channel looks exactly like a healthy one
Here is the failure that decides the argument. At some point the pipe itself dies. Someone regenerates the webhook URL while cleaning up the server. A channel gets archived. A migration drops the env var that held the webhook.
Discord does not notify your app that the webhook is gone. Your app does not notice either, because the helper never throws. From that moment your alert channel shows perfect peace while production does whatever it wants.
Think about what that means: the channel being silent is supposed to mean things are fine. Now silence also means the alerting itself is dead. You cannot tell the two apart by looking, and looking is all a Discord channel lets you do.
The alert Discord can never send
All three failures above share a root cause. A chat channel can only display messages that arrive. It has no opinion about messages that should have arrived and did not. The webhook that stopped firing, the cron that skipped the night, the agent that hung mid-run: none of them produce a message, so the channel stays clean and green.
That absence is the thing worth paging on. logs.so watches each channel's rhythm and pages you when a channel that should have moved, didn't. Payments sees a checkout roughly every 15 minutes, then nothing for 26: payments went quiet. No checkout.session.completed for 26 minutes. Expected one every 15. That page fires whether the cause is a broken webhook, a dead cron, or your event pipe itself falling over. Silence is the symptom of all of them.
Keep Discord for the community
Nothing here says leave Discord. It is where your users hang out and where your team talks. It is just not an error budget.
Moving the events is not a project. Your events are already one HTTP POST; pointing them at logs.so is the same POST with a different URL and a JSON body, and a coding agent can do it in one pass from one prompt. The feed is free: unlimited events, 7-day history, no rate-limit babysitting, no card, no trial clock. Searchable, filterable, per-user timelines, readable by your agent over MCP.
When the quiet starts to matter, Pro is $19/mo for silence detection and full history. Self-serve, cancel anytime.
Start free, re-point the webhook, and let the channel that watches your app be one that can also notice when your app stops talking.
Related: Your LogSnag feed looks fine. Production still died.
silence, server-side
Get paged when a channel that should have moved, didn't.
Free: unlimited events, 7-day history, no card. Pro is $19/mo for silence detection.