Salesforce load testing data generation means producing dataset volumes and distributions that match production, not just schema-compliant records in small batches. A full sandbox with 500 accounts tells you nothing about how a trigger behaves against 2 million. If your load test data doesn't reflect production record counts, ownership skew, and related-object ratios, the test results are decorative at best and dangerously misleading at worst.
Most teams get this backwards. They spend weeks tuning Apex and flow logic, then load test against a dataset an order of magnitude smaller than what production actually holds. The org passes. Three weeks after go-live, a batch job that ran fine on 50,000 records starts timing out on 4 million, and nobody can explain why the sandbox never caught it.
Why Small-Scale Test Data Hides Real Problems
Governor limits and query performance don't degrade linearly. A SOQL query against an indexed field on 10,000 rows returns in milliseconds. The same query against 5 million rows, especially with a non-selective filter, can push past the 120-second query timeout entirely. That cliff edge doesn't show up until you're near production volume, which is exactly why undersized test data is worse than no test data — it creates false confidence.
Sharing calculations are another quiet failure point. Recalculating role hierarchy or group membership visibility is cheap on a few thousand records. On an account object with 3 million rows and a deep territory hierarchy, a single sharing recalculation job can run for hours and consume async Apex capacity that other jobs need. You only see this at scale.
Flow and trigger bulkification bugs follow the same pattern. Code that handles 200 records per batch (the standard Bulk API v2 batch ceiling) can still choke when a nightly integration fires 50 consecutive batches against a poorly indexed lookup field. Small test runs simply don't generate enough concurrent load to expose contention.
Matching Production Shape, Not Just Production Count
Volume alone isn't the whole story. A dataset with 2 million contacts evenly distributed across 10,000 accounts behaves nothing like production data where 80% of contacts sit under 5% of accounts. That skew is what actually breaks list views, rollup summaries, and sharing calculations in the real world.
SproutEzee reads your org's actual schema, including record type distributions, picklist frequency, and lookup relationship ratios, then generates data that mirrors those patterns at whatever volume you specify. If your production org runs 60% Enterprise record type and 40% SMB on the Opportunity object, your load test data should carry the same ratio, not a clean 50/50 split that never stresses the code paths your real users hit most.
Ownership distribution matters just as much. If three sales reps own 40% of all open opportunities in production (a pattern more common than most admins want to admit), your load test needs that same concentration to properly exercise sharing rules, queue assignment, and dashboard rollups tied to those owners.
Building the Dataset: A Practical Sequence
Start with the objects that drive the heaviest daily transaction volume, not the objects with the most fields. Opportunity, Case, and custom transactional objects usually matter more for load testing than reference objects like Product2 or Account, which change far less often.
Generate parent records first, then children, preserving the referential integrity your org actually enforces. A load test that creates 500,000 orphaned Order Line Items because the parent Order records weren't generated in the right sequence produces errors that have nothing to do with performance and everything to do with data setup mistakes.
- Map object load order by dependency, not alphabetically or by convenience.
- Set volume targets per object based on 12-month production growth trends, not current-day counts.
- Preserve picklist and record type frequency distributions pulled directly from production reporting.
- Stagger insert timing across objects to simulate realistic transaction pacing rather than one giant simultaneous load.
That staggering point deserves more attention than it usually gets. Real production traffic doesn't arrive in one burst. Spreading your load test inserts across a simulated business day, with peaks around known busy periods, surfaces contention issues that a single massive batch insert never will.
Bulk API v2 as the Delivery Mechanism
Bulk API v2 is the right tool for generating load-test volumes because it handles file splitting, batch queuing, and parallel processing without manual chunking. For load testing specifically, the goal isn't just getting records in fast — it's controlling the rate and shape of the load so it resembles what production traffic actually looks like.
That means sometimes you deliberately throttle throughput rather than maximizing it. A load test meant to validate steady-state performance under normal daily volume shouldn't blast 5 million records in 20 minutes if production never sees more than 200,000 records inserted in any given hour. Match the delivery rate to the scenario you're testing, whether that's peak Black Friday traffic or a routine nightly integration sync.
SproutEzee's Bulk API v2 integration lets you define both volume and pacing per generation job, so a load test can simulate a realistic 8-hour business day of record creation instead of one artificial spike that stresses the platform in ways your users never will.
What to Measure Once the Data Is Loaded
Raw insert speed is the least useful metric once your test data is in place. What matters is how the org behaves under query and transaction load once the volume exists. Track SOQL query time on your most-used list views and reports, not just on the objects you loaded.
Watch async Apex queue depth during and after the load. A spike in queued batch jobs that takes hours to clear tells you something real about your automation's scalability that a passing unit test never will.
| Metric | Why It Matters at Scale |
|---|---|
| List view load time | Reveals unindexed filter fields and poor query selectivity |
| Sharing recalculation duration | Exposes role hierarchy and group membership bottlenecks |
| Async Apex queue depth | Shows whether automation can keep pace with real transaction volume |
| Report run time on large objects | Flags aggregate queries that will time out in production |
I'd argue the sharing recalculation metric gets ignored more than any other on this list, mostly because it's invisible until it isn't. Teams discover it during a Sunday-night deployment window when a routine role change triggers a multi-hour recalculation nobody budgeted time for.
Building This Into a Repeatable Process
Load testing shouldn't be a one-time event before a major release. Data volume grows every quarter, and the performance characteristics that held up at 2 million records last year might not hold at 6 million this year. Building a repeatable pipeline for generating scaled, production-shaped test data means every major release gets tested against current reality, not last year's assumptions.
That repeatability is the actual value of tools like SproutEzee over manual data generation scripts. A one-off script that generates 2 million accounts is easy enough to write. Rebuilding it every quarter to match updated schema, new record types, and shifted distribution patterns is where manual approaches quietly stop scaling, right around the same time your org does.
Frequently Asked Questions
How much test data volume do I need for accurate Salesforce load testing?
Match your test data volume to projected production volume 12 months out, not current-day counts. If your org grows opportunity records by 20% annually and currently holds 3 million, test against 3.6 million or higher. Testing at current volume only confirms today's performance, which tells you nothing about the load your org will carry by the next major release.
Does Bulk API v2 support the throughput needed for large-scale load test data generation?
Yes, Bulk API v2 handles multi-million record loads by automatically splitting files into manageable batches and processing them in parallel. For load testing purposes you often want to control the pace rather than maximize raw throughput, since realistic traffic patterns matter more than sheer insertion speed. SproutEzee's Bulk API v2 integration lets you set both volume and pacing to match specific test scenarios.
Why does data skew matter more than data volume for load testing?
Even distribution across accounts and owners rarely matches how production data actually clusters. Real orgs typically show heavy concentration, such as a small number of accounts holding most contacts or a few sales reps owning most open opportunities. Testing against evenly distributed data misses the sharing recalculation and list view performance issues that concentrated ownership patterns actually cause.
Should load testing happen in a full sandbox or a scratch org?
Full sandboxes are generally better suited for load testing because they can hold the record volumes needed to simulate production scale, while scratch orgs have tighter storage and record limits. Scratch orgs work well for functional and unit testing within CI/CD pipelines but aren't built for multi-million record volume scenarios. Reserve scratch orgs for logic validation and use full or partial sandboxes for genuine performance and load testing.
What Salesforce metrics indicate a load test actually succeeded?
Look beyond insert completion time and check SOQL query performance on frequently used list views and reports after the data is loaded. Monitor async Apex queue depth for signs of automation backlog and track sharing recalculation duration, since that process often reveals scalability problems that other metrics miss. A load test that only confirms records were inserted successfully hasn't actually tested performance.