Skip to content

Fix PostgreSQL DelayedSubscriber timezone query bug#53

Merged
m110 merged 1 commit intoThreeDotsLabs:masterfrom
AlfandiMario:fix-delayed-postgresql-timezone-bug
Oct 28, 2025
Merged

Fix PostgreSQL DelayedSubscriber timezone query bug#53
m110 merged 1 commit intoThreeDotsLabs:masterfrom
AlfandiMario:fix-delayed-postgresql-timezone-bug

Conversation

@AlfandiMario
Copy link
Copy Markdown
Contributor

Fixes #631 ThreeDotsLabs/watermill#631

Motivation / Background

This PR fixes a timezone query bug in the PostgreSQL DelayedSubscriber (and DelayedRequeuer) where messages with expired _watermill_delayed_until timestamps aren't republished when the server timezone differs from UTC (e.g., GMT+7). The issue causes failed messages to stay stuck in the queue indefinitely.

Root cause: The query uses NOW() AT TIME ZONE 'UTC', which strips timezone info and interprets timestamps in the local server timezone, leading to incorrect comparisons. This breaks delayed requeuing in non-UTC environments.

Fixes #631.

Details

  • Change: In pkg/sql/delayed_postgresql.go (line 87), remove AT TIME ZONE 'UTC' from the WHERE clause.
  • Before: (metadata->>'_watermill_delayed_until')::timestamptz < NOW() AT TIME ZONE 'UTC'
  • After: (metadata->>'_watermill_delayed_until')::timestamptz < NOW()
  • Why it works: PostgreSQL handles timestamptz comparisons in UTC internally, so NOW() (a timestamptz) compares correctly against stored UTC timestamps without manual conversion.
  • Testing: Verified locally with PostgreSQL 16 in GMT+7—messages now republish as expected. No breaking changes; existing UTC setups remain unaffected.

Alternative approaches considered (if applicable)

None—removing the timezone clause is the simplest, idiomatic fix. Adding explicit UTC casting (e.g., NOW() AT TIME ZONE 'UTC') was considered but rejected as it reintroduces the bug. Over-engineering with config options for timezones would violate KISS.

Checklist

  • I wrote tests for the changes. (Added unit tests for the query logic in non-UTC scenarios.)
  • All tests are passing. (Ran make test_short and full make test with Docker.)
  • Code has no breaking changes. (Query change is backward-compatible.)
  • (If applicable) documentation on watermill.io is updated. (No docs needed for this internal query fix.)

@m110
Copy link
Copy Markdown
Member

m110 commented Oct 28, 2025

Thank you @AlfandiMario! 🤝

@m110 m110 merged commit e26c90d into ThreeDotsLabs:master Oct 28, 2025
5 checks passed
@AdrianZajkowski
Copy link
Copy Markdown
Contributor

@m110 I think delayed_mysql was done to be consistent with postgres. With this change should mysql part be corrected as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants