Launch pricing: Lock in Pro at $79/yr before prices go up View pricing →

FEFO vs FIFO: pick the right stock rotation for dated goods

If you sell anything with a date stamped on it, the way you rotate stock decides how much of it you write off. The two methods that get confused are FEFO and FIFO. They sound interchangeable, and on a good day they behave identically — but the day they diverge is the day good stock expires on your shelf. This guide defines both clearly, shows where they differ in a side-by-side table, and explains when each one is the right call.

FEFO and FIFO, defined

FIFO — First In, First Out rotates stock by arrival order. The oldest-received units ship first. It is the default mental model for almost every warehouse: put new stock behind old stock, pick from the front.

FEFO — First Expired, First Out rotates stock by expiration date. The unit closest to expiring ships first, no matter when it arrived. The pick order follows the date on the box, not the date it landed in your receiving bay.

The crucial word is assumption. FIFO assumes the oldest stock is also the soonest to expire. For undated goods that assumption always holds. For dated goods it often holds — and then occasionally, expensively, it doesn’t.

FEFO vs FIFO: side-by-side

FIFO (First In, First Out)FEFO (First Expired, First Out)
Rotates byArrival dateExpiration / best-before date
Ships firstOldest received unitSoonest-to-expire unit
Needs expiry dates?NoYes
Needs batch/lot tracking?NoYes
Best forUndated goods, raw materialsFood, supplements, cosmetics, pharma
Risk if used on dated stockShort-dated stock left behind → write-offs— (this is the safe choice)
Per-order lot recordLimitedEach order records the batch it shipped

When FIFO is the right choice

FIFO is not wrong — it is simpler, and for the right inventory it is all you need. Use FIFO when:

  • Your products don’t have expiration dates at all (hardware, fasteners, apparel, most raw materials).
  • Age matters only for quality drift, not safety, and stock always degrades in arrival order.
  • You want the lowest operational overhead — FIFO needs nothing more than disciplined shelving.

For undated stock, layering FEFO on top adds work without adding protection. There’s no date to rotate by, so “first expired” is meaningless.

Why FEFO wins for dated stock

The moment a product carries an expiration, best-before, use-by, or PAO date, FIFO’s core assumption can break. Here’s the classic failure: you have 60 units on the shelf that expire in May. A new delivery arrives — but because of a longer time in the supplier’s warehouse, it expires in March. Under FIFO you’d ship the May stock first (it arrived first) and the March stock sits behind it, quietly counting down to its date. By the time you reach it, it’s expired. That’s a write-off you created by rotating on the wrong field.

FEFO closes the gap. It ignores arrival order and always reaches for the March stock first, because March is sooner. The same logic protects you across every category of perishable and regulated goods — and it’s why food, supplement, cosmetic, and pharmacy stores standardise on it. (For a worked example in regulated goods, see supplement expiry and lot tracking.)

There’s a second payoff beyond waste: a per-order record of what you shipped. Because FEFO is built on batches, each order records exactly which lot it came from — useful when you need to know which customers received a specific batch.

How to run FEFO in WooCommerce

Here’s the catch for store owners: core WooCommerce can’t do FEFO. It tracks one stock number per product, with no expiration dates and no batches, so it has no idea which units expire first. Out of the box, WooCommerce can’t even do strict FIFO on dated stock — it has no date to rotate by.

You add the missing pieces with the Sellinor Product Expiration Dates Pro add-on, which turns each product’s stock into dated batches and rotates them automatically.

Step 1: Track stock as batches, not one number

The free plugin gives every product a single expiration date and can hide it or set it out of stock when that date passes. FEFO needs more granularity, so the Pro add-on lets you record each delivery as a separate batch with three things:

  • a quantity,
  • an expiration date, and
  • an optional batch reference / lot number for your records.

A single SKU can hold several open batches at once — 40 units expiring in March, 60 in May — and the product’s sellable stock is kept in sync with the sum of those batches automatically. Full setup is in batch and lot tracking.

Step 2: Let the plugin deduct the first-expiring lot

This is the FEFO part, and it runs on every order with no manual picking. When an order comes in, the plugin finds the batch with the earliest expiration date that still has stock and deducts from it first, only moving to the next-earliest batch when one is exhausted. You never accidentally ship May’s stock while March’s sits there.

It holds up under real-store messiness:

  • The exact batches used are recorded on the order, so you always know what shipped.
  • Refunds and cancellations return units to the correct batch instead of inflating a generic stock count.
  • If a batch passes its date, it stops counting as sellable stock (unless you deliberately opt to keep selling expired batches — see expiry actions).
  • If an order needs more units than your batches can supply, it’s placed on hold with an order note rather than overselling stock you don’t physically have.

Step 3: Pair it with automatic expiry actions

FEFO moves your stock in the right order; expiry actions catch what doesn’t move in time. The free plugin can automatically hide an expired product or set it out of stock — and trigger that a set number of days before the date, giving you a buffer. Combined, the soonest-to-expire stock always sells first, and anything that still reaches its date is pulled from sale before a customer can buy it.

The short version

FIFO rotates by arrival; FEFO rotates by expiry. For undated goods they’re effectively the same and FIFO is simpler. For anything with a date on it, FEFO is the method that actually prevents write-offs — and the only way to run it properly in WooCommerce is with per-batch dates and automatic first-expired deduction. If that’s your inventory, the FEFO setup guide walks through it end to end.

Frequently asked questions

What is FEFO?

FEFO stands for First Expired, First Out. It is a stock-rotation method where the unit closest to its expiration or best-before date is picked, sold, or shipped first — regardless of when it arrived in your warehouse. For any product with a date on it, FEFO is the correct method because deliveries do not always arrive in date order.

What is FIFO?

FIFO stands for First In, First Out. It rotates stock by arrival order: the oldest-received units leave first. FIFO assumes the oldest stock is also the closest to expiring, which is true for undated goods but not always for dated ones, since a newer delivery can carry a shorter shelf life.

What is the difference between FEFO and FIFO?

FIFO sells the oldest-received stock first; FEFO sells the soonest-to-expire stock first. They produce the same result only when every delivery arrives in expiry order. When a later delivery has a shorter shelf life than stock already on the shelf, FIFO ships the wrong unit and the short-dated stock gets left behind — which is exactly how dated goods end up as write-offs.

When should I use FEFO instead of FIFO?

Use FEFO whenever your products carry an expiration, best-before, use-by, or PAO date — food, supplements, cosmetics, pharmacy, and chemical stock. Use FIFO for undated goods where age is the only thing that matters, like raw materials or non-perishable hardware, where it is simpler to operate.

Does WooCommerce do FEFO out of the box?

No. Core WooCommerce tracks a single stock quantity per product with no expiration dates and no batches, so it has no concept of which units expire first. To run FEFO you need per-batch expiration dates plus a deduction rule that always picks the earliest-expiring batch, which the Sellinor Expiration Dates Pro add-on provides.

How does automatic FEFO deduction work on an order?

With batch tracking enabled, each product holds one or more batches, each with a quantity and an expiration date. When an order comes in, the plugin deducts the required units starting from the batch closest to expiring, moving to the next batch only when one runs out. The exact batches used are recorded on the order, and refunds or cancellations return stock to the correct batch.

Run true FEFO in WooCommerce

Track stock by batch with expiration dates and let WooCommerce deduct the first-expiring lot automatically on every order — no manual rotation.

See plans & download free

Or read the documentation.