fix(mails): give each concurrent send its own kept-alive SMTP session by ChiragAgg5k · Pull Request #13722 · appwrite/appwrite · GitHub
Skip to content

fix(mails): give each concurrent send its own kept-alive SMTP session - #13722

Merged
ChiragAgg5k merged 2 commits into
mainfrom
fix/mails-smtp-session-per-send
Sep 16, 2026
Merged

ChiragAgg5k merged 2 commits into
mainfrom
fix/mails-smtp-session-per-send

Conversation

@ChiragAgg5k

Copy link
Copy Markdown
Member

What does this PR do?

The smtp registry entry becomes a utopia-php/pools pool of SMTP adapters, sized to _APP_WORKER_MAX_COROUTINES, and the mails and notifications workers borrow one adapter through Pool::use() for the length of a send. A project's own SMTP config is still dialled per send, now with keepAlive: false, since that adapter is never held.

Why

The entry was one SMTP adapter with keepAlive: true, cached for the life of the worker process. Workers run up to _APP_WORKER_MAX_COROUTINES jobs at once, so concurrent sends wrote into the same socket and desynchronised the session. A kept-alive session belongs to one send at a time, and the pool is what enforces that.

This is the consumer-side half of utopia-php/monorepo#282, which makes the kept session survive a server-side idle close by probing it before reuse. That fix lands with the next utopia-php/messaging release and needs no further change here; this PR works against the currently released 2.1 as well.

Test plan

  • tests/unit/Platform/Workers/MailsTest.php and NotificationsTest.php register the spy adapter through a Pool on the Stack adapter and pass unchanged in behaviour.
  • Mail E2E suites exercise the pooled path through the worker.

Related PRs and issues

The smtp registry entry was one SMTP adapter with keepAlive on, cached for
the life of the worker process. Workers run up to _APP_WORKER_MAX_COROUTINES
jobs at once, so concurrent sends wrote into the same socket and desynchronised
the session. The entry is now a utopia-php/pools pool of adapters sized to
the coroutine count, and the mails and notifications workers borrow one for
the length of a send. A project's own SMTP is dialled for one send, so it no
longer asks for keepAlive it never uses.
@greptile-apps

greptile-apps Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Comment thread app/init/registers.php Outdated
Comment thread tests/unit/Platform/Workers/MailsTest.php
@github-actions

github-actions Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

✨ Benchmark results

Comparing main (before) → fix/mails-smtp-session-per-send (after).

Metric Before After Change
🚀 Requests/sec 174.7 175.94 ⚪ +0.7%
⏱️ Latency P50 98.6 ms 98.66 ms ⚪ +0.1%
⏱️ Latency P95 235.38 ms 232.78 ms ⚪ -1.1%
Per-scenario breakdown & investigation details

Metrics below reflect the current branch (after). Δ P95 compares against the base.

Scenario P50 (ms) P95 (ms) Requests RPS Δ P95 (ms)
API total 98.66 232.78 11,400 175.94 -2.59
Account 186.82 374.02 600 10.03 +20.03
TablesDB 93.85 180 6,200 99.88 -4.44
Storage 93.61 203.7 3,000 49.31 +5.59
Functions 144.54 285.01 1,600 26.71 -8.78

Top API waits (after)

API request Max wait (ms)
account.name.update 570.68
storage.buckets.create 511.76
tablesdb.rows.create 448.09
tablesdb.rows.delete 436.84
functions.variables.delete 435.96

@ChiragAgg5k
ChiragAgg5k merged commit 8a85ce9 into main Sep 16, 2026
49 checks passed
@ChiragAgg5k
ChiragAgg5k deleted the fix/mails-smtp-session-per-send branch September 16, 2026 11:28
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.

2 participants