ClearStock is live on the Shopify App Store.Install free →

← All blogs

Guides9 min read

How to restore prices after a sale on Shopify (without a manual cleanup)

Restoring prices after a Shopify sale: original price vs compare-at, why manual restoration fails at scale, a staged restoration routine, and what to log.

InventoryX is in development and not available today. ClearStock is the live Shopify app.

Restoring prices after a sale means putting the pre-sale number back in the price field, putting the pre-sale compare-at value back where it came from, and turning off whatever discount mechanism you used — in that order, on a schedule, with a record of what the values were. The reason it's a problem at all is that Shopify has no restore button: the sale price is simply the price now, and the only copy of the original may be in the compare-at field you overwrote.

Manual restoration works for a twelve-SKU weekend sale. It fails at three hundred SKUs across four collections, because restoration is a data problem with a deadline, and nobody owns it after launch day.

The two values that need restoring

Price. If you ran the sale by editing price, restoration is writing the original number back. If the sale lived in compare-at only (price unchanged, discount applied at checkout), nothing to restore — the discount object simply expires.

Compare-at price. This is the one people miss. It has two failure directions:

  • Left behind. You restore the price but compare-at still holds the original price, so the storefront now shows a struck-through $68 next to a $68 price. It may render as nothing (compare-at must be higher to display) or as a permanent, meaningless discount depending on the theme.
  • Overwritten. You used compare-at as the sale anchor, destroying whatever was there before — an MSRP, a previous anchor, or a deliberate blank. Restoration now has no source of truth for that field.

Add a third: any discount object still active. An automatic discount that outlives the price edit keeps discounting the restored price, which looks exactly like a restoration that failed.

Restore in the right order

Order matters because each step changes what the next one sees.

  1. Stop the discount mechanism. End or pause automatic discounts and expire codes. Do this first so test carts reflect the post-sale state.
  2. Restore price. Bulk edit or CSV import for the whole SKU list, from the record you exported before the sale.
  3. Restore compare-at. Put back the pre-sale value, including blanks. This is a separate column, separate decision.
  4. Publish and re-check markets. If you sell in several markets with price lists, confirm the change reached each one — the admin edit writes the base price.
  5. Verify with a guest checkout. Private window, guest, main market, one product per collection touched.
  6. Log the outcome. Realized units and contribution, so the next markdown isn't a guess.

Step 3 is skipped by roughly everyone, and it's the one that leaves a visible scar: a catalog that permanently advertises a discount that ended in the spring.

Where manual restoration breaks

  • The sale list changes mid-sale. SKUs added in week two are on sale but not on your original list; SKUs that sold out and were restocked have new inventory at the sale price. Restoration from a static list misses the first group and mis-prices the second.
  • Nobody recorded compare-at. The compare-at field is the only place the original price lived, and it's now holding the sale's anchor. Restoration overwrites it with the sale-time anchor and calls it done.
  • Partial restores. One person restores the collections they own. Two weeks later the catalog has two pricing regimes and the next sale's "original price" baseline is contaminated.
  • The sale becomes the price. After six to eight weeks, customers read the sale price as the price. Restoration looks like a price increase, and it gets reversed. This is where a markdown stops being a sale and becomes a repricing — a decision worth making explicitly rather than discovering in reviews.
  • Wholesale, B2B, and draft pricing. A B2B catalog or a set of price lists may hold its own prices. Restoring the storefront doesn't touch them, and vice versa.

Scheduled restoration

Since Shopify has no native price scheduler, scheduled restoration comes from one of four places, all of which need a human decision about who owns the schedule:

  • The same tool that ran the sale. Apps that write prices usually write them back. Test the restore path before you launch, on a single SKU: if the app restores the wrong value, that's much cheaper to learn on Monday than in December.
  • Shopify Flow, if the price action you need is available on your plan at the time of writing. Verify the action exists in your admin; capabilities change.
  • The Admin API. Most control and the most fragile handover: a script nobody else understands is a scheduled outage waiting for the person who wrote it to leave.
  • A calendar entry and a bulk edit. Unglamorous, and reliable when the export is attached to the reminder. For a store with two promotions a year, this is the correct amount of machinery.

The calendar itself — the fields worth recording per sale — is set out in scheduling sale prices and restoring on time. The short version: export before launch, keep the file, put the restore date in a calendar with the file attached.

The restoration checklist

# Check Why
1 Pre-sale export exists and is filed with the sale name The only complete record of prices
2 Pre-sale compare-at values captured separately The field is often overwritten by the sale anchor
3 Exact SKU list recorded, including late additions Static lists miss week-two additions
4 Automatic discounts ended, codes expired Otherwise restoration is discounted away
5 All markets and price lists checked, not just base Multi-market stores restore per market
6 Price restored in one pass, not per collection Partial restores hide
7 Compare-at restored (including deliberate blanks) Prevents a permanent phantom discount
8 Discontinued SKUs handled: archived, not restored Don't return a dead SKU to full price
9 Guest test order placed in each market The only end-to-end verification
10 Restoration logged with date and person Next quarter's audit starts here

Rows 8 and 10 are the ones that distinguish a cleanup from a process. A SKU that's being retired should be archived at its final price, not restored to a price it will never sell at again — and the log entry is what lets you answer "was this price on purpose?" six months later.

What to log, and why

A restoration log is short, and each field answers a question someone will ask later.

Field Answers
SKU / variant ID Which unit this is
Pre-sale price What it should return to
Pre-sale compare-at (or "blank") What the anchor should return to
Sale price and depth What the ladder actually ran
Sale window (dates, store timezone) Whether the price was legitimate for the period
Units sold during the window Whether the discount changed velocity
Contribution during the window Whether the discount was worth it
Restoration date and owner Accountability, and the audit trail
Post-sale price Whether the SKU returned to full price or was repriced
Post-sale action Restored, repriced, archived, or exited

The two contribution rows are the ones that turn a log into a strategy. Units sold tells you the discount worked on volume; contribution tells you whether working on volume was worth it. A markdown that tripled units and halved total contribution is a failed markdown, and the only way to know is to have written both numbers down while they were current.

Preventing the next cleanup

Three habits, in descending order of leverage:

  • Store the original price somewhere that isn't the compare-at field. A metafield, an exported CSV, or a spreadsheet column — any of them survive a sale anchor. Compare-at is a display surface, and display surfaces get overwritten.
  • Keep a sale ledger with one row per SKU per sale. It's five minutes at launch and it's the entire restoration source of truth.
  • Make restoration part of the campaign, not an aftermath. The sale isn't finished when it ends; it's finished when the prices are back and verified. Put that in the campaign doc and nobody has to remember it in February.

At scale, this is the argument for running markdowns through something that owns both directions of the price edit. ClearStock sets markdown prices from product status, runway, or velocity and restores the original price when the product recovers or the run is reverted, which turns restoration from a project into a side effect. For a couple of promotions a year, the ledger and the calendar are enough — and cheaper to maintain than a tool you use twice.

Common questions

How do I restore original prices after a sale on Shopify? Re-import the product CSV you exported before the sale, or use the bulk editor with a recorded price column. End any automatic discounts first, restore price in one pass, then restore compare-at separately, and verify with a guest checkout in each market.

Does Shopify restore prices automatically? No, at the time of writing. There's no native restore for product prices — scheduling and restoration come from apps, Flow where the action exists on your plan, or the API. If you edited prices for a sale, restoration is a task you have to own.

What happens to the compare-at price after a sale? Whatever you leave there. If it still holds the pre-sale price, the storefront may show a struck-through anchor on a full-price product; if you overwrote it for the sale, the original value is gone unless you recorded it. Restore it as a separate step.

Should I restore prices on products that didn't sell? Yes — a sale that ends is a sale that ends. But if the SKU is past its exit point, don't restore it to full price: archive it or move it to a liquidation path. Restoring dead stock to full price just restarts the clock.

How do I know restoration worked? Place a real guest order in a private window in each market and check three things: the product page price, the compare-at display, and the cart total. The admin shows what's stored; only the checkout shows what's true.

Next step: if a sale is live right now, export the product CSV immediately — even mid-sale, it's better than nothing, and you can reconstruct the original from compare-at. Then write the restore date, the owner, and the file name into one line of your campaign doc. That line is the whole difference between a restoration and a cleanup.