SPF Record for Google Workspace, SendGrid and Other Providers: How to Combine Them Safely
How to write one SPF record for several email providers: syntax, include examples, the 10-lookup limit and a safe rollout from ~all to -all.

A domain must have exactly one SPF record. To use Google Workspace and SendGrid together, merge their includes into a single line: v=spf1 include:_spf.google.com include:sendgrid.net ~all. That line costs 3 DNS lookups measured on 2026-10-13 (Google 1 + SendGrid 2), well under the limit of 10. Publish it as one TXT record, verify with a checker and move from ~all to -all once every sender is accounted for.
Most businesses send email from more than one place: a mailbox provider for staff, a newsletter service for campaigns, a CRM, a support desk. Each one needs permission in your domain's SPF record. The mistake that breaks everything is adding a second SPF record instead of merging them, and the second most common one is losing count of DNS lookups. This guide shows the right way, with the real lookup cost of the popular providers measured from live DNS.
SPF in one minute
SPF (Sender Policy Framework, RFC 7208) is a DNS TXT record that lists which servers may send mail for your domain. Receivers check the connecting IP against it. A simple record looks like this:
v=spf1 ip4:203.0.113.10 include:_spf.google.com ~all
| Term | Meaning | Counts toward the 10 lookups? |
|---|---|---|
v=spf1 | Version tag, must come first | No |
ip4: / ip6: | Authorise an IP or CIDR range | No |
a, mx | Authorise the domain's A or MX hosts | Yes |
include:domain | Also accept whatever that domain's SPF accepts | Yes (plus everything nested inside) |
exists:, ptr | Advanced / discouraged mechanisms | Yes |
redirect= | Use another domain's record instead | Yes |
~all | Soft fail for everything else | No |
-all | Hard fail for everything else | No |
The qualifier in front of a term sets the result: + pass (default), - fail, ~ softfail, ? neutral. Terms are evaluated left to right, and anything after all is ignored.
The one-record rule
A domain may publish only one record that starts with v=spf1. RFC 7208 states that if the DNS returns more than one, the result is permerror and SPF fails for every message. This usually happens when a second provider's setup guide says "add this TXT record" and you add it alongside the existing one.
# WRONG: two SPF records
example.com. TXT "v=spf1 include:_spf.google.com ~all"
example.com. TXT "v=spf1 include:sendgrid.net ~all"
# RIGHT: one merged record
example.com. TXT "v=spf1 include:_spf.google.com include:sendgrid.net ~all"
Common include values and what they really cost
Include values are the ones the providers document today; always confirm against the provider's own help page because they can change. The lookup cost column is what we measured by resolving each record and everything nested inside it on 2026-10-13 with public DNS. These numbers move when a provider re-organises its record, so re-measure before relying on them.
| Provider | Include | Lookups it adds | What is inside |
|---|---|---|---|
| Google Workspace | include:_spf.google.com | 1 | IP ranges only (flattened) |
| Microsoft 365 | include:spf.protection.outlook.com | 1 | IP ranges only |
| SendGrid | include:sendgrid.net | 2 | IP ranges + include:ab.sendgrid.net |
| Mailchimp / Mandrill | include:servers.mcsv.net | 1 | IP ranges only |
| Amazon SES | include:amazonses.com | 1 | IP ranges only |
| Mailgun | include:mailgun.org | 5 | Two nested includes, one of which has two more |
| Postmark | include:spf.mtasv.net | 1 | IP ranges only |
| Brevo | include:spf.brevo.com | 1 | IP ranges only |
Two things stand out. First, older advice that "Google costs four lookups" is out of date: its record is now a flat list of IP ranges. Second, one provider (Mailgun in this snapshot) can consume half your budget on its own, so the cost per include is worth checking before you add it.
SPF Record GeneratorAn SPF record in the right order with a minimum lookup count (limit 10) and long-text splittingOpen the tool →Worked example: counting lookups for a typical stack
A company uses Microsoft 365 for staff mail, Mailchimp for newsletters, SendGrid for the app's transactional mail and Amazon SES for backups. The merged record is:
v=spf1 include:spf.protection.outlook.com include:servers.mcsv.net include:sendgrid.net include:amazonses.com ~all
| Term | Lookups |
|---|---|
include:spf.protection.outlook.com | 1 |
include:servers.mcsv.net | 1 |
include:sendgrid.net (+ ab.sendgrid.net) | 2 |
include:amazonses.com | 1 |
| Total | 5 of 10 |
Five lookups leaves room for a CRM and a helpdesk. If the same company swapped SendGrid for Mailgun, the total would jump to 8, which is why you should count before you add the next service. Real-world records can be near the limit: the public record of a large code-hosting company, resolved the same day, uses exactly 10.
Mind the 10-lookup limit
RFC 7208 §4.6.4 says implementations MUST limit the total number of DNS-querying terms to 10 and that exceeding it produces permerror. It also limits mx evaluation to 10 address records per MX name, and says implementations SHOULD limit void lookups (queries that return nothing) to two. To stay under the limit:
- Count with a tool instead of by eye; a checker walks the whole tree.
- Remove providers you no longer use. Old includes are the most common cause of overflow.
- Use dedicated subdomains: send campaigns from
news.example.comand give that subdomain its own SPF record and its own 10-lookup budget. - Prefer ip4/ip6 for static infrastructure you control, since they cost no lookups.
- Be careful with flattening. Copying a provider's IP ranges into your own record removes lookups but silently goes stale when the provider changes ranges; automate it or avoid it.
Read the detail in the SPF lookup limit guide.
A subdomain strategy that keeps every budget small
If one flat record starts to feel crowded, split by purpose and give each stream its own subdomain and its own record, for example example.com for staff mail, news.example.com for newsletters and app.example.com for transactional mail from your product. Each subdomain gets its own 10-lookup budget, a cleaner reputation (a problem on the newsletter stream no longer drags down staff mail) and an easier audit trail in DMARC reports. The cost is that the visible From address must use the matching subdomain for DMARC alignment, and each subdomain needs its own DKIM and DMARC setup.
Step-by-step: build and publish the merged record
- Inventory every sender using your domain: staff mailboxes, marketing tools, CRM, billing, support, website forms, servers.
- Build the record with the generator; it orders IPs first, then
a/mx, then includes, and ends in a singleallrule. - Replace the existing SPF TXT record in your DNS; do not add a second one.
- Wait for DNS propagation (often minutes, up to your record's TTL) and run the checker again.
- Send test messages from each platform and check
Authentication-Resultsforspf=pass(see how to read email headers).
A quick command-line check of what the world sees:
dig +short TXT example.com | grep -i "v=spf1"
# exactly one line expected; two lines = permerror
From ~all to -all: roll out safely
~all (soft fail) tells receivers that mail from unlisted sources is suspicious but may still be delivered. -all (hard fail) asks them to reject it. Start with ~all while you discover forgotten senders. Combine this with DMARC aggregate reports to see every source that sends as your domain, and only then switch to -all. Never publish +all; it authorises the entire internet. Remember that for the Gmail and Yahoo bulk-sender rules, SPF is only half of the story: DKIM and DMARC alignment matter too (see the requirements checklist).
Troubleshooting checklist
| Symptom | Likely cause | Fix |
|---|---|---|
permerror | Two SPF records, or over 10 lookups, or a syntax error | Merge to one record, reduce lookups, validate syntax |
softfail from a legitimate sender | Provider not included | Add the provider's include |
| SPF passes but DMARC fails | Provider uses its own envelope domain (no alignment) | Configure a custom return-path or rely on aligned DKIM |
none | No record on the envelope domain | Publish a record on the exact domain used in MAIL FROM |
| Works for some receivers, fails for others | Record too long for one DNS response, or lookups near the limit | Shorten, split sources across subdomains |
Frequently asked questions
Can I have two SPF records on one domain?
No. Two v=spf1 records on the same name cause a permerror. Merge all authorised senders into a single record.
How do I add SendGrid to an existing Google Workspace SPF record?
Edit the current record and add include:sendgrid.net before the final all term, giving v=spf1 include:_spf.google.com include:sendgrid.net ~all.
How many includes can an SPF record have?
The limit is 10 DNS-querying terms in total, including nested ones, not a fixed number of includes. Some providers cost several lookups each.
Should I use ~all or -all?
Start with ~all while auditing your senders and move to -all when you are sure every legitimate source is listed. Pair it with DMARC monitoring.
Do subdomains inherit the SPF record?
No. SPF is evaluated for the exact domain in the envelope sender, so each sending subdomain needs its own record.


