SPF Flattening, Explained Properly
What it actually means to flatten an SPF record, why it reduces lookup count so effectively, and the ongoing maintenance cost that makes it the wrong default for everyone.
What Flattening Actually Does
SPF flattening takes every lookup-triggering mechanism in a record — every include, a, and mx — and resolves it down to the literal IP addresses and ranges it currently points to, then publishes those directly as ip4 and ip6 entries in place of the original mechanism. A record like v=spf1 include:sendgrid.net ~all might flatten into something like v=spf1 ip4:167.89.0.0/17 ip4:198.37.144.0/20 ip4:198.21.0.0/21 ~all, listing out the actual ranges SendGrid's include currently resolves to, rather than pointing at their SPF hostname and letting the receiving server resolve it fresh on every check.
The immediate effect is a dramatic lookup-count reduction, because ip4 and ip6 mechanisms are evaluated as literal address comparisons with zero DNS queries involved. A record that was consuming 8 or 9 of its 10 available lookups through a handful of heavy vendor includes can often drop to 1 or 2 lookups after flattening those same vendors, freeing up substantial headroom.
The Trade-Off, Honestly Stated
| Aspect | Live Include | Flattened Static IPs |
|---|---|---|
| Lookup cost | 1+ per include, adds up quickly | Effectively zero |
| Stays accurate automatically | Yes, always reflects vendor's current IPs | No, only accurate as of the last time you re-flattened |
| Maintenance required | None, by design | Ongoing, periodic re-resolution needed |
| Failure mode when neglected | Record eventually exceeds lookup limit → permerror | Record silently misses legitimate sender IPs → failed authentication |
| Record length | Short and simple | Can grow long, sometimes needs multi-string TXT handling |
Neither failure mode is better than the other in the abstract — a permerror is at least loud and eventually noticeable, while a stale flattened record fails quietly, one legitimate message at a time, sometimes for months before anyone notices a pattern.
When Flattening Genuinely Makes Sense
How to Flatten a Record Correctly
Resolve the target include's TXT record directly, note every ip4 and ip6 entry it contains (recursively, if that record itself nests further includes), and transcribe those exact ranges into your own record in place of the include mechanism. Verify the resulting record still parses correctly and still resolves under the 10-lookup ceiling — a flattening job done partially, leaving some nested includes unflattened, can still leave you over the limit while adding the false confidence of "I already flattened this."
Document what you flattened, when, and from which source record, so a future audit (by you or whoever inherits the domain) has a starting point for re-verification rather than having to reverse-engineer which static entries came from which vendor.
Automated Flattening Services
Several third-party services exist specifically to solve the staleness problem: they host a continuously re-resolved, auto-published version of your flattened record, checking the underlying vendor domains on a schedule and updating DNS automatically when ranges change. This removes the manual re-check burden but introduces a new dependency — your SPF record's accuracy now relies on that third-party service staying operational and correctly configured, which is its own trade-off worth weighing against simply trimming unused vendors first.
A Worked Before-and-After
Suppose an organization's record reads v=spf1 include:_spf.google.com include:mail.zendesk.com include:spf.mandrillapp.com ~all and recursive evaluation shows it currently resolving to 11 lookups — already over the ceiling, with Google's nested includes contributing the bulk of it. The team decides Zendesk and Mandrill are both low-volume, relatively stable senders worth keeping on live include, but Google's chain is the one consistently pushing the total over. Resolving Google's chain down to its underlying ranges at the time of flattening might produce something like ip4:64.233.160.0/19 ip4:66.102.0.0/20 ip4:66.249.80.0/20 ip4:72.14.192.0/18 ip4:74.125.0.0/16 ip4:108.177.8.0/21 ip4:173.194.0.0/16 ip6:2404:6800:4000::/36 ip6:2607:f8b0:4000::/36 ip6:2800:3f0:4000::/36 ip6:2a00:1450:4000::/36 ip6:2c0f:fb50:4000::/36. The resulting record — those flattened ranges plus the two remaining live includes — now resolves to roughly 2 lookups instead of 11, comfortably under the ceiling with meaningful headroom.
The trade this specific team has now taken on, explicitly and knowingly, is that if Google ever changes which ranges back Workspace mail sending — something entirely plausible over a multi-year horizon — this flattened block goes stale until someone notices and re-resolves it. That's a real, ongoing obligation, not a one-time cost, and it's worth writing down exactly who owns re-checking it and how often.
Reading Vendor Documentation for Flattening Risk Signals
Before flattening any vendor's include, it's worth actually reading what that vendor says about their own SPF infrastructure, because many are explicit about exactly the risk flattening introduces. A vendor's own setup documentation that says something like "always reference our include record rather than hardcoding our IP ranges, as they change periodically without notice" is, in effect, telling you directly that flattening them is a bad idea. Conversely, a vendor whose sending infrastructure has been stable for years, with no history of range changes in their support documentation or community forums, is a meaningfully safer flattening candidate. This isn't something a lookup-counting tool can tell you on its own — it requires actually knowing something about the specific vendor's operational history.
Multi-String TXT Records and the 255-Character Limit
A single string within a DNS TXT record is capped at 255 characters by the underlying DNS protocol, not by SPF itself. A heavily flattened record, especially one combining several vendors' worth of IPv4 and IPv6 ranges, can easily exceed that in raw text length. DNS handles this by allowing a single TXT record to be composed of multiple quoted strings, which resolvers concatenate back together when reading the record — but this depends on your DNS provider's panel correctly supporting and displaying multi-string TXT entries, and on you entering the record in the format your specific provider expects for a multi-string value rather than accidentally truncating it at 255 characters or splitting it into two entirely separate TXT records (which, per the earlier discussion of multiple SPF records, is an entirely different and worse problem). Always verify a flattened record renders and resolves correctly after publishing, specifically checking that its full length wasn't silently cut off by the DNS panel.
Partial Flattening: A More Sustainable Middle Ground
A distinction worth drawing out explicitly is between fully flattening a record — converting every include into static ranges — and partially flattening it, which means selectively converting only the specific includes that are actually necessary to get under the lookup ceiling while leaving everything else on live include. Full flattening maximizes lookup savings but also maximizes the surface area exposed to staleness risk, since every single vendor relationship in the record now depends on someone remembering to re-check it. Partial flattening accepts a smaller lookup-count improvement in exchange for keeping most of the record on auto-updating includes, concentrating the maintenance burden onto just the one or two vendors where it was actually unavoidable. For nearly every real-world case covered in this series, partial flattening of just the heaviest offending include is enough to solve the immediate lookup-count problem without taking on more ongoing risk than necessary.
Building a Re-Verification Habit Around a Flattened Entry
Because a flattened entry has no built-in mechanism to signal it's gone stale, the responsibility for catching drift falls entirely on whatever process you set up around it. A reasonable minimum is: note the exact date you flattened a given vendor, set a recurring reminder at an interval matched to that vendor's known rate of change (monthly for anything flagged as changing occasionally, closer to every one to two weeks for anything explicitly documented as volatile), and on each check, re-resolve the vendor's live include record fresh and diff it against what's currently published in your flattened entry. A mismatch found this way, caught proactively, is a quiet DNS update. The same mismatch found reactively, after legitimate mail has already started failing SPF because the vendor moved to new ranges weeks ago, is a deliverability incident with a much less pleasant root-cause investigation attached to it.
Flattening and Third-Party Automation Tools, Weighed Honestly
Automated flattening services solve the staleness problem directly by re-resolving on a schedule and republishing automatically, which removes the manual re-check burden entirely. The trade being made in exchange is a new dependency: your SPF record's ongoing accuracy now relies on a third party's service staying operational, correctly configured, and itself accurately tracking whichever vendors you've delegated to it. For an organization already juggling many vendor relationships and limited internal capacity to manually re-check flattened entries, that trade is often a reasonable one. For an organization that's only flattened one or two low-volatility vendors as a targeted fix, manual periodic re-checking is frequently simpler and avoids adding yet another vendor dependency into the mix purely to manage a problem two static IP blocks are creating.
What Flattening Cannot Fix
It's worth being explicit about the limits of flattening as a technique, since it's easy to reach for it as a universal answer to lookup-count problems once you understand how effective it is. Flattening does nothing for the void-lookup sub-limit if the void lookups are coming from something other than the mechanism being flattened. It does nothing to address a genuine syntax error elsewhere in the record. And it does nothing to address the underlying question of whether every vendor still listed is actually still in active use — flattening a vendor you no longer send through just means you're now maintaining a static, unused block of IP ranges instead of an unused include, which is arguably worse, since a stale flattened block doesn't even carry the small silver lining of automatically updating if you ever did resume using that vendor. Flattening is a tool for a specific problem: a stable, actively-used vendor whose live include is consuming too much lookup budget. It's not a general-purpose record-shrinking technique to apply indiscriminately.
Estimating How Often a Given Vendor's Ranges Actually Change
Since the entire risk calculus around flattening hinges on how frequently a vendor's underlying IP ranges change, it's worth having an actual method for estimating this rather than guessing. One practical approach: resolve the vendor's live include record today, save the resulting list of ranges with a timestamp, and check back against it periodically over the following months, noting whether and how often the ranges actually differ from your saved snapshot. A vendor whose ranges are identical after six months of checks is a meaningfully safer flattening candidate than one already observed to have changed twice in that same window. This kind of direct observation, even informally kept, tends to be more reliable than relying purely on a vendor's own marketing language about infrastructure stability, which isn't always written with SPF flattening decisions in mind.
Communicating a Flattening Decision to Whoever Inherits the Domain
A flattened SPF record, viewed cold by someone who didn't make the original decision, looks exactly like a normal, static, deliberately-configured record — there's nothing in the DNS record itself that flags "this block of IPs was derived from a vendor's include on this date and needs periodic re-verification." Without documentation living somewhere the next administrator will actually find it, that context is lost the moment the person who did the flattening moves to a different role or leaves the organization, and the record silently transitions from "actively monitored flattened entry" to "static block nobody remembers the provenance of," which is exactly the condition under which staleness goes undetected for the longest.
Flattening and IPv6: An Easy Blind Spot
A specific, easy-to-miss mistake worth flagging directly: when manually flattening a vendor's include, it's common to carefully transcribe the ip4 ranges and overlook that the same vendor's record often also publishes ip6 ranges alongside them. Omitting the IPv6 ranges doesn't cause an error, but it does mean any mail actually sent from that vendor's IPv6 infrastructure, if they have any, will no longer be authorized under your flattened record even though it was authorized under the original live include. As IPv6 sending infrastructure becomes more common among major vendors, this omission has grown from a minor edge case into a genuine, if quiet, source of authorization gaps in manually flattened records.
Flattening as a Temporary Bridge, Not Always a Permanent State
It's worth framing flattening, in many cases, as a deliberate temporary measure rather than a permanent end state. A record flattened today specifically to solve an immediate lookup-count crisis can, given time, be revisited once the underlying cause (too many active vendors, an unusually heavy specific include) has been addressed through consolidation or vendor changes — at which point the flattened entry might be safely converted back to a live include, or removed entirely if that vendor relationship has since ended. Treating flattening as inherently permanent, rather than periodically reassessing whether it's still the right structural choice given the record's current overall shape, can leave a record carrying maintenance burden longer than actually necessary.
Related Reading in This Series
For the full mechanics of why the lookup limit exists and how to count it, see SPF 10 Lookup Limit. For how a single include actually resolves before you decide whether to flatten it, read SPF Include Mechanism. For the broader trimming and consolidation process beyond just flattening, see SPF Record Optimization. To check your current record and its lookup count before flattening anything, open SPF Lookup.
ToolsNovaHub tools are built and independently maintained with a focus on accurate, no-signup network and security utilities. Spotted an error? Let us know.
📋 Related Tools & Guides Comparison
| Resource | Type | Link |
|---|---|---|
| SPF Lookup | Tool | Open Tool → |
| SPF 10 Lookup Limit | Guide | Read Guide → |
| SPF Include Mechanism | Guide | Read Guide → |
| SPF Record Optimization | Guide | Read Guide → |
| DNS Lookup | Tool | Open Tool → |