SPF macros vs flattening
SPF macros are the lesser-known sibling of flattening — and arguably the
better fix. A single exists macro authorizes unlimited senders in exactly
one DNS lookup, and because it’s evaluated dynamically, it never goes
stale.
What is an SPF macro?
SPF supports macros — placeholders that expand at evaluation time from the incoming message. The useful ones:
%{i}— the sending IP address%{ir}— the sending IP, reversed%{d}— the domain
Combined with the exists mechanism, a record can ask a DNS zone, in real time,
“is this sending IP authorized?”:
v=spf1 exists:%{ir}.spf.example.net -all
For a message from 203.0.113.5, the receiver queries
5.113.0.203.spf.example.net. If an answer exists, SPF passes. One
exists mechanism = one lookup, no matter how many IPs are authorized, and
there is no 255-character record-size problem.
Macros vs static flattening
| Static flattening | Macro (exists) | |
|---|---|---|
| DNS lookups | 0 (raw IPs) | Exactly 1 |
| Size limit | Yes — 255-char strings; big IP sets get unwieldy | None |
| Stays current? | No — static snapshot, breaks on IP change | Yes — evaluated live |
| Compatibility | Universal | Very broad (Google, Microsoft, Yahoo); a few edge receivers weaker |
“Macros are the better flattening”
Classic flattening freezes provider IPs into your record and breaks silently when they change. A macro delivers the same single-lookup result but self-healing: the authorized set is looked up dynamically, so a provider changing IPs is handled automatically by the zone that answers the query. In practice this is delivered as a managed service — you publish one line, and a hosted zone keeps the authorized IPs current for you.
You don’t have to choose
Good managed services offer both a macro (exists) flavor and an include-flattening
fallback for the rare receiver that handles macros poorly. The goal is the same: a single-lookup
record that never drifts out of date. See how to choose a
tool.
Frequently asked questions
What is an SPF macro?
%{{ir}} that expands from the incoming message at evaluation time. With the exists mechanism it lets one lookup authorize unlimited sending IPs dynamically.