Our line-item script is working great, but getting persistent InstructionQuotaExceeded errors

Topic summary

A Shopify line-item script is applying tag-based bundle discounts, but it is running into persistent InstructionQuotaExceeded errors, suggesting the script exceeds Shopify Script execution limits. The code snippet is central to the issue.

Key details:

  • A custom Ruby class defines multiple discount campaigns such as “2 for $5” or “$10 when buying 4 or more.”
  • The script loops through cart line items multiple times, then through every campaign and every tag string, using substring tag matching to count qualifying items and later apply discounted line prices.
  • Discounts are calculated as a per-item price based on a campaign threshold and target bundle price.

The main concern is optimization:

  • The author suspects the nested loops are too expensive.
  • They ask for simpler or more efficient Ruby approaches to reduce instructions while keeping the same tag-based discount behavior.

No resolution is shown in the provided text; the question remains open.

Summarized with AI on March 5. AI used: gpt-5.4.

Any thoughts on how to optimize what we thought was a tidy solution to our need to discount products based on tagging? Better ways to simplify these nested loops we need to run? I’m very much a Ruby noob.

#object for lineitem campaigns
class XforYDollarsCampaign
  #array of strings that are substrings to search against product tags
  #int of threshold quantity, ex: 3 items to get the discount
  #cents of pricedAt when matching discount, ex: 1500 = $15.00, so per item will be 1500/3, so $5 per item purchased
  #discount message string
  #matchCount for iterating the cart
  attr_accessor :tagStrings, :threshholdQty, :pricedAt, :discountMsg, :matchCount

  def initialize(tagStrings, threshholdQty, pricedAt, discountMsg)
    @tagStrings = tagStrings
    @threshholdQty = threshholdQty
    @pricedAt = pricedAt
    @discountMsg = discountMsg
    @matchCount = 0
  end
end

CAMPAIGNS = [
  XforYDollarsCampaign.new(["2_for_5"],       2, 500,   "2 for $5"),
  XforYDollarsCampaign.new(["2_or_more_5"],   2, 1000,  "$5 when buying 2 or more"),
  XforYDollarsCampaign.new(["2_for_6"],       2, 600,   "2 for $6"),
  XforYDollarsCampaign.new(["2_or_more_6"],   2, 1200,  "$6 when buying 2 or more"),
  XforYDollarsCampaign.new(["2_for_7"],       2, 700,   "2 for $7"),
  XforYDollarsCampaign.new(["2_or_more_7"],   2, 1400,  "$7 when buying 2 or more"),
  XforYDollarsCampaign.new(["2_for_10"],      2, 1000,  "2 for $10"),
  XforYDollarsCampaign.new(["2_or_more_10", "10_dollar_2_or_more", "10_dollar_shoes_for_women"],   2, 2000,  "$10 when buying 2 or more"),
  XforYDollarsCampaign.new(["2_for_12"],      2, 1200,  "2 for $12"),
  XforYDollarsCampaign.new(["12_dollar_2_or_more"],      2, 2400,  "$12 when buying 2 or more"),
  XforYDollarsCampaign.new(["2_for_15"],      2, 1500,  "2 for $15"),
  XforYDollarsCampaign.new(["15_dollar_2_or_more"],      2, 3000,  "$15 when buying 2 or more"),
  XforYDollarsCampaign.new(["3_for_10"],      3, 1000,  "3 for $10"),
  XforYDollarsCampaign.new(["3_or_more_10", "10_dollar_3_or_more"],      3, 3000,  "$10 when buying 3 or more"),
  XforYDollarsCampaign.new(["3_for_15"],      3, 1500,  "3 for $15"),
  XforYDollarsCampaign.new(["15_dollar_3_or_more"],      3, 4500,  "$15 when buying 3 or more"),
  XforYDollarsCampaign.new(["10_dollar_4_or_more"],      4, 4000,  "$10 when buying 4 or more"),
  XforYDollarsCampaign.new(["5_for_10"],      5, 1000,  "5 for $10"),
  XforYDollarsCampaign.new(["10_dollar_5_or_more"],      5, 5000,  "$10 when buying 5 or more")
].freeze

line_items = Input.cart.line_items

#function findMatches (find and prep the matches, populate the CAMPAIGNS array with those lineitems)
#get qty amounts of products that match the tags
#puts ("Loozp em")
line_items.each do |line_item|
  CAMPAIGNS.each do |campaign|
    campaign.tagStrings.each do |thisTagString|
      #puts (line_item.variant.product.tags)
      if line_item.variant.product.tags.any? { |productTag| productTag.include?(thisTagString)  }
        campaign.matchCount += line_item.quantity
        #puts ("GOT ONE HOLY ■■■■ #{line_item.variant.product}")
      end
    end #end campaign.tagStrings loop
  end #end CAMPAIGNS loop
end #end sorted_items

#run that function, then cycle through the lineitems in cart again and price/message accordingly
line_items.each do |line_item|
  lineItemIsDiscounted = false
  CAMPAIGNS.each do |campaign|
    campaign.tagStrings.each do |thisTagString|
      #puts (line_item.variant.product.tags)
      if line_item.variant.product.tags.any? { |productTag| productTag.include?(thisTagString)  }
        #we have a match again, now check this campaign, 
        if campaign.matchCount >= campaign.threshholdQty
          perItemCents = campaign.pricedAt / campaign.threshholdQty
          #puts (perItemCents)
          updatedPrice = Money.new(cents: (perItemCents * line_item.quantity)) #set that price!
          if(updatedPrice < line_item.original_line_price)
            line_item.change_line_price(updatedPrice, {message: campaign.discountMsg}) #set that msg!
          end
          lineItemIsDiscounted = true
          break #stop cycling campaign strings, we have a winner
        end
      end 
    end
    if lineItemIsDiscounted
      break #stop cycling campaigns
    end
  end
  #continue to next lineitem
end

Output.cart = Input.cart