FEFO Is a Sequence, Not a Rule — and the Shelf Does Not Enforce It
First-expiry-first-out is one sentence in a procedure manual and three different events in a working pharmacy: what the system proposes, what the person confirms, and what the hand takes off the shelf. Only one of those is enforceable in software, and knowing which one you are relying on is the whole of the discipline.
It is four in the afternoon, there are six people waiting, and the shelf has three boxes of the same syrup. One expires next month, one in June, one has no date printed anywhere the assistant can see without opening the carton. The rule says take the first. The rule has no opinion about the queue, and the box at the front of the shelf is the one that arrived on Tuesday.
Every pharmacy says it operates FEFO. Almost every one of them means it sincerely. The gap between saying it and doing it is not honesty and it is not training — it is that first-expiry-first-out is not a rule anything enforces. It is a sequence, and a sequence is only as good as the three separate moments where somebody or something decides what comes next.
Three places the sequence gets decided
Write out what actually happens between a prescription and a box leaving the premises and you find three decision points, with very different properties.
| The moment | Who decides | What can be proved afterwards |
|---|---|---|
| The proposal | The software, by ordering the available batches and putting one first. | Everything. The ordering is deterministic and you can reproduce it from the same data on any afternoon. |
| The confirmation | The person at the counter, who accepts the proposal or picks a different batch. | Which batch was chosen. Not why, and not what was proposed instead. |
| The hand | Physics and shelf layout. The box in front is the box that gets picked up. | Nothing at all, unless the code on the box is scanned. |
Most FEFO failures live in the third row, and almost every FEFO conversation is about the first. A system can order batches perfectly and still watch newer stock walk out the door, because the ordering was a suggestion on a screen and the shelf was a physical object with a front and a back.
A sequence proposed on a screen and a box reached for on a shelf are two different events. The only thing that binds them together is a scan.
What "earliest expiry first" means once a computer is doing it
The phrase sounds unambiguous until you have to write it down. Here is the ordering our allocator actually applies, stated exactly, because the details are where the surprises are.
- Earliest expiry date first. The primary sort, ascending, across every batch of that item that is available at the location you are issuing from.
- Undated stock goes last. A batch with no expiry recorded is sorted as though it expires in the year 9999. This is deliberate: if you have not told the system when something expires, it will not let that silence jump the queue ahead of stock you did date.
- Ties break toward the larger holding. Two batches expiring on the same day, and the one with more units on hand is drawn first. That is a consolidation preference — it leaves you with fewer part-open locations rather than a scatter of remnants.
- Only available stock is considered. Anything quarantined, damaged, reserved, in transit or flagged as expired is not in the candidate set. A hold is a real exclusion, not a warning label.
Those four lines are the whole of the policy, and there is no per-item exception to them. If an item carries batch expiry dates, its issues are ordered this way — you do not opt one product out of the sequence because it happens to be inconvenient.
The property worth understanding before you shortlist anything
A sort that ranks the earliest expiry first ranks an already expired batch first of all — an expired date is the earliest date there is. In our allocator the guard against that is not in the sort, it is in two other places: a batch moved to a non-available status leaves the candidate set entirely, and the scan path refuses a lot whose date has passed, testing the date itself rather than trusting a status. So a scanned issue is protected by the date. A typed issue is protected by whoever last reviewed the statuses. Ask every vendor you talk to which of those two their protection is, because the answer is rarely the same in both workflows and it is almost never on the slide.
The override is a feature, and it should stay one
Our checkout screen defaults to Auto (FEFO) and lets the person choose a specific batch instead. It would be trivial to remove that dropdown, and it would be wrong.
Why the override has to exist
- A customer is on a course of treatment and the pharmacist wants continuity of batch, which is a clinical judgement software has no standing to overrule.
- The earliest-expiry batch is physically at another branch, or behind a locked door, or in a carton somebody has already opened for a different purpose.
- A recall notice has arrived and the affected batch has not yet been put on hold, so the person at the counter knows something the record does not.
- The date on the box and the date in the record disagree. The box wins, every time, and somebody then has to fix the record.
What the override costs you
- The batch chosen is recorded. The fact that it was not the proposed one is not. Nothing labels the movement as a departure.
- There is no report counting how often the proposal was declined, by item, by person or by branch — the raw material exists in the movement records, the report does not.
- A habit forms silently. One override a week is judgement; forty a week is a workaround for a shelf problem, and only the second one shows up in your expiry bands.
- If overriding is faster than finding the right box, people will override. That is not a discipline failure, it is a shelf layout failure wearing a discipline costume.
What gets written down when stock moves
Whatever was decided, the movement is recorded as a real row rather than a decrement of a total. Each allocation carries the batch, the direction, the movement type, the document that caused it and a reference — so "which batch went out on that sale" is a question with an answer, not a reconstruction.
That matters twice. Ordinarily it is how you close an expiry investigation: you find a batch that should have gone months ago and you can see exactly what went out instead. Exceptionally it is how you handle a recall, when the question is not statistical but specific — this batch, these movements, this list.
One item, one afternoon, four issues (illustrative figures)
Round numbers, chosen so you can follow them. The point is the last clause: the system can tell you Batch B moved on Issue 2, and it cannot tell you that Batch A was the one it offered. Reconstructing that means comparing what was on hand at that moment against what was taken — possible, and not a report you have.
What is built here, and what is not
Stated as a ledger rather than as prose, because this is the part a buyer should be able to lift straight into a comparison.
Running in the product today
- FEFO ordering at the point of issue, applied by the allocator rather than reported on afterwards — earliest expiry first, undated stock last, ties to the larger holding.
- Holds are exclusions. Quarantined, damaged, reserved, in-transit and expired-flagged stock is not offered for issue at all.
- The scan path refuses a past-dated lot by date, independently of whether anybody has updated its status.
- A deliberate override at checkout, defaulting to the FEFO proposal with the item's batches selectable underneath.
- Every movement records its batch, with direction, movement type, source document and reference — so recall and expiry investigations query rather than reconstruct.
Absences — on the roadmap, and commissionable now
- No override is flagged as an override. The chosen batch is recorded; nothing marks it as a departure from what was proposed.
- No FEFO adherence report. There is no by-item, by-branch or by-person view of how often the proposal was declined, so a drift in habit will surface in your expiry bands before it surfaces anywhere else.
- No shelf-position or pick-location guidance. The system can tell somebody which batch to take. It cannot tell them where on the shelf it is, and the third decision point in the table above is the one software reaches least.
What we would decline, and would rather say now
- We will not remove the override. A pharmacist has grounds for choosing a batch that software cannot see, from continuity of treatment to a recall notice that arrived this morning. A system that made the sequence unbreakable would be overruling a licensed judgement on the strength of a sort order.
- We will not present the movement record as proof of adherence. It proves which batch left. Whether that was the right batch is a comparison against what was available at that moment, and we would rather say that plainly than let a traceability report be read as a compliance report.
The three absences are absences rather than positions, and each is commissionable now on a written specification, a timeline and a price agreed before any money moves. The evidence that this is a real offer rather than a sales line is Kenya, where the eTIMS transmission and the maintained statutory payroll engine both exist because clients needed them and paid for them. We will not print a date on a blog post.
Read the split this way. The proposal is strong and the adherence measurement is not built — the product will reliably put the right batch in front of the person, and it will not tell you how often they took a different one. If your counter scans, that gap is narrow. If your counter types, it is the gap that matters most.
What to actually do about it
None of this requires a project. It requires deciding which of the three decision points you are going to defend, and defending that one properly.
Five things worth doing before you change any software
- Find out whether your counter scans or types. This single fact determines which protection you have, and most owners guess wrong about their own busiest hour.
- Walk the shelf and look at which box is at the front. If the newest delivery is the easiest to reach, the sequence is being lost at the shelf and no system change will recover it.
- Pick your ten fastest-moving lines and check that every batch of them has an expiry date recorded. Undated stock sorts last on purpose, which is safe — and it also means a genuinely urgent batch can hide behind a blank field.
- Review your hold statuses once a month rather than only when something goes wrong. In a typed workflow, the status is the guard.
- Count your overrides by hand for one week. Not to discipline anybody — to find out whether you are looking at judgement or at a workaround.
The last one usually settles the argument. A pharmacy that overrides twice a week has a working sequence and a couple of clinical exceptions. A pharmacy that overrides thirty times a week has a shelf problem, a layout problem or a stock-location problem, and the FEFO discussion was never the real one.
Which is the honest summary of the whole subject: FEFO is not a feature you buy, it is a sequence you defend, and software's contribution is to make the right choice the default and the wrong choice visible. We have done the first properly. The second is a report we have not built, and you should know that before you sign anything rather than after.
Bring one fast-moving item and one afternoon of issues
We will walk the three decision points against your actual process and show you which one is carrying the weight. If your current system already binds the proposal to the scan, we will tell you that and you can stop reading vendor pages.
Talk to us about pharmacy operations