Repository navigation
Conversation
Operator-listener deliveries reached the listener 0.25-2s after the mention committed, because the delivery worker only found new outbox rows on its idle poll. A batch of claimed deliveries also had to finish completely before the worker claimed again, so one slow endpoint (up to the 5s timeout) held up every mention queued behind it. The enqueue inside the event-insert transaction now runs pg_notify when it adds rows. Postgres delivers that only on commit, and every delivery worker LISTENs on its own connection outside the serving pool, so a worker on any pod wakes as soon as the row is claimable. The idle poll stays as the fallback for lost notifications and scheduled retries. The worker now keeps up to 10 deliveries in flight and claims again whenever a slot frees, instead of waiting for the slowest POST in a batch. Measured on a local relay (mention accepted -> listener POST received, 15 mentions 2.5-4s apart): main median 871ms, max 1.95s; this change median 1.9ms, max 3.9ms. Co-authored-by: murderbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Operator-listener deliveries (the push path kgoose uses to wake remote agents) reached the listener 0.25–2s after the mention committed. The delivery worker only found new outbox rows on its idle poll, which backs off from 250ms to 2s. A claimed batch also had to finish completely before the worker claimed again, so one slow endpoint (up to the 5s timeout) held up every mention queued behind it.
What changed
enqueue_mentions_in_transactionrunspg_notifywhen it adds outbox rows. Postgres sends the notification only when the event transaction commits and drops it on rollback, so workers wake only for rows they can already claim. Each delivery workerLISTENs on a dedicated one-connection pool, so it never takes a serving-pool slot. Every pod with a worker gets the wake, and the existingSKIP LOCKEDclaim decides which pod delivers.JoinSetand claims again whenever a slot frees, rather thanjoin_allon a batch of 10.Measured
Local relay. Each latency runs from
POST /eventsaccepted to the listener receiving the delivery, with 15 mentions spaced 2.5–4s apart so the worker sits at its idle ceiling:I also killed the
LISTENbackend withpg_terminate_backendmid-run. sqlx reconnected on a new backend right away, and the next mentions were still about 2ms.Tests
buzz-dbPostgres tests: a committed mention wakes a listener, and a rolled-back one does not.buzz-relayPostgres test: a committed mention wakes the realrun_wake_listener.buzz-relayunit tests drive the productionrun_delivery_loop:pg_notify, nonotify_one.Tradeoffs worth a look
NOTIFYtakes a database-wide lock at commit. Only event inserts that actually enqueue listener rows pay that, which today means mentions of registered agents.LISTENneeds a direct session. bbpci pointsDATABASE_URLstraight at the Aurora writer, so that works. A transaction-pooling proxy in front would silently fall back to the poll.LISTENsocket that never errors would also silently fall back to the poll. sqlx has no TCP keepalive here. Possible follow-up: a timeout with a heartbeat, plus a metric.🤖 Generated with Claude Code