Discount leakage as a share of revenue. Persistent >25% means the business depends on promos.
At a glance
Total discount given as a percentage of total revenue, an indicator of how much of your top-line is being given away to drive purchases. Sustained values above 25% indicate the business is structurally promo-dependent, a margin and brand risk.
| What it counts | SUM(totalDiscounts) ÷ SUM(totalPrice) × 100 over orders in the period. Note totalPrice is post-discount, so the ratio understates the discount-to-list-price share, more on this below. |
| API endpoint | Admin GraphQL. Order.totalDiscounts and Order.totalPrice. |
| VAT / tax treatment | Both numerator and denominator follow store tax setting consistently; ratio is tax-treatment safe. |
| Shipping | Shipping is in the denominator (totalPrice) but most discount-on-shipping is also captured in the numerator. The ratio is shipping-aware but skewed for stores running heavy free-shipping. |
| Discounts | The numerator IS discount value; obviously included. |
| Refunds | Refunds NOT deducted from either side. A heavily-refunded promo period shows the same discount % as the gross view. |
| Cancelled / voided orders | Included; cancelled orders contribute to both numerator and denominator. |
| Currency | Multi-currency: ratio works only within a single currency. Multi-currency stores see a meaningless arithmetic blend; filter to single presentment currency. |
| Channels / sources | Online + POS + B2B all contribute. POS price-adjustments at the till count as discounts (at-the-till discount can inflate the rate for retail-heavy brands). |
totalPrice is post-discount note | Important: because totalPrice already deducts discounts, this ratio understates true discount intensity. A 50% off sale shows here as 50/50 = 33% (not 50%). The true list-price discount % is discount / (revenue + discount); the displayed metric is discount / revenue-after-discount. Both views are useful but they answer different questions. |
| Time window | 30D (single window) |
| Alert trigger | >25%, sustained discount-to-net-revenue ratio above 25% indicates promo dependence |
| Roles | owner, marketing |
Calculation
Worked example
A US apparel brand on Shopify Plus. Period: 12 Apr 26 to 11 May 26.| Value | |
|---|---|
Total revenue (totalPrice) | $284,400 |
Total discount (totalDiscounts) | $86,200 |
| Computed: gross list price | $370,600 (revenue + discount) |
| Discount % (this card) | 30.3% (284,400) |
| List-price discount % | 23.3% (370,600) |
>25% sentiment threshold. Five things to notice:
- The jump is the alert. A move from 18% to 30% in 30 days is structural, not a single sale. Either a promo extended longer than planned, an evergreen-discount mechanic launched, or a margin-killing influencer code went viral. Cross-reference Top Discount Codes.
- 30% on this metric ≠ 30% off list. Because
totalPriceis post-discount, the intuition “everything is 30% off” is wrong. The list-price discount is 23.3%, still high but better than the headline. When communicating to non-technical stakeholders, explain both views. - Margin impact compounds. If gross margin is 60% (typical apparel), a 30% revenue-share discount means net margin drops from 60% × 222,360 to (60% - 23%) × 137,122. A $85k margin hit relative to a no-discount baseline. The card is a margin warning, not just a “the customer paid less” warning.
- Promo dependence has long-term costs. Brands that hover at 30%+ discount-to-revenue for 6+ months condition customers to wait for sales. AOV at full price drops, repeat rate becomes promo-anchored, and pulling the discount mid-year produces a worse drop than expected. The metric is a strategic-positioning canary.
- Channel mix can confound. A pop-up retail event with 20% staff-discount allocations, a B2B catalogue with standing 15% wholesale pricing, and DTC at full price all blend into one number. To filter B2B and staff out, use the per-channel breakdown in Shopify Admin (this card aggregates).
Sibling cards merchants should reference together
Discount % of revenue is a strategy alarm. Pair with these to find cause and fix:| Card | Why pair it with Discount % | What the combination tells you |
|---|---|---|
| Total Discount | The numerator. | Quantifies the £/$ promotional spend in absolute terms. |
| Total Revenue | The denominator. | A flat ratio with rising revenue and discount means discount $ growing in proportion; sustainable. A rising ratio with flat revenue means promos aren’t lifting top-line. |
| Discount Over Time | The timeseries view. | Tells you which days drove the high ratio. |
| Top Discount Codes | Which codes drove the spend. | Identifies the specific code(s) responsible. |
| AOV | AOV usually drops when discount % rises. | If AOV is flat or rising despite high discount %, the promo is broadening basket size; that is the rare healthy signal. |
| Repeat Rate | Customer behaviour vs promo intensity. | Healthy retention with low promo % = sustainable; declining retention with high promo % = the promos are poaching, not building loyalty. |
google_ads.google_promo_keywords | Paid search amplification. | High ratio + heavy paid-promo keyword spend = promo-CAC trap; the cost of acquiring promo-driven customers. |
Reconciling against the vendor’s own dashboard
Where to look in Shopify Admin: Shopify Admin does not have a single discount-as-share-of-revenue tile. Reconstruct from:- Reports → Discounts for the discount $ total
- Reports → Total sales for the revenue $ total
- Compute
discount / revenuemanually for the same date range
- Reports → Net sales: Shopify’s “net sales” report deducts discounts already; useful for comparing post-discount vs gross.
- Apps like Lifetimely: surface discount-share-of-revenue with margin overlay.
| Reason | Direction | Why |
|---|---|---|
| Time zone | Boundary days | Shopify uses store time zone; Vortex IQ uses store time zone for daily and UTC for window edges. |
totalPrice post-discount | Same on both | Both Shopify and the card use post-discount revenue as denominator. Use the list-price formula for the alternative view. |
| Refund timing | Either | Refunded orders pre and post-window are handled identically by both systems. |
| Channel filter | Either | Shopify can filter by sales channel; this card aggregates all channels. |
| B2B price catalogues | Both include | Both treat B2B catalogue discounts as discounts; some merchants would prefer to exclude wholesale. |
| Sync lag | Ours lower for “today” | 5 to 15 minute index lag. |
| Card | Expected relationship | What causes legitimate divergence |
|---|---|---|
google_ads.google_promo_keyword_share | Promo-keyword spend share correlates with this | Strong correlation in promo-driven brands; weak in brand-driven ones. |
facebook.fb_promo_creatives | Meta promo-creative spend share | Same logic, different channel. |
Known limitations / merchant FAQs
Why is my number higher than my “discount %”? BecausetotalPrice is post-discount. A 30% off promo applied to 70 paid + $30 discount, the card reads 30/70 = 43%, not 30%. The metric measures discount-as-share-of-net-revenue, not discount-off-list. Both views are useful; they answer different questions.
Is 25% a sensible threshold?
For most non-fashion DTC, yes. Fashion and beauty often run structurally at 20 to 35% promo intensity. Adjust the threshold to your industry baseline plus 5 ppt; that catches genuine moves rather than seasonal noise.
Are B2B and wholesale discounts counted?
Yes. The card aggregates across channels. A B2B-heavy store with standing 15% wholesale discount sees a permanently elevated baseline. Filter to DTC-only via channel filter (manual today; on roadmap) for clean retail-promo analysis.
What about staff and influencer discounts?
Counted. Both contribute to the numerator. If you want to isolate marketing discounts only, exclude staff / influencer codes via tag-based filtering (on roadmap as a configuration option).
Why does my Shopify number differ?
Most often, time zone or filter scope. Shopify uses store time zone for window edges; Vortex IQ uses UTC. Shopify reports can be filtered by channel; this card aggregates.
Multi-currency, any impact?
Yes, the ratio across mixed currencies is meaningless without FX. Filter to single presentment currency for accurate reads.
Shopify Plus vs basic?
Plus stores running Shopify Functions for custom discounts may not record some logic in the standard totalDiscounts field; in that case, the card under-reports. Audit Functions implementation if numbers seem too low.
Refresh cadence?
5 to 15 minute index lag. The 30-day rolling window updates each cycle.
The card alerted (>25%), what should I do?
- Open Discount Over Time. Find the days driving the rise.
- Open Top Discount Codes. Identify the responsible codes.
- Audit code expiry; an unintended-still-live code is the most common cause of a sustained rise.
- Check whether a campaign was extended without updating internal forecasts.
- Evaluate whether the discount is paying back: revenue lift vs margin hit. If margin damage outweighs revenue gain, plan exit.
- Long-term: build the brand-led narrative back; reduce promo dependence over 6 to 12 months by gradually replacing discounts with non-price levers (loyalty perks, exclusive access, content).