Today I’m going to be exploring signal lifespans and how we keep on top of signal expiry dates to ensure that we’re using up to date and high-efficacy signal. We will look at why every B2B signal, from an intent surge to an IP address to a closed-lost reason to the target account list itself, needs a time to live (TTL), and what the programmatic stack worked out before B2B started buying it.
The standing complaint about intent data is that it’s noisy. It is, and it always will be. Intent data is a balancing act between scale and accuracy, and topic-level interest is a broad thing to measure, so the signal arrives with noise built in. That isn’t a defect in the product. It’s the nature of the product, and it’s on the operator to take that noise and turn it into a signal that means something for their business.
Which is why I think “noisy” is the wrong diagnosis, and the wrong diagnosis is why the complaint never goes away.
Teams treat noise as a sourcing problem: buy from a better provider, swap partners, raise the threshold, narrow the topics. Start the year with Bombora, finish the year with Dun & Bradstreet, begin next year with the next shiny new toy. All three are part of the operator’s job, and plenty of teams have done all three and still end up with a rep ringing an account that bought from a competitor in August, and a display campaign chasing the same account into November. The noise was handled. Something else wasn’t.
What I see when I look inside a B2B stack isn’t too many signals. It’s signals that never die. A topic surge from last quarter is still in the score, and it’s still being read as “this company is in market for our offering today”, which it wasn’t even on the day it fired. A job post that was filled in June still counts as a hiring signal. A closed-lost reason that was the easiest button for a rep to hit sits in the CRM as the account’s permanent verdict. The target account list is a photograph of a meeting from January, if you’re lucky, as it’s quite conceivable that, from some of the lists I’ve seen, it could have been a photo taken in January 2008. We’ve seen one that still carried Lehman Brothers, which dates it to 2008 at the latest hence that example. None of it carries a stamp that says when it stops being true, so all of it gets treated as true forever.
The programmatic stack assumed the opposite from day one. Every layer of it was built on the idea that data rots. B2B copied the signals and left the expiry dates behind. Today we will explore how to stop doing that.
New here? I’m Mike Harty. I’ve been building programmatic platforms since 2011, and I now co-run FunnelFuel, a B2B-native programmatic managed service. The B2B Stack is where I write up what that work teaches us, ahead of it reaching a sales deck. Two earlier pieces sit underneath this one: the distinction between an account graph and an identity graph and why B2B programmatic segments aren’t data intelligence.
What you’ll learn in this article:
Why the ad stack treats every signal as perishable, and the exact point where that assumption gets stripped out on the way into a B2B CRM
The three ways a buying signal dies: it ages out, it gets spent, or it gets overruled
The expiry table: a starting TTL for every signal B2B teams buy and build, from intent surges to the target account list, as a graphic you can share
Why combining signals for validation in numbers only works when every input is live
What to change in the stack on Monday without buying anything new
Why programmatic spend is where an expired signal costs the most
Plus Field Notes: three live examples this week of a signal’s expiry date being set by someone other than you, including a ChatGPT Ads change that switches on tomorrow.
The ad stack assumes everything rots
If you’ve ever built or run a bidder, which for my sins I have done 4 times, the thing you internalise early is that nothing in the system is allowed to stay true for long. A cookie has an expiry. A segment in a DMP has a membership window: a user who qualified on a site visit falls out after the lookback closes unless they do something to qualify again. A retargeting pool is weighted by recency, so a visit from this morning outbids a visit from three weeks ago. A frequency cap resets. A suppression list removes anyone who has already converted, so you stop paying to persuade someone who has already been persuaded.
None of that was done because of good manners, the programmatic auction mechanics forced it. A bid request arrives carrying the state of the world as of right now - one of the enormous value points of programmatic - and you have ~120 milliseconds to price it, and pricing it on what was true last month loses money every time. So the whole architecture evolved to make a signal re-earn its place every window or drop out. In engineering terms every signal carries a TTL, a time to live. When the TTL runs out the signal is gone. Not “still there but a bit old”. Gone.
B2B imported the signals and not the TTL.
The intent vendors mostly get this right inside their own platforms. A surge is computed over a research window, typically a week, and an account that stops researching drops off the surge list. The decay exists. In the stacks I’ve seen, it dies at the export. The surge gets pushed into a CRM field, a marketing automation score or a static audience list, and at that moment it stops being a measurement of a window and becomes a flag. Flags don’t decay. A field written in March is still true in October unless a human edits it, and editing it is nobody’s job. I guess all of this is to say that sometimes what we blame as bad signal is actually poor implementation of the signal.
The worst version of the export is the whole CRM. A team needs an audience for an account-based campaign, so the entire account table goes across to the ad platform or the ABM tool: defunct companies, closed-lost from three cycles ago, every record anyone ever imported. After all, more is always better, right. That’s a problem at the input layer, and a problem at the input layer becomes a problem with the relevancy and freshness of every signal attached downstream. No amount of scoring recovers a list that was stale before it arrived. I will argue this point when the cows come home. The missing piece for most account-based programmes is the quality of the list on the way in - lists which often get millions of dollars spent against them, lacking the most basic of hygiene, segmentation, and ICP fit analysis.
First-party signal goes the same way. A site visit from a known account becomes points in a lead score, and the lead score only goes up. A score that only goes up isn’t a score. It’s a counter.
A signal dies in a minimum of three ways
Two threads this week, in r/SalesOperations and r/revops, put it more plainly than most vendor decks: a buying signal should be cancelled the moment it’s acted on, because at that point “the signal is spent”. That’s one of three ways a signal stops being true. Naming all three matters, because each one needs a different mechanism, and most stacks have none of them.
It ages out. The signal measured attention over a window and the window closed. An intent surge, a page view, a webinar seat, a job post: each is evidence of something happening at a moment, and the moment passes. The job post is the one people get most wrong. The same threads call open roles a weak signal on their own, and I’d go further. A job post tells you a budget line was opened, not that anyone is buying tooling. It also has a visible end date, the day it’s filled or withdrawn, and most stacks ignore it. In general, this class of signal needs rapid pipelining to take advantage of, and that pipelining includes a minimum of daily refreshing: taking out stale signal and adding in fresh new signal. Anything less than that is leading you down the wrong path - the path that leads to wasted budget.
It gets spent. Sales acted on it. The rep called, the meeting happened or didn’t, the account said yes, no or not now. Whatever the answer, the signal has done its job and should stop scoring the account, and it should certainly stop feeding a media campaign that chases the account the week after the meeting. Programmatic has had the fix for years in the conversion suppression list. The B2B version, suppressing an account from the display campaign because sales touched it on Tuesday, is almost nobody’s default. I’m not sure, in all of our conversations, we’ve ever spoken to a client that’s wanted to execute this.
It gets overruled. A newer signal contradicts the older one. The champion left. The tech stack changed. The account recorded as “price sensitive” just hired a VP whose first move is replacing the incumbent. The closed-lost field is the clearest case. In a separate thread this week, sales ops people admitted that lost-deal reasons fail the same way “how did you hear about us?” does: price is the easiest button to hit when the form pops up. So the field holds a rep’s guess under time pressure, with no expiry, and eighteen months later it decides whether the account is worth a campaign.
A stack with no TTL can’t tell these three apart. It sees a signal, and a signal is a signal.
The expiry table
This is the part to save and argue with. The windows in the graphic are where I’d start, drawn from running account-based campaigns rather than from a benchmark study. Treat them as an opinion to be corrected by your own data, not a number to copy into a deck.
In words, for anyone reading this somewhere the image doesn’t load: a third-party intent surge gets one surge window, typically a week, and leaves the score after two misses in a row. A job post lives as long as the post does and works as a modifier, never a trigger. A technographic install holds until the next crawl, stamped with the crawl date rather than the import date. A first-party site visit is worth days to a few weeks, weighted by recency and never summed. A download or webinar seat lasts a few weeks, after which it’s a contact record. A closed-lost reason survives one buying cycle, then gets re-asked or discarded. A place on the target account list lasts a quarter, after which every account re-qualifies against live signal. And an engaged-account status resets the moment sales acts, and inherits the shortest TTL of whatever fed it.
Nothing in that table has a TTL of forever, including the list, which is the row that most often does.²
Over to you: which row of the expiry table would you argue with, and what window does your own data say it should have?




