Office hours: Build your self-driving GTM engine·Oct 29, 9:00am PT, onlineRegister→
Cargo
  • PrimitivesData ModelsYour companies, contacts and deals, merged from every sourceContextWhat your team knows, as files every agent readsTerritoriesWho sells where, defined onceMailboxesMailboxes in your reps' names, warmed up and kept under limitsToolsThe actions your agents, plays and reps callAgentsAI that researches, decides and writes, reading your contextPlaysWorkflows that run on a trigger or a schedule, with retriesAppsInternal apps for your reps, hosted on Cargo
    Add-onsChrome ExtensionSell faster, right in your browserButtonTrigger AI agents inside your CRMFormTurn any tool into an embeddable formSlackTag Cargo in Slack. It does the GTM workGitHubPlan on every pull request, deploy on merge
    MoreProjectsDefine your entire GTM in codeCLIUse Cargo from your terminalMCPUse Cargo from Claude and ChatGPTDeveloper resourcesCargo API docs, OpenAPI spec, auth docs, webhooks, MCP serverAPI ReferenceExplore the Cargo APIDocumentationLearn how to use CargoIntegrationsConnected to your entire GTM stack
  • VeriffHow Veriff replaced MuleSoft with Cargo under NetSuite, Stripe and SalesforceAugmentHow Augment Code routes developer sign-ups to reps in under an hourWeights & BiasesHow Weights & Biases ships a new purchase signal in 2 days on CargoSee all
  • Pricing
  • Cookbooks
  • Blog
Sign in
Blog

How Long Is a Buying Signal Worth? Time Decay, Weights, and Verification

30 Sept6min read
AurelienAurelien

Every buying signal has a shelf life, and most GTM systems never write it down. A job change is worth acting on for months. A hiring spike is stale in weeks. Serve both to a rep with the same weight and no expiry, and the rep chases last spring’s news with a reason that no longer holds. The fix is small: give each signal type a window and a weight, verify the signal before it counts, and stop serving it when the window closes.

John Kutay, who runs growth and GTM engineering at Rippling, described how they do this in his talk on Rippling’s Growth OS, for a system with 2,000 internal monthly users processing over a billion rows a day. The mechanics are the same at a startup.

Not every signal is equal #

Rippling keeps a large catalog of signals, but a handful are canonical: a job change, a funding round, a new office opening. Those are ranked high and handed to the rep as the reason, when the account is in the addressable market and matches the ICP. Everything else is ranked below them in different ways.

That split is the first decision to make: which signals are strong enough to be the reason for a touch on their own, and which only nudge a score. Most teams skip it and end up with a single intent number made of thirty ingredients, which a rep cannot explain to a prospect and a model owner cannot debug.

The simplest decay is a WHERE clause #

Asked how they set the decay per signal, John’s answer was refreshingly plain: it is a filter. How recent was the signal? If it is outside the window, it is not served to the rep.

sql
-- Serve only signals still inside their window.
SELECT s.*
FROM signals s
JOIN signal_types t ON t.slug = s.type
WHERE s.observed_at >= now() - t.window

The windows he gave: three to six months for a job change, a little longer for an office opening, and much fresher for hiring activity. The numbers matter less than the fact that each type has one, it is written down, and it is in a table you can change with a reviewed diff instead of a setting nobody remembers.

Start with a hard window. It is easy to reason about, easy to explain (“we only flag job changes from the last four months”), and it removes most of the stale noise on day one.

When to add weights and a curve #

A hard window treats a signal from yesterday and one from 89 days ago the same. Once the window is working, the next step is a weight that falls over time. An exponential half-life is the usual shape:

sql
-- Weight halves every half_life; zero outside the window.
SELECT s.account_id,
       SUM(t.weight * power(0.5, extract(epoch FROM now() - s.observed_at)
                               / extract(epoch FROM t.half_life))) AS intent
FROM signals s
JOIN signal_types t ON t.slug = s.type
WHERE s.observed_at >= now() - t.window
GROUP BY s.account_id

Two rules keep this honest:

  • Set weights from outcomes, not intuition, as soon as you can. Which signal types preceded meetings and pipeline last quarter? That is a query, not a debate. Until you have the data, a reasoned guess written in a file beats an unreviewed guess in a tool.
  • Keep the canonical signals as reasons, not just points. A rep needs “they raised a round three weeks ago”, not “intent is 74”. The score ranks the list. The signal is what goes in the first line.

Verify before it counts #

The step most teams skip comes before any of this. In John’s words, raw signals need verification.

A signal arrives as a fragment: someone changed jobs, a company raised money. Before it can mean anything, it has to be resolved to an account and a contact you already know, checked against what the CRM says, and confirmed to be what it looks like. A funding headline about a company with a similar name is not a signal. It is a false positive with a timestamp.

Rippling does this with coding agents. The question they encoded is how a human would check this: pull the record from the CRM, compare the sources, decide. The agent gets the same tools and makes the same decision, with evaluations run against it before the pipeline ships. Only verified signals go live for sellers.

Verification is also where decay starts. The clock runs from when the event happened, not when you found out. A job change your provider reported in September that happened in May has already used most of its window.

What to write down #

A signal catalog is one table, and it belongs next to the scoring model in your repository:

FieldExampleWhy
slugjob_changeThe stable key every play references
canonicaltrueCan this be the reason for a touch alone
window120 daysAfter this, it is not served
half_life45 daysHow fast its weight falls inside window
weight3Relative strength against other types
verified_byagent:resolverWhat confirms it before it counts

When a rep says an alert was stale, the answer is a one-line pull request against this table, reviewed and reversible. When it lives in a vendor’s settings, the answer is a shrug.

For the wider pattern, see signal-based selling and operationalizing custom signals.

FAQ #

It depends on the type. Rippling serves job changes for roughly three to six months, office openings a little longer, and hiring activity for a much shorter window. Give every signal type its own window, write it down, and stop serving the signal once the window closes.

Time decay reduces the weight of a buying signal as it ages, so recent events count more than old ones. The simplest version is a hard expiry window. A more precise version applies a half-life so the weight falls gradually until the window ends.

Use both. A score is useful for ranking accounts, but the strongest signals, such as a job change or a funding round, should also be passed to the rep as the explicit reason for reaching out, because a number alone gives them nothing to say.

Because raw signals are fragments. A signal has to be resolved to a known account and contact and checked against existing records before it is trusted, or reps act on false positives such as news about a similarly named company.

~/run-it-on-cargo/

Build this workflow instead of reading about it.

Cargo is the GTM infrastructure your coding agent builds on: enrichment, scoring, routing and outreach, defined in code and run in production.

Start building
AurelienAurelienSept 30, 2026
On this page
  • Not every signal is equal
  • The simplest decay is a WHERE clause
  • When to add weights and a curve
  • Verify before it counts
  • What to write down
  • FAQ

Stay Informed with our
weekly Newsletter

Related articlesSee all articles
Sales Operations
How to Qualify a List of Leads Against Your ICP

To qualify a list of leads against your ICP, enrich each company by domain, score it with deterministic rules that put a score, a reason and a tier on every row, then write the verdict back to your CRM. The runnable steps with the Cargo CLI and the open-source score-leads skill, then where automated qualification breaks between systems.

MaxMax·Oct 16, 2026
Sales Operations
Find Every Portfolio Company of an Investor, Then the People Inside

How go-to-market teams and their coding agents list every portfolio company of a VC or accelerator, then the decision-makers at each one, with two Cargo actions: an investor-filtered company search and a people search by domain. Commands, prices and returned fields.

AurelienAurelien·Oct 16, 2026
Sales Operations
Monitor Buying Signals on a List of Accounts

Check a list of target accounts for the dated, public events that mean someone is in market: a job post for the role you sell into, a company saying something new, a detection feed firing. The commands with the Cargo CLI and the open-source monitor-buying-signals skill, free check first, what each check costs, and what a signal does not give you.

AurelienAurelien·Oct 16, 2026

Build the self-driving GTM engine

Your coding agents build it on Cargo.Or our team builds, operates and improves it with you.

Start building
Cargo
Backed byY CombinatorSOC 2 Type IICertified
LinkedinX

Product

Data ModelsContextTerritoriesMailboxesToolsAI AgentsPlaysAppsIntegrationsPricing

Add-ons

Chrome extensionButtonFormSlackGitHub

Build

DocsDeveloper resourcesCargo API docsCargo OpenAPI specCargo auth docsCargo webhooksCargo MCP serverProjectsClaude CodeCodexCursorAll coding agents

Resources

ReportsBlogCustomer storiesCookbooksEnrichmentRoutingSignalsScoringCRM hygieneAd audiencesGTM skillsGTM EngineeringGlossaryCompareCargo x ClayCargo x WorkatoCargo x n8nCargo x DeeplineCargo x DefaultCargo x LeanDataCargo x UnifyCargo x ValleyCargo x GojiberryCargo x PhantomBusterCargo x ZapierCargo x ApolloCargo x Chili PiperCargo x Common RoomCargo x MakeCargo x Tray.io

Company

ManifestoCommunityEventsJobsPartners DirectoryPartner Program

Legal

SecurityTerms of servicePrivacy PolicyRefundsDPASupport
© 2026 Cargo
 ////////    ///////    ////////     ////////    ///////
///         ///   ///   ///   ///   ///         ///   ///
///         ///   ///   ///   ///   ///         ///   ///
///         /////////   ////////    ///  ////   ///   ///
///         ///   ///   /// ///     ///   ///   ///   ///
///         ///   ///   ///  ///    ///   ///   ///   ///
 ////////   ///   ///   ///   ///    ///////     ///////

$ npm install -g @cargo-ai/cli