Sample Data and Fixtures
Install the Luma sample store, generate fixture data at real volumes, and stop testing against twenty products.
bin/magento setup:performance:generate-fixtures <path-to-profile.xml> [-s|--skip-reindex]These are two different things. Sample data is a demonstration shop: the Luma theme, categories, around 2,000 products, CMS pages and price rules, installed as Composer packages. Fixtures are generated volume — hundreds of thousands of rows produced from a profile, with no design intent at all.
Sample data
bin/magento sampledata:deploy edits the root composer.json and pulls the packages from repo.magento.com, so your authentication keys must already be in an auth.json. Follow it with setup:upgrade, then cache:flush and indexer:reindex. It will not install in production mode, and Adobe's own warning is the important part: sample data cannot be uninstalled. Put it on a database you are willing to throw away.
Fixtures
The performance toolkit generates data from an XML profile. The bundled Open Source profiles live in setup/performance-toolkit/profiles/ce: small is 800 simple products, 16 configurables, 30 categories, 200 customers and 80 orders; medium is 24,000 simple products; large 300,000; extra large 600,000. The ee profiles ship with Adobe Commerce only. Stop cron before generating, and reindex afterwards.
Why twenty products hide problems
Code that loads one product per iteration is instant over 20 rows and fatal over 300,000. A missing index, a collection with no page size, a loop over a whole category, a reindex that now takes forty minutes, layered navigation across EAV joins: none of it shows at demo size, and all of it shows the week after launch.
Example
<!-- setup/performance-toolkit/profiles/ce/dev-medium.xml - copied from small.xml -->
<config xmlns:xi="http://www.w3.org/2001/XInclude">
<profile>
<admin_users>5</admin_users>
<websites>1</websites>
<store_groups>1</store_groups>
<store_views>2</store_views>
<sources>1</sources>
<stocks>1</stocks>
<assign_entities_to_all_websites>0</assign_entities_to_all_websites>
<simple_products>20000</simple_products>
<configurable_products>
<config>
<attributes>
<attribute>
<options>3</options>
<swatches>image</swatches>
</attribute>
<attribute>
<options>8</options>
</attribute>
</attributes>
<sku>Configurable Product %s</sku>
<products>500</products>
</config>
</configurable_products>
<categories>300</categories>
<categories_nesting_level>3</categories_nesting_level>
<customers>2000</customers>
<catalog_price_rules>20</catalog_price_rules>
<cart_price_rules>20</cart_price_rules>
<cart_price_rules_floor>2</cart_price_rules_floor>
<coupon_codes>20</coupon_codes>
<product_attribute_sets>10</product_attribute_sets>
<product_attribute_sets_attributes>5</product_attribute_sets_attributes>
<orders>5000</orders>
<tax_rates_file>tax_rates_small.csv</tax_rates_file>
<xi:include href="../../config/attributeSets.xml" />
<xi:include href="../../config/searchConfig.xml" />
</profile>
</config>When to use it
- Get a storefront with real products and categories to build a theme against.
- Reproduce a slow category page by generating a catalogue the size of the client's.
- Measure how long a full reindex takes before promising a deployment window.
- Check that a new collection query still returns in time with 300,000 products.
More examples
Installing the Luma sample store
Run this on a throwaway install when you need a storefront that looks like a shop: product images, a category tree, CMS blocks and working price rules. The packages come from repo.magento.com, so the public and private keys from your Adobe account have to be in an auth.json, either in the project root or in your Composer home directory. Skipping setup:upgrade leaves the modules enabled but the data absent, which looks like a broken download.
# developer mode only; sampledata:deploy refuses to run in production mode
bin/magento deploy:mode:show
# edits composer.json and downloads the sample data packages
bin/magento sampledata:deploy
bin/magento setup:upgrade
bin/magento cache:flush
bin/magento indexer:reindexGenerating volume
The profile path is a required argument and takes a file, not a directory. Expect minutes for the small profile and hours for large, and expect the process to be writing to your database the whole time. Note that small.xml also switches several indexers to Update on Save, so check indexer:status afterwards rather than assuming your earlier settings survived.
# stop cron first; indexers and the generator fight over the same tables
bin/magento cron:remove
bin/magento setup:performance:generate-fixtures \
setup/performance-toolkit/profiles/ce/small.xml
# the same command, abbreviated - Symfony Console accepts any unambiguous prefix
bin/magento setup:perf:generate-fixtures \
setup/performance-toolkit/profiles/ce/small.xml
# -s is the short form of --skip-reindex, for when you want to reindex yourself
bin/magento setup:performance:generate-fixtures \
setup/performance-toolkit/profiles/ce/small.xml --skip-reindex
bin/magento indexer:reindexSnapshot before you commit to it
Take the snapshot while the install is still clean. This is the only practical undo for either kind of generated data, and it is also how you reset between performance measurements so that two runs start from the same rows. The cache flush matters because Magento has cached configuration that the restored database may no longer agree with.
# there is no uninstall for sample data or fixtures, so keep a way back
docker compose exec -T db \
mysqldump --single-transaction -uroot -pmagento magento > snapshot-clean.sql
# ... install sample data, generate fixtures, break things ...
docker compose exec -T db mysql -uroot -pmagento magento < snapshot-clean.sql
docker compose exec php bin/magento cache:flush
docker compose exec php bin/magento indexer:reindex
Discussion