Skip to content

Comments

fix(product): avoid loading all variants on scalar variant updates#14728

Open
avonian wants to merge 1 commit intomedusajs:developfrom
avonian:fix/variant-update-performance
Open

fix(product): avoid loading all variants on scalar variant updates#14728
avonian wants to merge 1 commit intomedusajs:developfrom
avonian:fix/variant-update-performance

Conversation

@avonian
Copy link

@avonian avonian commented Feb 9, 2026

What

Fixes mutation response performance for products with many variants (400+).

The problem

Multiple product sub-resource mutation routes (variant CRUD, option CRUD) use retrieveProductQueryConfig for the post-mutation refetchEntity call. This config includes *variants, *variants.prices, variants.prices.price_rules.*, *variants.options — loading ALL variants with all their prices, rules, and options after a single sub-resource change.

Profiling results on a product with 414 variants:

Operation Time
updateProductVariantsWorkflow 3.5s
refetchEntity with full product config 11min 51s
Total POST response 11min 54s

The admin dashboard already fetches variants separately via GET requests (using fields=-variants). The mutation responses don't need to include all variant data.

The fix

1. Lean product query config for sub-resource mutations

Added retrieveProductWithoutVariantsQueryConfig that filters out *variants and variants.* fields. Applied to these middleware configs:

  • POST /admin/products/:id/variants (create variant)
  • POST /admin/products/:id/variants/:variant_id (update variant)
  • DELETE /admin/products/:id/variants/:variant_id (delete variant)
  • POST /admin/products/:id/options (create option)
  • POST /admin/products/:id/options/:option_id (update option)
  • DELETE /admin/products/:id/options/:option_id (delete option)

2. Conditional allVariants loading in updateVariants_

updateVariants_() unconditionally loads all sibling variants with options for the checkIfVariantWithOptionsAlreadyExists validation, even when options aren't being updated. Moved the query inside the conditional so it only runs when options are present in the update payload.

Files changed

  • packages/medusa/src/api/admin/products/query-config.ts — add lean product config
  • packages/medusa/src/api/admin/products/middlewares.ts — use lean config for 6 sub-resource routes
  • packages/modules/product/src/services/product-module-service.ts — conditional allVariants loading

Impact

  • Sub-resource mutations no longer refetch all variants with prices
  • No behavior change for product-level GET/POST/DELETE routes
  • No behavior change for variant creation or option-changing updates in the service layer
  • Follow-up to fix(product): Update performance issue #14150 which fixed product update performance

Fixes #14727

@avonian avonian requested a review from a team as a code owner February 9, 2026 11:05
@changeset-bot
Copy link

changeset-bot bot commented Feb 9, 2026

⚠️ No Changeset found

Latest commit: da6b1f0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Feb 9, 2026

@avonian is attempting to deploy a commit to the medusajs Team on Vercel.

A member of the Team first needs to authorize it.

@avonian avonian force-pushed the fix/variant-update-performance branch from 36c2f94 to 7e5f8e2 Compare February 9, 2026 13:11
…ny variants

Two fixes for variant update performance on products with many variants:

1. product-module-service: `updateVariants_()` unconditionally loads all
   sibling variants (with options) to check for duplicate option combos,
   even when options haven't changed. Move the query inside the conditional
   so it only runs when options are present in the update payload.

2. Route middleware: the variant POST/DELETE routes use
   `retrieveProductQueryConfig` which refetches the full product with ALL
   variants, prices, price rules, and options after a single variant update.
   For products with 400+ variants this refetch alone takes 10+ minutes.
   Use a lean product config that excludes variant relations — the admin
   dashboard already fetches variants separately via GET.

Before: variant title update on product with 414 variants = 12+ minutes
After: ~3 seconds (workflow) + fast refetch

Fixes medusajs#14727
@avonian avonian force-pushed the fix/variant-update-performance branch from 7e5f8e2 to da6b1f0 Compare February 9, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Variant updates still slow for products with many variants (fix from #14150 not applied to variant path)

1 participant