You are here:
Get Started with Archive Policies
Create automated jobs on a regular cadence to either archive data from Salesforce according to your needs, or purge from the Archive managed package for compliance or other requirements.
An archiving policy sets out the principles and requirements for archiving data and its retention period.
The retention period defines how long the archived records remain before being purged. This is based on a single criteria.
Data purging is the process of permanently removing obsolete data from your Archive database when it is no longer required. The purge policy overrides the original expiration date defined by when the data was archived according to the retention period. A Purge Policy allows you to create more complex purge criteria other than time, with multiple conditions available for selection.
Pre-defined, Out-of-the-Box Archiving Policies
To assist your onboarding process, there are five out-of-the-box policies in the Policies tab with common objects that you can activate, edit, clone, or use as an example.
Before You Start with Archiving Policies
We recommend reviewing the questions below before starting to create Archiving Policies.
- Which objects and related objects do you want to archive and why?
- What is the scheduled frequency (weekly / daily / monthly) that the Archive must run?
- What day of the week or month and at what time must the archive policy run?
- When must policies be set to run?
- Customers can choose to run archive jobs during off-peak hours (e.g. overnight or weekends) based on internal policies.
- Who can set up archiving policies (Admins only)?
- Permission Sets can be assigned to appropriate system admins.
- Who needs to see the archived data? (Admins only / End users / Auditors / etc.)
- Who has access to the unarchive records? ( Admins only / End users / Auditors / etc.)
- Permission Sets can be assigned to appropriate users.
OwnBackup_Unarchivepermission set lets the user unarchive records.
Now, you can jump straight to;
Example of Use Cases and Queries
For testing purposes, we recommend starting with a low policy limit initially.
Archive Tasks
Object: Task
Use Case: Archiving Tasks that are associated with a specific record type of contact,
for example RecordTypeID = 'abc', and last modified more than 2
years ago
LIMIT = 5 archives 5 tasks in each run and its related objects
Preview: Id, Activity Date, Category (custom field), Description, Owner ID, Subject, Status
SELECT Id FROM Task WHERE Whold IN (SELECT Id FROM Contact WHERE RecordTypeid
= 'abc') AND ActivityDate<LAST_N_DAYS: 730 LIMIT 5
Archive Cases
Object: Case
Use Cases: Archive cases that meet these criteria:
- Status is set to
Closed - Created more than 30 days ago
LIMIT = 5000 archives 5000 cases in each run and its related
objects
Preview: Id, Case Number, Type, Sub Category (custom field), Issue (custom field)
SELECT Id FROM Case WHERE Status = 'Closed' AND CreatedDate < LAST_N_DAYS:
30 LIMIT 5000
Archive Cases from a Specific Account
Object: Case
Use Cases: Archive cases that meet this criteria:
- Status is set to
Closed - Created more than 30 days ago
- Belongs to account with ID number
1234
LIMIT = 5000 archives 5000 cases in each run and its related
objects.
Preview: Id, Case Number, Type, Sub Category (custom field), Issue (custom field)
SELECT Id FROM Case WHERE accountId IN (SELECT id from Account WHERE id
='1234XXXXXXXXXXXXXXX') AND Status = 'Closed' AND CreatedDate <
Last_N_Days:30 LIMIT 5000
Archiving Attachments
Object: Attachment
Use Cases: Archive attachments where:
- Parent is an Opportunity in a stage that is either
Signed OfforAsbestos Completed. - Opportunity Close Date is more than 6 months in the past.
LIMIT = 2500 archives 2500 attachments in each run and its related
objects
Preview: Id, Parent ID, Created Date
SELECT Id FROM Attachment WHERE ParentId IN (SELECT Id FROM Opportunity WHERE
(StageName='Signed Off' OR StageName='Asbestos Completed') AND CloseDate <
N_MONTHS_AGO:6) LIMIT 2500
Archiving Contacts
Object: Contact
Use Cases: Archive contacts where:
Archiver__cfield is set toTrue
LIMIT = 1000 archives 2500 contacts in each run and its related
objects.
Preview: Id, Parent ID, Created Date
SELECT Id FROM Contact WHERE Archiver__c = true LIMIT 1000
Archive Queries Best Practices
To improve the success of Archive queries, consider these recommendations:
- Write conditions on indexed fields. The complexity of the SOQL query enormously influences whether a field is suitable for indexing. Standard and custom indexes are different.
- See the Salesforce resource Query & Search Optimization Cheat Sheet.
- Limit the result set to a manageable size — retrieving too many records at once can trigger table scans, which are significantly slower than indexed lookups.
- Avoid overly broad filters that match large volumes of data. If needed, split your date ranges into smaller batches to reduce query load.
- Validate filter logic regularly to ensure you're targeting only the records you truly need to archive.
- Monitor job logs to identify recurring performance bottlenecks or records that fail to proceed through the entire job lifecycle.
- See Filter Query Results Using Dates.
- Reference the
SystemModstamprather than theLastModifiedDate. - Consider that Force.com has its own SOQL query optimizer. For more details, see Salesforce resource: Lightning Platform query optimization FAQ.
Optimizing Queries
When running queries in Salesforce, it's crucial to ensure they are optimized to improve efficiency and avoid performance issues, especially when dealing with large datasets. Below are best practices to refine queries for better efficiency.
Identifying Full Table Scans
A common issue is that certain filters can trigger a full-table scan, which negatively impacts performance. For example:
SELECT Id FROM EmailMessage WHERE ParentId IN (SELECT Id FROM Case WHERE
IsClosed = true) AND LastModifiedDate < LAST_N_MONTHS:13 LIMIT 350000
Problems with This Query
IsClosedis not a selective filter, meaning it doesn't leverage an index efficiently.LastModifiedDatecan return more than 1 million records, which prevents the use of an index.- The queried object must be indexed in Salesforce to take full advantage of query optimizations.
- The
INsubquery must be removed to improve efficiency.
Steps to Optimize the Query
- Remove the
INsubquery: This reduces unnecessary complexity. - Ensure the object is indexed: Queries on non-indexed objects don't benefit from performance optimizations.
Enable Query Plan in Developer Console
- Go to Help | Preferences in Developer Console.
- Enable the Query Plan option to analyze query selectivity.
Modify Filters for Better Performance
- Change
Parent.IsClosedto an indexed field. - Use
SystemModstampinstead ofLastModifiedDate, as it is indexed and generally more efficient. - Consider narrowing the date range to reduce the number of records scanned. For
example,
<13and>15
SELECT Id FROM EmailMessage WHERE Parent.IsClosed = true AND
LastModifiedDate < LAST_N_MONTHS: <13 and >15 LIMIT
350000
LastModifiedDate vs. SystemModstamp
LastModifiedDate is user-driven and updates when users make changes
to records.
SystemModstamp is system-driven and updates when a record is
modified by the system, including automation and back end processes.
Queries using SystemModstamp tend to perform better because they're
indexed.

