What Is the SPF include Mechanism?
TL;DR
An SPF include is a mechanism inside an SPF record that tells a receiving server to also evaluate the SPF record published by another domain, normally a sending provider. It is how one record authorises a provider whose server addresses change without you having to track them.
How is an SPF include evaluated?
The receiver runs a full SPF check again against the included domain, using the same sending address. If that nested check returns pass, the include matches and the message passes. If it returns fail, softfail or neutral, the include simply does not match and evaluation carries on with the next term.
One case is worth knowing. If the nested check hits a permanent error, the whole evaluation returns that error rather than moving on, so a provider with a broken record can fail your SPF even though your own syntax is correct.
Why does each include cost a DNS lookup?
Because it is a real query. The include, a, mx, ptr and exists mechanisms, and the redirect modifier, each cause DNS lookups, and the specification caps the total at 10 for a single evaluation. The all, ip4 and ip6 mechanisms cost nothing.
The cost is not always one. An include pulls in a record that may contain includes of its own, and every one of those counts against the same total of 10, which is why two or three sending platforms is usually enough to get close to the cap.
How do you add a second sending provider?
Inside the record you already have, as another include term. Publishing a second SPF record is a permanent error that can make the check fail for every message, so the existing record is edited rather than joined by a new one.
Order matters only for the final term. v=spf1 include:_spf.google.com include:spf.protection.outlook.com -all works, while anything placed after -all is never reached.
Frequently asked questions
An include evaluates another record and carries on if it does not match, so your own terms still apply. A redirect is consulted only after none of your mechanisms match, and then the result of the target record becomes yours. It is ignored entirely if the record contains an all mechanism.