15 May 2026 · 11 min read
SPF was designed in an era when a domain sent its mail from one or two servers it controlled directly. You listed those servers in a DNS record, receiving mail servers checked the sending IP against that list, and the whole thing fit comfortably inside a single short line of text. That world is long gone. A modern business sends through a mail platform, a marketing tool, a help-desk system, an invoicing service, a CRM and a handful of one-off transactional providers, and each of those wants you to add its own fragment to your SPF record. The record grows, and at some point it quietly breaks against a limit that almost nobody knew was there until they hit it.
SPF flattening is the technique people reach for when that happens. It can be genuinely useful, and it can also create a slow-motion deliverability failure that nobody notices for weeks. This guide explains exactly what flattening is, the specific limit it solves, the real trade-offs you are accepting when you do it, why doing it by hand is more dangerous than it looks, and how a hosted approach keeps you under the limit without the manual upkeep. If you only want to know whether your current record is in danger, the SPF checker counts your DNS lookups and flags the problem in a few seconds. The rest of this article is the why and the how behind that number.
The limit that makes flattening a topic at all
The relevant rule lives in the SPF specification, RFC 7208, and it is precise: when a receiving mail server evaluates your SPF record, it is allowed to perform at most ten DNS lookups in total. Every mechanism that requires the receiver to go and resolve something counts against that budget. Specifically, the include, a, mx, ptr and exists mechanisms each cost lookups, and the redirect modifier does too. Plain ip4 and ip6 mechanisms cost nothing, because the address is already written out in the record and there is nothing to resolve.
The catch is that the counting is recursive. When your record contains include:_spf.google.com, that is one lookup, but Google's record then contains its own include statements, and each of those costs another lookup against your budget, and so on down the tree. A single innocent-looking include can pull in three, four or five further lookups that you never see in your own record. This is why the limit is so easy to breach without realising. You add what looks like one entry and you have actually spent four.
When a receiver exceeds ten lookups while evaluating your record, the result is not a soft warning. SPF returns a permerror, a permanent error, and the message is treated as though SPF simply failed. For DMARC purposes that means SPF no longer contributes a pass, and if you were leaning on SPF for alignment, your authentication can collapse. Mail that was sailing through yesterday starts landing in spam or being rejected today, and the only thing that changed is that you added one more sending service and tipped over the edge.
There is a second, less famous limit worth knowing: a void lookup limit. RFC 7208 also says that if more than two of your lookups return an empty result or a non-existent domain, that too is a permerror. Records that accumulate dead include statements for services you stopped using can trip this even while staying under ten live lookups. Both limits push in the same direction: keep the lookup tree small and clean.
To see your own number, paste your domain into the SPF checker. It walks the entire include tree the way a receiver would and tells you the total. Anything at eight or above deserves attention, because you are one new service away from a problem.
What flattening actually does
Flattening is the act of replacing lookup-based mechanisms with the raw IP addresses they ultimately resolve to. Instead of telling receivers "go and ask Google which addresses are allowed", you do that resolution yourself, once, and write the resulting ip4 and ip6 ranges directly into your record.
A typical unflattened record might look like this:
v=spf1 include:_spf.google.com include:servers.mcsv.net include:sendgrid.net include:_spf.intercom.io -all
That is four include mechanisms in your own text, but each expands into a sub-tree of further lookups. In practice a record like this can consume anywhere from eight to fourteen lookups once fully resolved, which means it may already be over the limit.
A flattened version of the same record replaces those include statements with the actual address blocks behind them:
v=spf1 ip4:209.85.128.0/17 ip4:64.233.160.0/19 ip4:66.249.80.0/20 ip4:198.2.128.0/18 ip4:167.89.0.0/17 ip4:185.250.236.0/22 -all
Now there are zero DNS lookups during evaluation. Every allowed address is spelled out, so a receiver reads the line and is done. The lookup budget is irrelevant because you are not asking the receiver to resolve anything. That is the entire appeal of flattening: it converts a recursive, lookup-heavy record into a flat, self-contained list of IP ranges, and the ten-lookup limit stops being your problem.
If you want to understand the mechanisms you are replacing before you replace them, the SPF product page explains each one, and the SPF generator builds valid syntax from your list of sending services so you can see a correct record next to your current one.
The trade-off you are accepting
Flattening solves the lookup limit by trading away the one thing that made include valuable in the first place: the ability for your providers to change their infrastructure without telling you.
When your record says include:sendgrid.net, you are delegating. You are saying "whatever addresses SendGrid publishes today are the addresses I authorise". If SendGrid adds a new sending region next month, retires an old data centre, or shifts customers onto a different IP range, their published record updates and your SPF follows along automatically. You did nothing and your mail kept passing.
The moment you flatten that include into a fixed list of ip4 ranges, that automatic updating stops. Your record now reflects SendGrid's addresses as they were on the day you flattened, frozen in amber. If SendGrid moves your traffic to a new IP that is not in your frozen list, SPF will fail for those messages, because as far as your record is concerned that address was never authorised. The failure is silent. Nothing in your DNS looks broken. The record is valid, it resolves, it is under the limit. It is simply out of date, and out-of-date SPF is indistinguishable from a misconfiguration as far as your deliverability is concerned.
This is the heart of the trade-off. Unflattened records are larger in lookup cost but self-maintaining. Flattened records are cheap to evaluate but require you to keep them in sync with providers who change their infrastructure on their own schedule and have no obligation to warn you. You have not removed the work. You have moved it from the receiver's evaluation budget onto your own maintenance calendar.
Cloud-scale senders are the worst case here. Google, Microsoft 365 and the large email service providers publish huge, frequently changing pools of addresses precisely because they operate at a scale where IP churn is constant. Flattening a small fixed-IP provider that has used the same three addresses for five years is low risk. Flattening Google Workspace or Microsoft 365 is high risk, because those ranges genuinely move, and a frozen snapshot of them goes stale faster than you would expect.
Why hand-flattening goes wrong
People underestimate flattening because the first time you do it, it works. You resolve the includes, paste the IPs in, your lookup count drops to zero, your mail flows. The problem is everything that happens after that first afternoon.
The record drifts out of date and nothing tells you. This is the dominant failure mode. There is no alert when a provider changes their IPs. There is no error in your DNS. The first sign of trouble is usually a customer or colleague mentioning that your emails stopped arriving, by which point messages have been failing for days. Because the change happened on the provider's side and your record looks healthy, the cause is genuinely hard to diagnose unless you already suspect flattening. If you are monitoring authentication results, change alerts are the only practical way to catch this early, which is part of why ongoing monitoring matters more for flattened records than unflattened ones.
You hit the length limit instead of the lookup limit. Flattening trades the ten-lookup limit for a different ceiling. A single DNS TXT string is capped at 255 characters, and the total SPF record across concatenated strings should stay within 512 bytes to remain safe across resolvers. A fully flattened record for a domain with several cloud senders can easily contain dozens of IP ranges and blow straight past these limits. You then have to split the record across multiple strings, which is fiddly and easy to get wrong, and if you split it badly some receivers will fail to parse it at all. The DNS record splitter exists precisely because hand-splitting long records is error-prone. You have not escaped a limit, you have swapped a well-known one for a less obvious one.
You flatten too aggressively and lock out legitimate mail. In the rush to get under the limit, it is tempting to flatten everything, including providers whose ranges change often. Each aggressively flattened cloud sender becomes a future outage waiting for the provider's next infrastructure change. The mechanisms most worth keeping as live include statements are exactly the ones people most want to flatten, because they are the ones contributing the most lookups.
You forget the record exists. A flattened record needs revisiting on a schedule forever. Six months later the person who flattened it has moved on, the new owner sees a long list of IP4 ranges with no comments explaining where they came from, and nobody dares touch it. The record quietly decays. Documentation in DNS is non-existent, so a hand-flattened record carries no memory of which IPs belonged to which provider or when they were last verified.
None of these failures are exotic. They are the normal, expected outcome of treating a one-time flatten as a permanent fix. Flattening is not a fix, it is a commitment to ongoing maintenance, and the maintenance is what people skip.
When you actually need to flatten
Flattening is a tool, not a default. Reach for it only when the simpler options are exhausted.
Before flattening anything, try these in order:
- Remove dead includes. Audit every
includeagainst the services you genuinely send mail from today. Old marketing tools, retired help-desks and trial services you abandoned often leave includes behind, each costing lookups for no benefit. Deleting them is free and risk-free, and it frequently brings a record back under the limit on its own. - Drop redundant
aandmxmechanisms. Many records carryaandmxout of habit even though no mail originates from the domain's own A record or mail exchangers. If your sending is entirely through third-party providers, these mechanisms cost lookups while authorising addresses that never send. - Consolidate providers. If two tools send through the same underlying email platform, you may be able to authorise the platform once rather than each tool separately.
- Use a subdomain for bulk senders. Move a high-churn marketing or transactional sender onto a dedicated subdomain with its own SPF record. The subdomain carries its own ten-lookup budget, so the includes that were crowding your main domain no longer compete with your core business mail. This is often the cleanest fix of all, and it keeps the volatile sender isolated from the addresses you actually care about.
If you have done all of that and you are still over ten lookups, then flattening is justified, but flatten selectively. Flatten the stable, fixed-IP providers whose ranges rarely move, and keep the volatile cloud senders as live include statements wherever the budget allows. The goal is the smallest amount of flattening that gets you safely under the limit, not the maximum.
How hosted flattening removes the maintenance problem
Every risk above comes from the same root cause: a hand-flattened record is a static snapshot of something that moves. Hosted flattening attacks that root cause directly by making the record dynamic instead of static.
The idea is straightforward. Instead of resolving your providers' IPs once and pasting them into DNS, you delegate the SPF record to a service that resolves them continuously. Your DNS holds a pointer to a record that is kept current automatically. Behind that pointer, the service re-resolves every provider's published addresses on a schedule, rebuilds the flattened list whenever a provider's IPs change, and serves the up-to-date result. From the receiver's point of view the record is flat and lookup-free. From your point of view it never goes stale, because something is doing the re-resolution that a human would otherwise have to remember to do.
This is exactly how DMARC Engine handles flattening as part of the hosted SPF service. The lookup count stays under the limit because the served record is flattened, and the staleness problem disappears because the flattening is recomputed automatically as your providers change. When a provider shifts its IP ranges, the hosted record follows, the same way a live include would have, but without reintroducing the lookups that caused the problem in the first place. You get the evaluation cost of a flattened record with the self-maintaining behaviour of an unflattened one.
The other half of the solution is visibility. Because the record is managed and monitored, a change in your authentication posture triggers an alert rather than a silent failure that you discover from an annoyed customer. Pairing managed flattening with monitoring means the two failure modes that hurt most, drift and silence, are both covered. Drift is handled by automatic re-resolution; silence is handled by change alerts that tell you when something moved.
The practical takeaway
SPF flattening exists to solve one specific, real problem: the ten-lookup limit that a modern stack of sending services blows through with ease. As a technique it works, and there are legitimate situations where you need it. But flattening by hand trades a visible, well-understood limit for an invisible maintenance burden, and the failure mode it introduces, a record that quietly goes out of date while looking perfectly healthy, is one of the harder email problems to diagnose after the fact.
So the order of operations is: measure first, prune second, flatten last, and if you must flatten, flatten only the stable providers and never the volatile ones. Better still, let something keep the flattening current for you so the maintenance never lands on a calendar that everyone eventually forgets.
Start by finding out where you actually stand. Run your domain through the SPF checker to see your real lookup count and the full include tree behind it. If you are close to the limit or already over it, and you would rather not own a flattened record for the rest of its life, the done-for-you hosted SPF service keeps you under the limit automatically and tells you when anything changes, which is the whole point of not having to think about this again.