Hacker News new | past | comments | ask | show | jobs | submit login

Implementing webhook deliveries is one of those things that's way harder than you would initially imagine. The two things I always look for in systems like this are:

1. Can it handle deliveries to slow on unreliable endpoints? In particular, what happens if the external server is deliberately slow to respond - someone could be trying to crash your system by forcing it to deliver to slow-loading endpoints.

2. How are retries handled? If the server returns a 500, a good webhooks system will queue things up for re-delivery with an exponential backoff and try a few more times before giving up completely.

Point 1. only matters if you are delivering webhooks to untrusted endpoints - systems like GitHub where anyone can sign up for hook deliveries.

2. is more important.

https://github.com/xataio/pgstream/blob/bab0a8e665d37441351c... shows that the HTTP client can be configured with a timeout (which defaults to 10s https://github.com/xataio/pgstream/blob/bab0a8e665d37441351c... )

From looking at https://github.com/xataio/pgstream/blob/bab0a8e665d37441351c... it doesn't look like this system handles retries.

Retrying would definitely be a useful addition. PostgreSQL is a great persistence store for recording failures and retry attempts, so that feature would be a good fit for this system.




I think retries are sketchy. Sometimes they really are necessary, but sometimes the API can be designed around at-most-once semantics.

Even with a retry scheme, unless you are willing to retry indefinitely, there is always the problem of missed events to handle. If you need to handle this anyway, it might as well use this assumption to simplify the process and not attempt retries at all.

From a reliability perspective, it is hard to monitor whether the delivery is working if there is a variable event rate. Instead, designing it to have a synchronous endpoint the web hook server can call periodically to “catch up” has better reliability properties. Incidentally, this scheme handles at-most-once semantics pretty well, because the server can periodically catch up on all missed events.


That's a good call: having a "catch me up" API you can poll is a very robust way of dealing with missed events.

Implementing robust retries is a huge favor you can do for your clients though: knowing that they'll get every event delivered eventually provided they return 200 codes for accepted events and error codes for everything else can massively simplify the code they need to write.


Hi there! I'm one of the authors of the pgstream project and found this thread very interesting.

I completely agree, retry handling can become critical when the application relies on all events being eventually delivered. I have created an issue in the repo (https://github.com/xataio/pgstream/issues/67) to add support for notification retries.

Thanks for everyone's feedback, it's been very helpful!


Really any time you're using a distributed system, you should ask yourself, do I need retries? Do I need circuit breakers? Do I need rate limits?

The answers are probably either "yes" or "yes, but not yet."


>a good webhooks system will queue things up for re-delivery with an exponential backoff and try a few more times before giving up completely.

Microsoft's Graph API also requires consumers to re-register webhooks every N days, a kind of "heartbeat" to make sure the webhooks aren't sent to a dead server forever.


This is definitely an interesting idea. Pgstream does offer the ability to unsubscribe from the notifications (https://github.com/xataio/pgstream/blob/main/pkg/wal/process...), but it relies on the receiver actively making that request.

It can be annoying to have to re-subscribe every N days when your application is working as expected though. I wonder if one way to work around this could be to "blacklist" servers that have failed consistently for an amount of time. They could be deleted from the subscriptions table if they remain inactive once they've been blacklisted.

I have opened an issue in the repo to track this (https://github.com/xataio/pgstream/issues/68), since it would be a critical feature to avoid denial-of-service attacks.

Thanks for your feedback!


They should defo use Svix[1], I'll reach out to the blog author, this looks like a cool blog post and use-case.

1: https://www.svix.com




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: