SfSkills Domains Docs GitHub

Home / data / sandbox-refresh-data-strategies

sandbox-refresh-data-strategies

Use this skill when designing data strategies for sandbox refreshes: which reference data must be re-seeded after every refresh, the native Data Seeding feature, SandboxPostCopy implementations that hand off to Queueable jobs for large data loads, and clearing stale data between sprints.

Open the skill folder on GitHub


Sandbox Refresh Data Strategies

Use this skill when designing the data management layer for sandbox refreshes — specifically the strategy for re-seeding reference data after a refresh, using Salesforce's native Data Seeding feature, and implementing SandboxPostCopy for automated post-refresh data population. Distinct from sandbox-refresh-and-templates (which covers refresh mechanics and PII masking) and data-seeding-for-testing (which covers scratch org and CI seeding).


Before Starting

Gather this context before working on anything in this domain:


Core Concepts

SandboxPostCopy Interface and Its DML Limitations

The SandboxPostCopy Apex interface provides a runApexClass(SandboxContext context) method that runs immediately after sandbox creation or refresh, as the Automated Process user. This user has DML capability but operates under specific constraints:

The canonical anti-pattern is attempting large DML directly inside runApexClass — this times out for datasets exceeding a few hundred records per object.

Native Salesforce Data Seeding Feature

Salesforce provides a native Data Seeding feature (accessible in Setup > Data Seeding) that supports three template types:

  1. Nodes: Seed specific records from selected objects individually
  2. Levels: Seed records up to a defined relationship depth (parent → child hierarchies)
  3. Generate: Create synthetic test data matching field-level data types

Key capabilities:

Native Data Seeding does NOT support these object types:

For unsupported object types, use SFDMU, Apex scripts, or Data Loader instead.

Reference Data Classification

Not all data must be re-seeded after every refresh. Reference data falls into categories:

  1. Must seed every refresh: Configuration tables that control application behavior (Custom Settings if not deployed via script, territory hierarchies, product category trees, approval chain configuration objects)
  2. Seed on initial setup only: Master data that rarely changes (country/region codes, currency codes)
  3. Never seed: Transactional data (Cases, Opportunities, Orders) — these are test artifacts that should be generated by test scripts, not pre-seeded

Common Patterns

Pattern: SandboxPostCopy with Queueable Delegation

When to use: Any time more than ~100 records per object need to be seeded post-refresh.

How it works:

global class PostRefreshSeedHandler implements SandboxPostCopy {
    global void runApexClass(SandboxContext context) {
        // Only enqueue — never do large DML here
        if (!Test.isRunningTest()) {
            System.enqueueJob(new SeedReferenceDataQueueable());
        }
    }
}

The SeedReferenceDataQueueable class chains additional Queueables if needed (Salesforce allows up to 50 chained Queueable jobs). Each Queueable processes one object or a manageable batch.

Why not DML in SandboxPostCopy directly: Large DML in the SandboxPostCopy method causes the refresh completion step to time out, resulting in a failed or incomplete seeding with no clear error.

Pattern: Native Data Seeding Template for Reference Objects

When to use: Reference object data is stable enough to be defined once and re-used across all sandbox refreshes without code.

How it works:

  1. In production or a reference sandbox, navigate to Setup > Data Seeding.
  2. Create a seeding template selecting the reference objects and record criteria.
  3. Choose template type: Nodes (specific records) or Levels (with children).
  4. Assign the template to sandbox environments that need this data after refresh.
  5. Configure the seeding to run automatically on sandbox creation/refresh.

Why use Data Seeding over scripts for stable reference data: Data Seeding handles automation-disable automatically, supports incremental updates, and requires no Apex deployment. For stable reference data, it is lower maintenance than custom scripts.


Decision Guidance

SituationRecommended ApproachReason
< 100 records, simple objectSandboxPostCopy with direct DMLSmall datasets are safe within the method timeout
> 100 records or complex parent-child hierarchySandboxPostCopy → Queueable delegationDirect DML in SandboxPostCopy times out for large datasets
Stable reference data, no Apex team neededNative Data Seeding templatesNo code; handles automation-disable; incremental updates
ContentDocument or Big Object seeding neededSFDMU or Data Loader post-refresh stepNot supported by native Data Seeding
Stale transactional data cleanup between sprintsSeparate cleanup Queueable or Data Loader delete jobTransactional data should not be pre-seeded

Step-by-step instructions for an AI agent or practitioner working on this task:

  1. Classify reference data — Identify which objects must be seeded after every refresh (application configuration) vs. objects that should never be pre-seeded (transactional test data).
  2. Assess data volume per object — Count the records that must be seeded. Objects over ~100 records require Queueable delegation; very large sets may need native Data Seeding or SFDMU.
  3. Check native Data Seeding eligibility — Confirm the objects are supported by native Data Seeding (not Big Objects, Files, Chatter, external objects).
  4. Design the SandboxPostCopy class — Write a minimal runApexClass that only enqueues the seeding Queueable. All actual DML lives in the Queueable(s).
  5. Build Queueable chain — Implement SeedReferenceDataQueueable that processes one object per execution, chains to the next Queueable for the next object.
  6. Configure automation disable — For objects with active triggers or flows, add logic to disable automations before seeding (or use native Data Seeding which handles this automatically).
  7. Test the full refresh cycle — Refresh a Developer sandbox, confirm seeding runs automatically, verify all reference data is present and valid.

Review Checklist

Run through these before marking work in this area complete:


Salesforce-Specific Gotchas

  1. SandboxPostCopy large DML times out — Running DML for hundreds or thousands of records directly inside runApexClass causes the post-copy step to time out, leaving the sandbox seeded incompletely with no clear failure message. Always delegate large seeding to a Queueable.
  2. Native Data Seeding does not support Big Objects, Files, or Chatter — These object types silently fail in Data Seeding templates. Use SFDMU or Apex scripts for these types.
  3. SandboxPostCopy runs as Automated Process user — This user is not a named user and does not appear in audit logs as a standard user. Org-wide sharing rules apply, but profile-based field-level security does not. Be aware that seeded records may have visibility behavior that differs from named user-created records.
  4. Automations fire on seeded records by default — Without explicit automation disable logic, triggers and flows execute on seeded records. This can cause unwanted data changes, platform event publishing, or email sends. Use native Data Seeding's automation-disable feature or write explicit disable/enable logic.

Output Artifacts

ArtifactDescription
Reference data seeding strategyClassification of objects by seed frequency with rationale
SandboxPostCopy classMinimal class that enqueues the seeding Queueable
Seeding QueueableQueueable chain handling all large-volume reference data seeding
Native Data Seeding template planObject selection, template type, and automation settings

Package files