Loading
Feature Disruption - Service Cloud VoiceRead More
Feature degradation | Gmail Email delivery failureRead More
Set Up and Maintain Your Salesforce Organization
Table of Contents
Select Filters

          No results
          No results
          Here are some search tips

          Check the spelling of your keywords.
          Use more general search terms.
          Select fewer filters to broaden your search.

          Search all of Salesforce Help
          Get Started with Archive Policies

          Get Started with Archive Policies

          Use the Archive app to create automated, scheduled policies that manage your data's lifecycle.

          Archive Policies

          An archive policy defines the criteria for moving data from production into your archive. When you create this policy, you also set its initial retention period.

          An archive policy uses a single condition, such as LastModifiedDate > 365 days ago, to identify which records to archive.

          An archive policy also sets a simple, default retention period, such as "Delete 7 years after archive date." The retention period sets the archived record's initial expiration date.

          Purge Policies

          A purge policy defines the criteria for permanently deleting data that's stored in your archive.

          The purge policy changes the default retention period set by the archive policy and gives you more power and flexibility to manage data destruction.

          For example, you can purge certain record types sooner, such as Record Type = 'Test Data' AND Archived Date > 1 year, while keeping more critical records longer, such as Record Type = 'Financial' AND Archived Date > 10 years, regardless of the default 7-year retention set during the archive policy.

          Key Questions Before You Begin

          A good policy starts with a good plan. Before you start building, discuss these key questions with your stakeholders.

          What to Archive?

          • Which root objects and their related child records must be archived? For example, closed Cases, old Tasks, or custom project records.
          • What's the business driver? Are you trying to improve performance, reduce storage costs, or meet a specific compliance requirement?

          When to Run?

          • How often must the archive and purge policies run? For example, daily, weekly, or monthly.
          • What specific time and day must the archive and purge policies run?
            Note
            Note To reduce any possible impact on your users and system performance, we strongly suggest running large archive or purge processes during off-peak hours, such as nights and weekends.

          Who Has Access?

          • Who's responsible for creating and managing these archive and purge policies?
            Note
            Note Typically a system admin, but you can assign the Archive permission sets to the appropriate admins.
          • Who needs to view data after it's been archived? For example, admins, auditors, or specific support teams.
          • Who requires permission to unarchive records from your archive and restore them back to your live org?
            Note
            Note The Unarchive permission sets control this capability. Assign these permission sets only to specific users who require it.

          Use Cases and Queries

          For testing purposes, we recommend starting with a low archive policy limit.

          Example: Archive Tasks

          Object: Task

          Use Case: Archive Tasks that meet these criteria.

          • Related to record type of Case
          • RecordTypeID = 'abc'
          • Last modified more than 2 years ago

          LIMIT = 5 archives 5 Tasks in each run, and their 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

          Example: Archive Cases

          Object: Case

          Use Case: 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 their 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

          Example: Archive Cases from a Specific Account

          Object: Case

          Use Case: Archive Cases that meet this criteria.

          • Status is set to 'Closed'
          • Created more than 30 days ago
          • Belongs to an 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

          Example: Archive Attachments

          Object: Attachment

          Use Case: Archive attachments where:

          • Parent is an Opportunity in a stage that is either 'Signed Off' or 'Asbestos Completed.'
          • Opportunity Close Date is more than 6 months in the past.

          LIMIT = 2500 archives 2,500 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

          Example: Archive Contacts

          Object: Contact

          Use Case: Archive contacts where:

          • Archiver__c field is set to True

          LIMIT = 1000 archives 2,500 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.
          • Consult the Query & Search Optimization Cheat Sheet.
          • Limit the result set to a manageable size‌. Retrieving too many records at one time 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 that must be archived.
          • Monitor process logs to identify recurring performance bottlenecks or records that fail to proceed through the entire process lifecycle.
          • Filter query results by using dates. For more information, see Date Formats and Date Literals in WHERE.
          • Reference the SystemModstamp rather than the LastModifiedDate.

            LastModifiedDate is user-driven and updates when users change records. SystemModstamp is system-driven and updates when a record is modified by the system, including automation and back-end processes. Queries that use SystemModstamp tend to perform better because they're indexed.

          • Consider that Force.com has its own SOQL query optimizer. For more information, see Lightning Platform Query Optimization FAQ.

          Optimize Archive Queries

          When you run queries in Salesforce, it's important to make sure that they're optimized to improve efficiency and avoid performance issues, especially when you're working with large datasets.

          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:

          • IsClosed isn't a selective filter, meaning it doesn't use an index efficiently.
          • LastModifiedDate can return more than 1 million records, which prevents the use of an index.
          • To take full advantage of query optimizations, index the queried object in Salesforce.
          • To improve efficiency, remove the IN subquery.

          To optimize the query:

          • Remove the IN subquery, which reduces unnecessary complexity.
          • Make sure that the object is indexed.

            Queries on non-indexed objects don't benefit from performance optimizations.

          • Turn on the Query Plan setting in the Developer Console.

            The Query Plan setting analyzes query selectivity. To turn on this setting, go to Preferences under Help in the Developer Console.

          • Modify these filters.
            • Change Parent.IsClosed to an indexed field.
            • Use SystemModstamp instead of LastModifiedDate, as SystemModstamp is indexed and more efficient.
            • To reduce the number of records scanned, narrow the date range. For example, <13 and >15.

          Here's the new, more efficient query.

          SELECT Id FROM EmailMessage WHERE Parent.IsClosed = true 
          AND LastModifiedDate < LAST_N_MONTHS: <13 and >15 LIMIT 350000
           
          Loading
          Salesforce Help | Article