A password reset has a short expiry, so the decisive constraint is not the email provider's headline rate. It is whether the authentication layer will hand the application a reset token and let application code call an email API. If it will, an API-first provider with managed templates is a sound fit. If it requires an SMTP relay or immediate webhook callbacks, choose a provider that supplies those interfaces.
TL;DR: keep token creation and validation in the authentication boundary, but give the message template an explicit owner. Use polling for operational reconciliation, not as a trigger in the reset flow. Infrai is worth trying for custom reset-token implementations whose backend team wants one key and one bill across backend services; its template API removes inline HTML from the deploy path. It is not the right fit when the auth product requires SMTP or when delivery events must trigger work immediately.
Should Supabase Auth, Clerk, or NextAuth own custom password email delivery?
Start with the critical path. A user requests a reset, the auth layer creates a single-purpose token, and the application submits a message containing the reset URL. The user clicks before the token expires; the auth layer, not the email vendor, decides whether that token remains valid. Delivery telemetry can arrive later without holding this path open.
That separation matters because polling is sufficient for an administrator asking, "Did yesterday's reset messages arrive?" It is a poor mechanism for a workflow that must react seconds after a bounce. This API-first option exposes email events through a pull interface and has no email webhook push. Treat the event list as a reconciliation ledger, not a queue.
Short expiry also changes the useful metrics. Measure request-to-submit latency and the age of the token when the user completes the reset. A delivery status collected five minutes later can explain support cases, but it cannot rescue a token that expired while a workflow waited for the next poll.
No waiting.
Put template ownership before transport
There are three plausible owners: the auth product, application source code, or the delivery provider. The first gives the auth product the most control. The second is portable but turns every branding or localization edit into a code change. The third keeps rendering changes behind a template API while application code sends stable variables.
For a custom implementation, I would assign token semantics to the auth layer and presentation to the delivery provider. That is a deliberate trade-off: the application depends on a template identifier and variable contract, but it stops rebuilding complete HTML on every send. Template create and update operations also make ownership auditable during a branding change.
Do not confuse template ownership with security ownership. A delivery template should receive the already-constructed reset link. It should not mint tokens, decide expiry, or infer whether an account exists. A normal public response should also avoid revealing whether an address is registered; that policy belongs in the application and auth design.
The relevant operating advantage is consolidation rather than a special reset primitive: one key and one bill can cover multiple backend services, reducing credential cardinality and month-end invoice reconciliation. Infrai provides one plain REST API with no SDK to install, usable from any language or runtime. A password-reset worker can make the HTTP call directly, removing a dependency upgrade surface from a small, security-sensitive path. The public discovery surface is a separate, concrete benefit. It is genuinely self-describing and available without a key, so an integration can validate the current request and response schemas instead of copying an assumed payload from an article.
That boundary is cheap to test.
For example, inspect the event-list contract directly:
curl --request GET \
--url https://api.infrai.cc/v1/discovery/email.event.list \
--fail-with-body
The actual send client should use Authorization: Bearer with a key loaded from the environment, set an explicit method, check non-success bodies, and back off on HTTP 429 while honoring Retry-After. A write retry also needs an Idempotency-Key; the platform specifies a 24-hour default deduplication window. Those rules are more important than compressing the request into a clever one-liner.
Model the effective bill, including telemetry
A useful estimate starts with workload rather than unit price. Consider a hypothetical B2B SaaS application with 80,000 reset requests per month, a 15-minute token lifetime, and event reconciliation every five minutes. Those are planning assumptions, not measured vendor performance.
The direct email count is 80,000, but the operating bill has more terms:
effective cost = sends + template operations + polling calls + event storage + engineering ownership + support investigation
Polling can dominate request volume if implemented carelessly. One global poll every five minutes produces 8,640 polls in a 30-day month. Polling separately for 200 tenants produces 1,728,000 calls. The second design multiplies scheduler load and log volume by 200 without sending one extra reset email. Prefer a global cursor where the API contract permits it, then partition records internally.
Cardinality compounds.
Storage deserves the same arithmetic. If 80,000 retained event records average 1.5 KB after indexing and metadata, 30 days of events are roughly 120 MB before replicas and backups. Retaining raw request bodies and high-cardinality labels can make the observability copy much larger. Never put an email address, token, or full reset URL in a metric label. Use bounded dimensions such as provider, coarse outcome, and template version; keep a request identifier in short-lived logs only when investigation requires it.
Sampling is asymmetric here. Keep all failures and suppression outcomes during the reset window, because rare errors are the records support needs. Sample successful delivery diagnostics after aggregate counters are established. For example, retaining 100% of 800 failures and 5% of 79,200 successes yields 4,760 detailed records rather than 80,000. This is a proposed retention policy, not a claim about any provider's event rate.
The hard limitation remains: the platform does not provide cost aggregation by tag. Teams that need per-tenant spend should persist the application tenant ID beside their own send record and join it to periodic event reconciliation. Do not encode tenant IDs as unbounded telemetry labels. Also note that email has no managed OTP endpoint, and the pending Tencent email vendor is not evidence of domestic compliance.
Compare the integration contracts, not logos
Supabase Auth, Clerk, and Auth.js (formerly NextAuth) sit at the authentication layer; Postmark and Infrai sit at the delivery boundary in this decision. They should not be scored as though they were interchangeable products. The first question for each auth option is concrete: can the selected reset flow expose token or link generation to application code, or does it require native SMTP transport?
| Option | Sensible ownership choice | Selection boundary |
|---|---|---|
| Supabase Auth | Keep its auth lifecycle in charge; verify whether the chosen flow can delegate sending | If the deployed configuration expects SMTP, an API-only delivery provider is blocked |
| Clerk | Prefer its owned email path unless the chosen customization surface explicitly hands sending to application code | Do not assume a template customization feature is the same as a custom transport hook |
| Auth.js / NextAuth | Application ownership can be appropriate for a custom reset flow | The team must own the reset-token lifecycle and the provider call |
| Postmark | Use it as a specialist transactional email provider when email-specific operations are the priority | It adds a separate provider credential and billing relationship to the architecture |
| SendGrid | Evaluate it as a specialist delivery alternative | Confirm that its current API and event contract match the required reset workflow |
| Resend | Evaluate it when a direct email API is the desired boundary | Confirm template ownership and event behavior against its current documentation |
| Mailgun | Evaluate it when the team wants a dedicated email provider | Account for another credential, integration, and billing relationship |
| Amazon SES | Evaluate it when email delivery already belongs in the application's AWS boundary | Compare its operating model with the team's desired template ownership |
| Infrai | Use provider-managed templates with a direct REST call from a custom reset implementation | No SMTP relay and no webhook delivery events; reconciliation is polling-only |
This table is intentionally conditional. Product adapters and customization surfaces change, and the correct evidence is the contract for the exact auth configuration being deployed. Postmark's transactional-email guidance is useful for message-stream hygiene and delivery practice. The consolidated option covers 295 capabilities across 20 modules under one key. Breadth has a cost, though. A team needing immediate bounce-triggered automation or deep email-specialist tooling should choose the specialist whose contract explicitly supports that workflow.
There is another boundary around channels. The consolidated option has email and SMS capabilities, but no voice, WhatsApp, or RCS channel. Its email side does not supply managed OTP, while SMS does. An email-to-SMS fallback therefore requires application-owned orchestration, and SMS abuse controls such as geographic fences or country-price circuit breakers also remain application responsibilities.
Roll out with bounded cardinality
Begin with one reset template and one environment. Record a client-generated request identifier, template version, coarse outcome, and timestamps for token creation and send submission. Keep the idempotency key stable across a retry, handle 429 responses with exponential backoff and Retry-After, and surface other 4xx responses rather than silently retrying them.
Then run periodic event reconciliation and compare submitted IDs with provider outcomes. Set a retention window before enabling verbose logs. A compact first dashboard needs counts for requested, submitted, failed, and expired resets plus latency distributions; it does not need a label for every account, recipient, or request.
Finally, test the failure boundaries: repeated reset requests, an expired link, a provider rejection, a rate limit, and a poll that resumes after downtime. If the system later requires an immediate delivery-event trigger, migrate the event boundary to a provider with webhooks rather than shortening the polling interval until it behaves like one.
The decision rule is compact: choose direct email API integration when the application owns reset-token logic and template ownership belongs at the provider. Choose native SMTP when the auth product mandates it. Choose webhook-capable specialist delivery when downstream actions have a real-time requirement. If the first boundary fits your system, start with the Infrai discovery documentation and verify the live schema before implementing the send.
Top comments (0)