Admins / Sales Cloud / Tutorials

Why Your Salesforce Contact’s Last Activity Date Is Lying to You (And How to Fix It)

By Wanlapa Tantiprasongchai

Last Activity on Contact is a date field that sales, marketing, and ops teams rely on regularly. It drives re-engagement campaigns, lead scoring, pipeline reviews, and more. But if your org has Shared Activities enabled, this field only captures activity for the primary contact on a Task or Event. Secondary contacts do not get updated, which means the data that a lot of teams are reporting on is incomplete.

This article explains why this happens and how to fix it using Rollup Helper and a formula field.

Why Last Activity Date Fails With Shared Activities

Shared Activities is an org-wide setting that lets one Task or Event relate to multiple contacts at the same time. To check if it is enabled in your org, go to Setup → Quick Find → Activity Settings and look for the checkbox “Allow Users to Relate Multiple Contacts to Tasks and Events”.

Salesforce Activity Settings page showing the Allow Users to Relate Multiple Contacts to Tasks and Events checkbox enabled.
Salesforce Setup > Activity Settings showing the Allow Users to Relate Multiple Contacts to Tasks and Events checkbox.

When Shared Activities is enabled, Salesforce stores those contact relationships through two junction objects: TaskRelation for Tasks and EventRelation for Events. One contact is set as primary through the WhoId field. The rest are stored as secondary relations.

READ MORE: What Is the Difference Between WhoId and WhatId?

The issue is that Salesforce only updates the Last Activity date for the primary contact. Secondary contacts are ignored. So if your rep had a meeting with three contacts and one is set as primary, the other two keep whatever date was there before, even though they attended the same meeting. Salesforce has documented this as a known limitation.

Take this task as an example. It was completed on 15 March 2026 and is related to two contacts: Jane Doe as the primary contact and John Doe as a secondary contact.

Salesforce Task record showing Jane Doe as primary and John Doe as secondary contact in the Name field, completed 15/3/2026.
Task “Email about contract renewal” completed on 15/3/2026, with Jane Doe as primary and John Doe as secondary contact in the Name field.

If you open John Doe’s contact record, you can see this task appearing in his activity timeline under March 2026.

John Doe's contact page shows an email about a contract renewal task dated 15 Mar 2026 appearing in the March 2026 activity timeline.
John Doe’s contact page showing the “Email about contract renewal” task from 15 March 2026 in his activity timeline.

But when you pull a report on Contact’s Last Activity Date, John Doe still shows 20/10/2025. Because he was not the primary contact on that task, his Last Activity Date was never updated. Jane Doe, who was primary, shows the correct date of 15/3/2026.

Report showing John Doe Last Activity as 20/10/2025 and Jane Doe as 15/3/2026 after the same shared task was completed.
Contact Last Activity Report showing John Doe with Last Activity 20/10/2025 and Jane Doe with 15/3/2026, despite both being on the same task completed 15 March 2026.

“If your team regularly logs activities against multiple contacts at once, it is worth checking whether Last Activity Date is actually showing what you think it is.”

The Business Impact on Reporting

This affects any process that relies on the Last Activity Date being accurate:

  • Re-engagement campaigns: Marketing pulls a list of contacts with no recent activity. Some of those contacts were in a meeting last week as a secondary relation and should not be on that list.
  • Sales follow-up timing: A rep filters contacts by Last Activity Date to decide who to reach out to next. Secondary contacts show an old date and get skipped.
  • Lead scoring: A contact drops in score because their Last Activity Date looks old, even though they were recently engaged.
  • Account activity tracking: A rep checks when the account was last touched. The date is wrong because the contacts were secondary relations on the most recent activities.
READ MORE: Salesforce Activities: Everything You Need to Know

Creating Task and Event Rollup Fields

The workaround is to create two rollup fields on a Contact that calculate the maximum activity date from TaskRelation and EventRelation directly. This captures activity for all related contacts, not just the primary one.

There are several rollup tools on AppExchange that can handle this. For this article, I will be using Rollup Helper.

Task Rollup: Last Task Date

Start by creating a new Date field on Contact called Last_Task_Date__c. This is where Rollup Helper will store the result. 

Salesforce New Custom Field screen showing Last Task Date field label, field name, description, and help text on the Contact object.
Salesforce Setup showing the Last Task Date custom field configuration on the Contact object with description and help text filled in. Source: Salesforce Setup > Object Manager > Contact.

Then configure the rollup with these settings:

SettingValueNotes
Rollup Object (Parent)ContactThe object being rolled up to.
Source Object (Child)TaskRelationInclude all related contacts.
Rollup TypeMAXReturns the most recent date.
Field to AggregateTask: ActivityDateDate field on the related Task.
Filter CriteriaIsWhat = false AND Task: Status = CompletedContacts only, completed tasks only.
Result FieldLast_Task_Date__cNew Date field on Contact.

Here is a screenshot of the Rollup Helper setting for Last Task Date:

Rollup Helper All Rollups screen showing Contact Last Task Date rollup with TaskRelation source, MAX logic, and Completed Tasks condition.
Rollup Helper showing the Contact Last Task Date rollup with source TaskRelation > Task > ActivityDate, logic MAX, condition Completed Tasks, targeting Contact > Last_Task_Date__c.

Event Rollup: Last Event Date

Create another Date field on Contact called Last_Event_Date__c.

Salesforce New Custom Field screen showing Last Event Date field label, field name, description, and help text on Contact object.
Salesforce Setup showing the Last Event Date custom field configuration on the Contact object with description and help text filled in. Source: Salesforce Setup > Object Manager > Contact

Then set up a second rollup for Events:

SettingValueNotes
Rollup Object (Parent)ContactThe object being rolled up to
Source Object (Child)EventRelationInclude all related contacts
Rollup TypeMAXReturns most recent date
Field to AggregateEvent: ActivityDateDate field on the related Event
Filter CriteriaIsWhat = false AND Event: EndDateTime <= TODAYContacts only, past events only
Result FieldLast_Event_Date__cNew Date field on Contact

 Here is a screenshot of the Rollup Helper setting for Last Event Date:

Rollup Helper All Rollups screen showing Contact Last Event Date rollup with EventRelation source, MAX logic, and Contact Relation condition.
Rollup Helper showing the Contact Last Event Date rollup with source EventRelation > Event > ActivityDate, logic MAX, targeting Contact > Last_Event_Date__c.

A few things worth knowing:

  • By default, Rollup Helper recalculates rollups on Task and Event objects in real-time. No scheduled job needed.
  • Run a manual recalculation in Rollup Helper after your initial setup to backfill existing Contact records. After that, Rollup Helper will handle updates automatically.
  • Test in a sandbox first. It’s always good practice before pushing any configuration to production.
  • Make sure the new fields are visible to the right profiles and permission sets, otherwise the updated dates will not show up for the people who need them.

Once both rollups are saved and the initial manual recalculation is done, you can verify the results by checking your report. In the report below, you can see that John Doe’s Last Task Date and Last Event Date are now correct, which matches the task that was completed on that date. However, his standard Last Activity Date still shows 20/10/2025 because he was a secondary contact on that task. This confirms the rollups are working correctly.

Report showing John Doe with Last Activity 20/10/2025 but Last Task Date 15/3/2026 and Last Event Date 14/8/2025 after Rollup Helper ran.
Contact Last Activity Report after Rollup Helper has been run, showing Last Task Date and Last Event Date now populated for John Doe (15/3/2026) while his standard Last Activity Date still shows 20/10/2025.

Building a Consolidated Formula Field

Now you have two rollup fields, one for Tasks and one for Events. The next step is to combine them into a single field that returns whichever date is more recent. Create a Formula field of type Date on Contact called Last_Activity_Date_All__c and paste in this formula

IF(
    AND(NOT(ISBLANK(Last_Task_Date__c)), NOT(ISBLANK(Last_Event_Date__c))),
    IF(Last_Task_Date__c >= Last_Event_Date__c,
        Last_Task_Date__c,
        Last_Event_Date__c
    ),
    IF(NOT(ISBLANK(Last_Task_Date__c)),
        Last_Task_Date__c,
        IF(NOT(ISBLANK(Last_Event_Date__c)),
            Last_Event_Date__c,
            NULL
        )
    )
)

If both fields have a date, it returns the more recent one. If only one has a date, it returns that one. If neither has a date, it returns null, so contacts with no activity do not show a zero date.

Salesforce Contact custom field detail page showing Last Activity Date All formula field.
Salesforce Contact custom field detail page showing Last Activity Date All formula field.

Once saved, use Last_Activity_Date_All__c in your reports and list views instead of the standard Last Activity Date.

Report showing John Doe with Last Activity 20/10/2025 but Last Activity Date All as 15/3/2026, same as Jane Doe, after formula field was created.
Contact Last Activity Report showing all four fields side by side. John Doe’s Last Activity Date All correctly shows 15/3/2026 even though his standard Last Activity Date still shows 20/10/2025.

Reporting on True Engagement Data

With Last_Activity_Date_All__c in place, here are a few useful reports to start with.

  • Contacts Without Recent Activity: Filter a Contact report where Last_Activity_Date_All__c is older than 30, 60, or 90 days. This gives marketing a much more accurate list for re-engagement compared to using the standard Last Activity Date.
  • Activity Recency by Owner: Group by Contact Owner and add Last_Activity_Date_All__c with a MAX aggregation. Useful for managers who want to see how recently each rep has been in contact with their accounts.
  • Account Engagement Overview: Filter contacts by Account and sort by Last_Activity_Date_All__c descending. This gives a quick view of which contacts within an account have been recently touched and which have not.
  • Contacts Never Contacted: Filter where Last_Activity_Date_All__c is blank. These are contacts with no completed Task or Event on record at all.

Final Thoughts

Last Activity on Contact only tracks the primary contact on a Task or Event. When Shared Activities is enabled, secondary contacts are not included, which makes the field unreliable for reporting or any automation that depends on engagement recency.

The workaround:

  • Use a rollup app (in this article, we used Rollup Helper) to roll up the maximum activity date from TaskRelation and EventRelation on Contact, filtering for completed Tasks and past Events only.
  • Store the results in Last_Task_Date__c and Last_Event_Date__c.
  • Combine them into Last_Activity_Date_All__c using a formula field.
  • Replace Last Activity Date with Last_Activity_Date_All__c in your reports and list views.

If you are already using Last Activity Date for re-engagement or scoring, it is worth running both fields side by side for a while to see how much the data differs. Drop a comment below if you have questions or found a different approach.

The Author

Wanlapa Tantiprasongchai

Wanlapa is a 6x certified Senior Salesforce Solutions Specialist who is passionate about automation, Flow, and turning complex business problems into simple, scalable solutions.

Leave a Reply