Form Delivery Reliability for Your Own Site: SMTP Setup, Delivery Rates, Retries, and Logs
1. Why PHP mail() can’t be trusted
Many site owners think the job is done once the form shows a confirmation page after “Submit.” In reality, WordPress’s default wp_mail() goes through PHP’s built-in mail() function, which has no sender authentication, no TLS encryption, and no dedicated IP pool, so the emails it sends are very likely to be flagged as spam by Gmail and Outlook.
This isn’t a plugin problem, it’s a protocol-level problem. mail() hands the email to the local MTA (mail transfer agent), which connects directly to the recipient’s MX server on port 25, but most cloud hosts (Alibaba Cloud, Tencent Cloud, AWS) block outbound port 25 by default to prevent spam. The result: the form shows success, but the email never went out.
A counterintuitive take:The more “hassle-free” the sending method, the more orders you lose. Skipping an SMTP plugin may save you half an hour of setup, but in practice you could lose 20% to 40% of your inquiries every month, and you’d have no idea, because the submission page shows a green checkmark. For how to design form fields to balance conversion and filtering, see Inquiry Form Field Design and Conversion Rate.
| Sending method | Average delivery rate | Setup complexity | Best for |
|---|---|---|---|
| PHP mail() (default) | 40% to 60% | Zero configuration | Not recommended for any production site |
| Host’s local SMTP | 60% to 75% | Low | For test environments |
| Third-party SMTP relay (free tier) | 85% to 92% | Medium | Up to 5,000 emails per month |
| Dedicated transactional email service | 95% or higher | Medium-high | More than 5,000 emails per month |
2. SMTP setup: choosing a plugin and its settings
Setting up SMTP on WordPress doesn’t require touching code, just install a plugin. There are three main choices: WP Mail SMTP (most popular, clean interface), FluentSMTP (open source and free, supports failover across multiple providers), and Post SMTP (strongest logging). Pick one; don’t install two at once, as they’ll conflict.
There are 7 key settings: SMTP host, port (587 or 465, never 25), encryption (TLS or SSL), username, password/API key, sender email, and sender name. The sender email must match your domain, like noreply@yourdomain.com. You can’t send from a Gmail or QQ address, or your SPF record won’t line up and your mail goes straight to spam.
Example: you use SendGrid as your SMTP relay. Set the host to smtp.sendgrid.net, port 587, encryption TLS, username is always apikey, and the password is the API key you generated in your SendGrid dashboard. Set the sender to noreply@yourdomain.com, then add three records in your DNS panel, which we cover in the next section.
| Spec | Correct value | Common mistake |
|---|---|---|
| SMTP host | smtp.sendgrid.net / smtp.mailgun.org | localhost or your local IP |
| Port | 587 (TLS) or 465 (SSL) | 25, which your host blocks |
| Encryption | TLS (587) or SSL (465) | “None”, sending in plain text |
| Username | apikey for SendGrid, postmaster@mg.xxx for Mailgun | Your own email address |
| Sender | noreply@yourdomain.com | A personal Gmail/QQ address |
| From name | Company name + department | Blank, or garbled Chinese characters |
3. Domain authentication: SPF, DKIM, and DMARC records
Configuring the SMTP plugin is only step one. Why should the recipient’s mail server trust that this email came from you? Because of three DNS records: SPF (which servers may send mail for your domain), DKIM (a digital signature that proves the message wasn’t tampered with), and DMARC (what to do when a message fails those checks). Miss any one of them and your deliverability suffers.
SPF is a TXT record that looks roughly like v=spf1 include:sendgrid.net ~all, meaning “only SendGrid’s servers may send mail from my domain; everything else gets a soft fail.” DKIM is a CNAME record: your SMTP provider supplies the public key, and the recipient uses it to verify the signature. DMARC is also a TXT record, starting with v=DMARC1. Set p=none first and watch it for a week, then switch to p=quarantine.
How to check: enter your domain in MXToolbox or the Google Admin Toolbox Checkup tool. All three need to come back green. If SPF shows “not found” or DKIM shows “no key”, add the missing records in your DNS panel, wait 15 minutes for them to take effect, and test again. To see how domain compliance fits with GDPR, see Compliance foundation for global sites.
| Record type | Role | Minimum setup | Verification tool |
|---|---|---|---|
| SPF (TXT) | Declares authorized sending servers | v=spf1 include:provider ~all | MXToolbox SPF Lookup |
| DKIM (CNAME/TXT) | Digital signature that prevents tampering | The selector record from your provider | DKIM Core Key Check |
| DMARC (TXT) | Policy and report collection | v=DMARC1; p=none; rua=email | Google Admin Toolbox |
| MTA-STS (TXT) | Enforces TLS-encrypted delivery | v=STSv1; id=20260921 | MXToolbox MTA-STS |
4. Deliverability metrics and retrying failed sends
Setting up SMTP and DNS is only half the job — you have to watch the metrics. Three numbers matter most: inbox placement rate (the share that lands in the inbox, not spam), hard bounce rate (address or domain doesn’t exist — permanent failure), and soft bounce rate (mailbox full or server busy — temporary failure). Healthy thresholds are placement ≥ 95%, hard bounces ≤ 2%, soft bounces ≤ 5%.
Don’t rely on your plugin’s default retry behavior. WordPress form plugins send once and call it done — if it fails, the page shows no error. The right approach is to add a retry layer: wait 1 minute after the first failure, 5 minutes after the second, 15 minutes after the third, and 60 minutes after the fourth. If all four attempts fail, fire an alert (to your backup email or WeCom) and save the inquiry to your database for manual resend.
Example: a customer in Germany submits the form at 11 p.m. their time (6 a.m. in Beijing), just as SendGrid is doing maintenance and SMTP returns a temporary error. Without retries, that inquiry is lost. With exponential backoff, the fourth attempt succeeds 60 minutes later, and the customer wakes up the next morning to your auto-reply. For how to set your first-response time, see First-response SLA and conversion rate for inquiries.
| Metrics | Healthy range | Alert thresholds | Action |
|---|---|---|---|
| Inbox placement rate | ≥ 95% | Below 90% | Check SPF/DKIM logs |
| Hard bounce rate | ≤ 2% | Above 5% | Clean up invalid email addresses |
| Soft bounce rate | ≤ 5% | Above 10% | Check your SMTP provider’s status |
| Retry success rate | ≥ 80% | Below 50% | Switch to a backup SMTP channel |
| Daily submissions | Baseline ±20% | Drop of 50% or more | Check whether front-end JS is throwing errors |
5. Logging and weekly self-checks
No logs means no way to troubleshoot. The Post SMTP plugin includes an email log table that records the from, to, subject, send time, SMTP response code, and retry count for every email. FluentSMTP has similar features. Keep logs for at least 30 days and auto-purge older ones so they don’t bloat your database.
Do a self-check once a week: pull 5 recent emails and check whether the SMTP response codes are in the 250 range (250 = success, 4xx = temporary failure, 5xx = permanent failure). Then send a test email from Gmail to yourself, click “Show original,” and confirm SPF=pass, DKIM=pass, and DMARC=pass are all green. If any one fails, check your DNS immediately.
Another easy thing to miss: your form plugin needs logging too. If a user submits and a JS error prevents the request from ever being sent, nothing shows up in the SMTP log. So add Nginx access log monitoring at the server level and track the volume of POST requests to /wp-admin/admin-ajax.php (or your REST API endpoint). If it drops by more than 50% on any given day, something is wrong on the front end. For how to set up site monitoring, see Site monitoring and alerts.
| Logging layer | What to record | Retention period | How to view |
|---|---|---|---|
| Form submission log | Field values, IP, UA, timestamp | 90 days | Plugin dashboard / database table |
| SMTP send log | Response codes, retry counts, error messages | 30 days | SMTP plugin log page |
| ESP delivery logs | Opens, clicks, complaints, bounces | Provider dashboard, permanent | SendGrid/Mailgun dashboard |
| Nginx access log | POST request volume, status code breakdown | 14 days | grep access.log on the server |
FAQ
Do I really need an SMTP plugin for WordPress forms, or can I just use PHP mail()?
Do I need all three records, SPF, DKIM and DMARC, or is SPF alone enough?
Which SMTP port should I use, 25, 587 or 465?
How do I check delivery rates, and where can I see whether mail landed in the inbox or the spam folder?
The form submits but no email goes out. What’s the fastest way to troubleshoot?
Is the free SMTP quota enough, and when should I start paying?
Final thoughts
Form delivery is the most overlooked leak on a standalone site. Most site owners watch traffic and conversion rates, but never verify whether the email behind that “submitted successfully” message actually reached the customer. Set up SMTP once and add three DNS records, spend two hours, and you can cut your monthly lost orders by more than half.
Three steps to get it done. First, install an SMTP plugin this week and connect it to a free SendGrid or Mailgun tier. Second, add SPF, DKIM, and DMARC records in your DNS panel and verify they all pass green in MXToolbox. Third, set up 4 retries with exponential backoff and spot-check 5 emails a week for delivery status. Do these three things and your form delivery reliability has a floor.
One line worth remembering: the green checkmark on your form only means “the server received it,” not “the customer saw it” — SMTP, DNS, and the spam folder stand in between.
