Critical Performance Degradation: Cart Transform Latency (8s+) on POS during Peak Hours for High-Volume Merchants

Issue Summary

Our POS extension experiences severe performance degradation during peak hours. Add-to-cart operations that normally take 1-2 seconds increase to 5-8 seconds during busy periods. Force-closing and restarting the Shopify POS app temporarily restores normal performance.

Performance Comparison

  • Off-peak: 1-2 seconds per add-to-cart
  • Peak hours: 5-8 seconds per add-to-cart (and sometimes up to 15 seconds)
  • After POS app restart: Returns to 1-2 seconds (then degrades again)

Supporting Evidence

Please see the following screen recordings demonstrating:

Normal performance

(1-2s, 3 API calls completing quickly) during off-peak hours

Degraded performance

(5-8s, each API call taking longer) during peak hours - these are from two different merchants:

Example 01:

Example 02:


Current Implementation: Sequential API Calls

We currently use the standard sequential approach for adding items to the cart:

// Step 1: Add the line item
const uuid = await shopify.cart.addLineItem(
  Number(variantId),
  quantity
);

// Step 2: Add line item properties
await shopify.cart.addLineItemProperties(
  uuid,
  lineProperties // includes _modifierVariants, _order_type, etc.
);

// Step 3: Update cart properties
await shopify.cart.addCartProperties(mergedCartProperties);

Current Approach Characteristics

  • 3 sequential API calls per add-to-cart operation
  • 2-3 Cart Transform executions (triggered after each cart mutation)
  • Race condition potential between calls (properties added after initial line item)
  • Each API call must complete before the next begins

Optimized Cart Transform Function

Our Rust Cart Transform function is optimized with:

  • Early exits to skip unnecessary processing
  • Pre-allocated vectors with capacity hints
  • Cached attribute lookups to avoid repeated HashMap access
  • Minimal string allocations using Cow<str>
// Early exit if no processing needed
fn should_process(cart: &input::InputCart) -> bool {
    let referrer = cart.referrer.as_ref().and_then(|a| a.value.as_ref());
    referrer.is_some()
}

// Parse modifiers with early returns
fn parse_modifier_variants(line: &input::InputCartLines) -> Vec<ModifierVariant> {
    let value = match line.modifier_variants
        .as_ref()
        .and_then(|attr| attr.value.as_ref()) {
        Some(v) => v,
        None => return vec![],
    };
    
    if value.is_empty() {
        return vec![];
    }
    
    serde_json::from_str::<Vec<ModifierVariant>>(value).unwrap_or_default()
}

Key Observations

  1. Time-based pattern: Fast in morning, degrades throughout the day during peak hours
  2. Affects all locations and devices (multiple iPads at different sites)
  3. App restart fixes it temporarily: Suggests memory/state accumulation in POS app
  4. General Shopify POS sluggishness: Users report overall Shopify POS slowness during same periods (not just our extension)
  5. Same code, different performance: Identical code runs fast off-peak, slow during peak
  6. Multiple Transform executions: Each of our 3 API calls may trigger a Cart Transform, compounding latency

Performance Breakdown

Off-Peak (Normal)

  • Total: 1-2 seconds
  • addLineItem: ~400-600ms
  • addLineItemProperties: ~400-600ms
  • addCartProperties: ~200-400ms
  • Cart Transform (2-3x): Unknown execution time

Peak Hours (Degraded)

  • Total: 5-8 seconds
  • Each API call appears significantly slower
  • Cart Transform executions may also be slower
  • Compounding effect with sequential calls

Business Impact

  • Peak hours = 60-70% of daily revenue
  • Staff must wait 5-8 seconds per item during lunch/dinner rush
  • Each add-to-cart requires 3 sequential API calls + multiple Cart Transform executions
  • Reduced order throughput during critical business periods
  • Staff resorting to app restarts multiple times per shift
  • Customer satisfaction impacted by slow service

What We Need

Immediate Questions

  1. Is this a platform-level performance issue during peak load?
  2. Is this a POS app memory/state management issue?

Guidance Requested

  • Recommendations for improving performance with our current approach
  • Best practices for Cart API usage during high-load scenarios
  • Whether atomic cart updates would be more resilient during peak periods

Context: Why We Use This Approach

We currently use the sequential approach because:

  1. It’s the documented standard pattern for adding line items with properties
  2. We need to attach custom properties (including _modifierVariants JSON for Cart Transform)

We’re open to refactoring if a different approach would solve the peak-hour performance issue.


Technical Details

  • Platform: Shopify POS (iOS/iPad)
  • Extension Type: POS UI Extension (Preact) + Cart Transform Function (Rust)
  • API Version: 2025.10.x
  • Cart Transform: Expands line items based on _modifierVariants property
  • Current Pattern: addLineItemaddLineItemPropertiesaddCartProperties
1 Like

thanks @adamwooding for the detailed post

i can also +1 for our extensions we have received reports from our baristas:

  • long waiting times for simple fetchProductWithId (or just outright failing)
  • long waiting time for addLineItem and/or applyCartDiscount, setCustomer
1 Like

Hey folks - thanks for flagging, we’re looking into this now.

1 Like

Hi @adamwooding & @Gunes

Is this performance issue something you’ve only recently started experiencing, or has it been observed for a while? Have you considered using the bulkCartUpdate API?

hey @Liam-Shopify, my calls are not chained, just single calls.

the first report from the baristas came in at Jan 16th, but the initial report was it happens 1-2 times per hour where the product details do not load, so they’d have to close the app and open it again.

but again, i don’t have any chained calls.

Hey @Liam-Shopify, thank you for your time and help with this.

With regards to your questions:

Timeline: Past 3-4 weeks have been significantly worse (similar to @Gunes’s Jan 16th timeline), though we’ve actually had intermittent issues for several months. We have unfortunately lost some merchants to other platforms due to the intermittent slow issues.

bulkCartUpdate: Yes, we’ve already implemented it! Single atomic call with client-generated UUIDs. Works great off-peak (1-2s), but still degrades to 5-8s during peak hours.

I think that since @Gunes is also seeing issues with single, non-chained calls (fetchProductWithId, etc.), could suggest that this might be a platform-wide performance issue rather than something specific to our call patterns.

Thank you very much for your help and support @Liam-Shopify :folded_hands:t5: