SfSkills Domains Docs GitHub

Home / devops / sandbox-refresh-and-templates

sandbox-refresh-and-templates

Sandbox refresh cycles, sandbox templates, post-refresh automation via the SandboxPostCopy Apex interface, and data handling during refresh. NOT for sandbox type selection — use admin/sandbox-strategy.

Open the skill folder on GitHub


Sandbox Refresh and Templates

This skill activates when a practitioner needs to run, plan, or troubleshoot a sandbox refresh — including how to configure sandbox templates for Partial Copy sandboxes, automate post-refresh setup using the SandboxPostCopy Apex interface, and handle data safely during the refresh process. It does not cover choosing which sandbox type to use (see admin/sandbox-strategy for that).


Trigger Scenarios


Before Starting

Gather this context before working in this domain:


Core Concepts

Refresh Intervals by Sandbox Type

Salesforce enforces mandatory minimum intervals between sandbox refreshes. A sandbox cannot be refreshed again until the interval has elapsed since the previous refresh completion.

Sandbox TypeRefresh IntervalData Copied
Developer1 dayMetadata only — no production data
Developer Pro1 dayMetadata only — no production data
Partial Copy5 daysMetadata + subset of data defined by sandbox template
Full29 daysMetadata + all production data (storage mirrors production)

Developer and Developer Pro sandboxes are configuration-only copies. They receive no production records. Full sandboxes are exact replicas including all records. Partial Copy sandboxes receive a data subset controlled by a sandbox template.

Sandbox Templates (Partial Copy Sandboxes Only)

Sandbox templates define which objects and how many records are copied into a Partial Copy sandbox. Templates are configured in Production under Setup > Sandbox Templates before the sandbox is created or refreshed.

Key behaviors:

SandboxPostCopy Interface

The SandboxPostCopy interface is a System namespace Apex interface that runs automatically at the end of sandbox creation or refresh. It is the only supported mechanism for automating post-refresh configuration inside the sandbox itself.

Interface definition:

global interface SandboxPostCopy {
    void runApexClass(SandboxContext context);
}

SandboxContext methods available inside runApexClass:

How to register the class: When creating or refreshing a sandbox via Setup UI, specify the Apex class name in the "Apex Class" field on the sandbox create/refresh form. The class must exist in the production org (not the sandbox), must be global, and must implement SandboxPostCopy.

Execution context: The class runs under the Automated Process user in the new sandbox. This user does not have access to all objects and features. Any DML or callouts must be authorized under that user's permission set. Use @future or Queueable if the work needs to run asynchronously after the initial post-copy script completes.

What SandboxPostCopy can automate:

Org ID Changes on Refresh

Every time a sandbox is refreshed, the sandbox org receives a new organization ID. Any code, custom setting, or metadata that stores the org ID as a hardcoded value will be stale after the refresh. The SandboxContext object provides the new org ID via context.organizationId() and should be used to update any stored org ID values inside the post-copy script.


Mode 1: Plan and Execute a Sandbox Refresh

Use this mode when preparing for an upcoming refresh or executing one for the first time with proper automation.

Step 1 — Confirm refresh eligibility

Check when the sandbox was last refreshed. The refresh option in Setup is greyed out until the interval has elapsed. The interval resets from the moment the previous refresh completed (not when it was initiated).

Step 2 — Check or create a sandbox template (Partial Copy only)

If the target is a Partial Copy sandbox, review the template attached to it under Setup > Sandbox Templates. Confirm it includes the objects your team needs for testing. Attach or update the template before initiating the refresh.

Step 3 — Write or update the SandboxPostCopy class in production

The class must live in production and must be global. Minimum pattern:

global class SandboxSetup implements SandboxPostCopy {
    global void runApexClass(SandboxContext context) {
        String sandboxName = context.sandboxName();
        String orgId = context.organizationId();

        // Update custom settings with the sandbox org ID
        Sandbox_Config__c cfg = Sandbox_Config__c.getOrgDefaults();
        cfg.Org_ID__c = orgId;
        cfg.Environment_Name__c = sandboxName;
        upsert cfg;

        // Deactivate any scheduled jobs that should not run in sandbox
        for (CronTrigger ct : [SELECT Id FROM CronTrigger WHERE State = 'WAITING']) {
            System.abortJob(ct.Id);
        }

        // Reset integration endpoint to sandbox URL in custom metadata
        // (use a Queueable for callouts or DML that needs async context)
    }
}

Step 4 — Register the class on the sandbox record

In Setup > Sandboxes, click Refresh next to the target sandbox. In the refresh form, enter the name of the SandboxPostCopy class in the "Apex Class" field.

Step 5 — Initiate the refresh

Submit the refresh. Monitor status under Setup > Sandboxes. A Full sandbox refresh can take hours to days depending on data volume. Developer sandboxes typically complete in minutes.

Step 6 — Run the post-refresh manual runbook

Document and execute any steps the SandboxPostCopy class cannot handle:


Mode 2: Review or Audit Post-Refresh State

Use this mode on an existing sandbox to assess whether refresh automation is adequate or identify drift from production.

  1. Check whether a SandboxPostCopy class is registered on the sandbox record in production Setup. If none, all post-refresh setup is manual and error-prone.
  2. Search the production org for any Apex classes implementing SandboxPostCopy. Confirm only one active class is registered per sandbox.
  3. Audit custom settings and custom metadata for hardcoded org IDs — query Organization.Id and compare against stored values.
  4. List active scheduled jobs in the sandbox (SELECT Id, CronJobDetail.Name, State FROM CronTrigger). Flag any that point at production endpoints.
  5. Review Named Credentials — any that require password/OAuth reconfiguration after refresh should be documented in the manual runbook.
  6. For Partial Copy sandboxes, verify the sandbox template includes all objects needed for current test scenarios. Templates should be reviewed before each refresh cycle.
  7. Check whether email deliverability is set to "System Email Only" or "All Email" in the sandbox — most sandboxes should be on "System Email Only" to prevent test emails reaching real users.

Mode 3: Troubleshoot Refresh Issues

Use this mode when a refresh has failed, the SandboxPostCopy class did not run, or the sandbox is in an unexpected state after refresh.

SandboxPostCopy class did not execute

Refresh is stuck or taking unexpectedly long

Data from the template is not what was expected (Partial Copy)


Decision Guidance

SituationRecommended ApproachReason
Need to automate user passwords and org settings after refreshImplement SandboxPostCopy class in productionOnly supported automated hook for post-copy setup inside the sandbox
Need to control which records land in a Partial Copy sandboxDefine a sandbox template in production before refreshTemplates are the only supported mechanism for Partial Copy data scoping
Need specific records in a sandbox, not just a random subsetUse Developer sandbox + data loading scripts post-refreshPartial Copy templates cannot filter by specific record criteria
Named Credentials must be reconfigured after every refreshDocument in manual runbook; consider SandboxPostCopy to set placeholder valuesNamed Credential secrets cannot be set via Apex — manual entry required
Scheduled jobs must not fire in sandboxAbort all CronTrigger records in SandboxPostCopy classJobs are copied from production in an active state and will fire unless explicitly aborted
Org ID is stored in custom settings or codeRead new org ID from SandboxContext in SandboxPostCopy and update stored valuesOrg ID changes on every refresh — stale IDs cause downstream failures

Step-by-step instructions for an AI agent or practitioner activating this skill:

  1. Gather context — confirm the org edition, relevant objects, and current configuration state
  2. Review official sources — check the references in this skill's well-architected.md before making changes
  3. Implement or advise — apply the patterns from Core Concepts and Common Patterns sections above
  4. Validate — run the skill's checker script and verify against the Review Checklist below
  5. Document — record any deviations from standard patterns and update the template if needed

Review Checklist

Run through these before marking a refresh cycle complete:


Salesforce-Specific Gotchas

Non-obvious platform behaviors that cause real production problems:

  1. Org ID changes on every refresh — The sandbox receives a new organization ID each time it is refreshed. Hardcoded org IDs in custom settings, custom metadata, Apex constants, or remote site settings will be stale immediately after refresh. Use context.organizationId() in SandboxPostCopy to update any stored values.
  2. Scheduled jobs are active in the sandbox immediately after refresh — All CronTrigger records are copied from production with their WAITING state preserved. If those jobs make callouts or DML against production data endpoints, they will fire in the sandbox. Always abort or reschedule CronTrigger records in SandboxPostCopy.
  3. Named Credentials lose their secrets on refresh — Named Credentials are copied to the sandbox but their passwords and OAuth tokens are blanked. Any integration that uses Named Credentials will fail silently until secrets are re-entered manually. There is no Apex API to set Named Credential secrets, so this step is always manual.
  4. SandboxPostCopy runs as Automated Process user, not an admin — The Automated Process user does not have access to all objects. DML against certain objects will throw a permissions error. Assign a permission set to the Automated Process user before the refresh if the class needs access to custom objects, or use System.runAs() in test coverage.
  5. Partial Copy template record counts are not exact — Salesforce follows parent lookups to maintain referential integrity, which can pull in significantly more records than the template cap specifies. Template counts are a request, not a hard limit.

Output Artifacts

ArtifactDescription
Refresh readiness checklistPre-refresh and post-refresh checklist covering interval, template, SandboxPostCopy registration, and manual runbook steps
SandboxPostCopy Apex classGlobal Apex class implementing the SandboxPostCopy interface, registered in production for automated post-refresh configuration
Sandbox template recommendationList of objects and record count caps for a Partial Copy sandbox template aligned to the team's testing needs
Manual post-refresh runbookOrdered list of manual steps for credentials, Named Credentials, and external system configuration that cannot be automated

Package files