Salesforce Renewal Alerts Automation Nobody Ignores
Salesforce renewal alerts automation usually ships as a report subscription nobody reads. Build the escalating version instead — no developer required.
Salesforce renewal alerts automation is the build almost every org attempts and almost no org finishes. The attempt looks the same everywhere: someone makes a report of contracts expiring in the next ninety days, schedules it to email the team every Monday, and calls it an alerting system. Three weeks later that email is a filter rule. Six months later somebody finds out a contract lapsed because the customer mentioned it on a call.
The failure is not that Salesforce lacks a renewal feature. The failure is that a report subscription and an alert are different objects, and teams keep building the first one while needing the second.
A report subscription is a broadcast, not an alert
Here is the actual difference, and it is not pedantic.
A report subscription sends the same list to the same people on the same day forever. It has no memory of what it sent last week. It cannot tell whether anyone acted. It goes to whoever subscribed, not to whoever is responsible. And critically, it treats a contract ending in eighty-nine days exactly the same as one ending in four.
An alert has state. It knows it already fired at ninety days and got no response, so at sixty it should get louder and involve somebody else. It knows who owns the outcome, not just who owns the record. It stops when a human acknowledges it, and only then.
That difference is why the report version dies. Every message is identical, so the team learns that no message is urgent, which is a rational response to an unranked feed. You did not build an alerting system. You built a training program for ignoring alerts.
What you’re actually building: an escalation, not an email
The thing worth building is a small state machine that runs nightly, looks at every date-bearing record in your org, and asks one question per record: given how close this is and what we’ve already done about it, what should happen tonight?
Everything below is a step toward that. The build is not large. It is a custom object, one scheduled job, a query, and a set of rules you already enforce informally. It takes an experienced admin-plus-developer pair a couple of days, which is precisely why it never gets scheduled — it is too small to justify a project and too involved to squeeze into a Friday.
Step 1: Find the date field you already have
Before building anything, locate the field that carries the deadline. In most orgs it already exists, unloved and unqueried.
Standard candidates depending on your model: Contract.EndDate if you use the Contract object, Asset.UsageEndDate for equipment and warranties, Entitlement.EndDate for support terms, Opportunity.CloseDate for a renewal opportunity created ahead of time. Plenty of teams have a custom Renewal_Date__c on Account instead, which is fine.
If the date lives in a spreadsheet rather than the org, stop here — you have a data-model problem before you have an alerting problem, and the custom object your process actually needs is the prerequisite build. An alert can only fire on data the org can see.
One more thing to find while you are looking: the records that should have a date and don’t. A null renewal date is an invisible renewal, and it will never fire an alert of any kind. Count those now. That number is usually the most alarming thing in this entire exercise.
Step 2: Write the escalation ladder before you build anything
Write the ladder as sentences, in plain language, before touching Setup. If you cannot write it, you cannot build it, and this is where most attempts quietly fail.
A workable starting ladder, to adapt rather than copy:
- 90 days out: a task for the record owner. Quiet. No email.
- 60 days out, unacknowledged: task plus an email to the owner and their manager.
- 30 days out, unacknowledged: task to the manager directly, and post to the account team channel.
- 14 days out, unacknowledged: route to the renewals queue and flag the record at-risk.
- Acknowledged at any rung: stop. Log who and when.
Notice that every rung after the first depends on the word unacknowledged. That single condition is the entire difference between this and the report subscription. It also tells you what to build next.
Step 3: Make the alert a record, not a message
Give the alert somewhere to live: a Renewal_Alert__c custom object with a lookup to the record, plus fields for the rung it reached, the date it fired, who acknowledged it, and when.
This one decision buys you almost everything the report version can never do. State becomes durable, so tonight’s job can see what last night’s job did. Acknowledgment becomes a field rather than a hope. And the whole thing becomes reportable — you can finally answer “how many renewals fired to the 30-day rung last quarter, and who acknowledged them,” which is a question no email log will ever answer.
It also makes the system debuggable. When someone insists they never got an alert, you have a record that says otherwise or agrees with them, and either way you learn something.
Step 4: Query the window, not the day
This is the step that quietly separates an alerting system that survives from one that silently drops records.
The intuitive query is date-exact: find everything where the renewal date is exactly ninety days from today. It works perfectly until the night your scheduled job doesn’t run — a deploy, a maintenance window, a job that failed on a governor limit. Every record that hit ninety days that night is skipped, permanently, because tomorrow they are at eighty-nine and no longer match.
Query a window instead. Salesforce’s SOQL date literals make this easy — NEXT_N_DAYS:90 gives you everything due in the next ninety days relative to when the query runs, so a window query combined with the alert records from Step 3 becomes self-healing. Each night the job asks which records are inside the window and haven’t yet received the rung they qualify for. Miss a night and the next run catches up on its own.
Write it that way from the start. Retrofitting it after you have discovered a silently missed renewal is a much worse afternoon.
Step 5: Route to a role, not a person
The record owner is the obvious recipient and the wrong default. Owners go on PTO, change territories, and leave the company, and a renewal alert sent to a deactivated user is worse than no alert because it looks handled.
Resolve the recipient at send time rather than storing it: try the owner, check whether they are active and available, then fall back to their manager, then to a queue that is guaranteed to have somebody in it. It is the same fallback discipline that makes round-robin lead assignment survive a real team — every routing decision needs a defined answer for “nobody is eligible,” or it silently routes to nobody at all.
Log the resolved recipient on the alert record. When the escalation goes wrong, that field is the first thing you will want.
Step 6: Run one job, not one job per alert type
Architecturally, resist the temptation to schedule a separate job for contracts, another for warranties, another for certifications. Salesforce caps you at 100 scheduled Apex jobs at one time, and orgs burn through that allowance faster than anyone expects once every team schedules its own.
Run one nightly job that iterates over a configuration — a custom metadata record per alert type naming the object, the date field, the ladder, and the fallback queue. Adding a new alert type becomes a config row instead of a deployment, which means the next request lands on an admin rather than back on a development queue.
If your volumes are large, have that job hand off to a batch class rather than processing inline. The failure mode you are avoiding is a governor limit on a Tuesday in month-end, taking the whole night’s alerting down with it.
Step 7: Backtest against the renewals you already missed
Do not test this with fake data. Test it against your own history.
Point the job at a sandbox with real data, set the clock reference back a year, and run it forward against renewals you have already lived through. You know which ones lapsed. You know which ones got saved at the last minute by somebody’s memory. A system worth deploying should light up on the ones that lapsed, at a rung early enough that somebody could have acted.
This backtest is also the only convincing thing you can show a skeptical VP. Not a diagram — a list of the specific renewals from last year that this would have caught, and when.
What this used to cost, and what changed
Spec, custom object, scheduled job, escalation logic, tests, deploy: call it a solid couple of days of combined admin and developer time, then a review cycle. Nothing about that is hard. It is just expensive enough, and small enough, that it loses every prioritization meeting it enters. That is the real reason renewal alerts don’t exist in most orgs — not difficulty, but the awkward size.
What changed is who does the building. With Sentinel giving your AI the ability to develop in your org, the ladder you wrote in Step 2 is the request. You describe the rungs, the acknowledgment rule, the fallback chain and the config model; your AI builds the object, writes the scheduled class and its tests, deploys to a sandbox first, and reports back with results you read and approve. The two-day build becomes an afternoon of conversation and review, at $500/month per Sentinel plus a one-time $2,500 onboarding on your first one.
Being straight about the limits: none of this stops you from deploying a ladder that’s wrong. Set your rungs badly and you will get badly timed alerts — deployed accurately, logged completely, and reversible. Every change is visible and every deploy recoverable, which is a different promise than “safe,” and the honest one. The full mechanism is written up separately if you want it. ORG Endgame is not affiliated with Salesforce; Sentinel works through Salesforce’s own supported APIs.
Start with the date you’re already tracking by hand
Don’t build the general system first. Build the one alert you are currently doing with your own memory.
Almost every ops lead has one: the spreadsheet tab, the recurring calendar reminder, the quarterly ritual of opening a report and eyeballing dates. That is a rung-one alert you have already specified and already tested — you have just been executing it manually. Move that one into the org, watch it run for a month, then add the second alert type as a config row.
Once the pattern exists, the rest of the backlog looks different. The renewal alerts nobody remembers to send stop being a someday item, and so do the other CRM tasks that were never too hard to build, only too small to buy.
Put your renewals on rails — onboarding included.
KEEP READING
Bulk Update Salesforce Records Without Data Loader
How to bulk update Salesforce records without Data Loader — when a CSV round-trip is right, and when to build a job that runs itself.
Build Salesforce Round-Robin Lead Assignment With AI
Salesforce round-robin lead assignment isn't native. Here's how to build one that respects capacity and PTO — and deploy it without hiring a developer.
Ready to see what AI can do for your business?
Start a Conversation