Skip to main content
MailCub Logo Image
Guidelines

Laravel Transactional Email Setup with Queue, Retry, and Webhooks

By MailCub TeamFeb 24, 202612 min read

Introduction

A Laravel app usually sends transactional email at the most sensitive moments: signups, OTPs, password resets, invoices, and payment receipts. If sending is slow or unreliable, users feel it immediately, support tickets increase, and critical flows break.

This guide is for SaaS and development teams who want a production-safe Laravel transactional email setup using queues, controlled retries, and webhook-driven event tracking. The goal is to separate email sending from request/response latency, retry only the failures that should be retried, and connect your app logs with provider delivery logs so debugging becomes fast and consistent.

The provided content references MailCub for the send endpoint, auth header, common response codes, and where to find analytics and logs in the dashboard. Start with MailCub Documentation and send your first queued Laravel email so you have message IDs you can trace in logs.

Quick Answer

  • Put all transactional sends into a queue job, not inside the web request.
  • Retry only transient failures like timeouts or 429 rate/quota errors.
  • Store a correlation ID and provider message ID for every send.
  • Use delivery logs and analytics to debug “not received” reports quickly.
  • Add webhook event handling for bounces and failures so your app state stays accurate.

Why It Matters

Queues are not only about performance. They are a reliability control. If email sending is synchronous, a provider issue can turn into slow pages, request timeouts, duplicate sends, and user frustration.

Retries can also make things worse when they are not controlled. Retrying the wrong errors can create bursts, trigger throttling, and repeatedly send to bad addresses. The provided content notes that MailCub gives response codes that help separate retryable errors from errors that need a human or configuration fix.

Without event tracking and logs, “email didn’t arrive” becomes guesswork. The provided content also notes that MailCub includes analytics and per-message delivery logs with status and error messages, which makes support and troubleshooting much easier.

Laravel Transactional Email Architecture (Queue + Retry + Webhooks)

A practical production pattern for most SaaS apps looks like this:

  • Your controller or service creates an EmailSend record with a pending state.
  • A queue job is dispatched with one responsibility: call the email API once.
  • Your app stores the provider status and message ID from the API response.
  • A webhook endpoint updates final outcomes like delivered, bounced, or failed when events arrive.

The provided content notes that the Transactional Email page mentions real-time event tracking and webhook support, which fits this workflow well.

Step-by-Step Setup

1) Define your send contract

Create a small internal payload structure for every transactional email. Keep it provider-agnostic so your application remains stable if you change providers later.

Minimum fields from the provided content:

  • to
  • from
  • subject
  • html + text (recommended)
  • correlation_id (your internal UUID for tracing)

2) Move sending into a queue job

Use a queue worker (Redis or database queue) and dispatch a job only after your database state is committed. The request should schedule work, and the worker should perform the send.

This keeps the user-facing request fast and gives you a cleaner retry model.

3) Implement idempotency to prevent duplicate sends

Common duplicate cases include user double-clicks, network timeouts after provider acceptance, and worker retries without dedupe protection.

A simple and practical approach is to store a dedupe key for the message intent and enforce uniqueness before dispatching the job. The provided content suggests examples like user + template + day, or order ID + receipt. The key idea is that retries should map back to the same logical send.

4) Call the email API using MailCub as the source of truth

The provided content states that MailCub Documentation includes the email send endpoint and the authentication header x-sh-key. It also mentions the same endpoint and auth approach on the Transactional Email product page.

When you send, store these details in your application:

  • HTTP status code
  • Response body (redacted where needed)
  • Returned message identifier (if present)

Use MailCub Documentation for endpoint and auth details, and review the Transactional Email page for event tracking context.

5) Retry only when retry makes sense

The provided content highlights common response codes such as 401, 403, 422, and 429. These are useful for deciding what should be retried and what should stop immediately.

Suggested retry behavior from the provided content:

  • Retry: timeouts, network errors, and 429 rate/quota exceeded (with backoff)
  • Do not retry: 401 invalid key, 403 domain not verified, 422 account paused, 102 suspended (these need a fix first)

The content also notes an API rate guideline of 15 requests per second, so queue concurrency should be set carefully to avoid bursts.

You can use MailCub Pricing when planning rollout and usage expectations, and MailCub Documentation for response code behavior and operational guidance.

6) Add webhook event handling for final outcomes

The provided content notes that MailCub’s Transactional Email page includes real-time event tracking and webhook support. A clean implementation approach is:

  • Create a POST webhook endpoint (for example, an email events route in Laravel)
  • Verify authenticity if the provider supports signatures
  • Parse the event type and message or correlation ID
  • Update your EmailSend record to the final state (delivered, bounced, failed)

This keeps your app state accurate without depending only on send-time responses.

7) Use provider logs and analytics to debug “not received”

The provided content states that MailCub Documentation includes analytics (delivery rate, success rate, bounces) and detailed Email Logs with per-message status and error info.

A practical support workflow is:

  • Support collects recipient email and timestamp
  • Your team searches by correlation ID in your database
  • You cross-check the provider’s Email Logs for recipient, status, and errors

This is much better than guessing whether the issue is spam, bounce, or a configuration problem.

Production Checklist

Area What to implement Where in Laravel Why it matters
Queueing Job-based sending, worker supervision Jobs/SendTransactionalEmail.php + Horizon/Supervisor Keeps requests fast, avoids timeouts
Dedupe Unique dedupe_key per message intent DB unique index Prevents duplicate sends on retries
Retry policy Retry only transient failures, backoff Job tries/backoff/exception handling Avoids retry storms and throttling
Status tracking Pending → queued → sent → final email_sends table + events Support can answer “what happened?”
Webhooks Event endpoint + DB updates routes/api.php controller Bounces/failures update your app
Logs/Analytics Provider logs + internal correlation Dashboard + your admin panel Faster incident response
Domain auth SPF/DKIM (+ DMARC when ready) DNS + onboarding setup Improves deliverability consistency

Common Mistakes

  • Sending email inside controllers, which causes slow pages and timeout risk
  • Retrying every error, including 401/403/422 that should stop and alert
  • Not storing correlation IDs or recipient timestamps
  • Ignoring rate limits and pushing too many jobs at once
  • Not having a support workflow for logs and analytics, which turns debugging into guesswork

Troubleshooting Playbook

If you get 401 / 403 / 422

  • 401: API key missing or invalid — fix secrets/configuration
  • 403: domain not verified — complete domain verification (DNS)
  • 422: account paused — resolve account/billing/policy issue first

If you get 429 (rate/quota exceeded)

  • Reduce worker concurrency
  • Add backoff (for example, increasing delays across retries)
  • Smooth bursts with a queue buffer

The provided content notes MailCub’s rate/quota behavior and an API rate guideline, so this is an operational setting your team should review early.

If “sent” but the user did not receive the email

  • Check provider Email Logs status and error details
  • Confirm SPF/DKIM alignment
  • Check bounce/failed events if webhooks are enabled

The provided content specifically notes that MailCub Documentation includes Email Logs and what each log entry contains, which makes this troubleshooting path much faster.

FAQ

What is the safest way to send transactional email in Laravel?

Queue it. Send in a job, store correlation IDs, and keep retries controlled.

Should I retry failed transactional emails automatically?

Only for transient failures like timeouts and 429 responses. Do not retry configuration or account errors such as 401, 403, or 422.

How do webhooks help transactional email reliability?

They allow your app to capture final outcomes like bounce or failure and update application state automatically without manual checks.

Where do I debug delivery issues fastest?

Start with provider Email Logs and your correlation ID. The provided content notes that MailCub includes per-message logs and error fields for faster debugging.

Do queues improve deliverability?

Not directly. Deliverability mostly depends on domain authentication (SPF, DKIM, DMARC), content quality, and sending behavior. Queues improve reliability and operational control.

What should I store for each email to make support easier?

Store recipient, template/type, timestamp, correlation ID, provider status, and any provider message ID.

Conclusion

A production Laravel transactional email setup is mainly about engineering discipline: queue everything, retry carefully, store the right metadata, and use logs and events to debug quickly.

The provided content notes that MailCub gives the send endpoint, auth header, response codes, and access to analytics/logs. Use MailCub Documentation as your operational baseline, use the Transactional Email page for product capabilities like logs and webhooks, and check MailCub Pricing when planning usage and production rollout.

Tags:
laravel transactional emaillaravel queue emailemail retry policy laravelemail webhooks laraveltransactional email eventsemail delivery logsMailCub APIx-sh-key headerbounce handling

You Might Also Like