Key takeaways
A traceability system exists to answer two questions fast, under pressure, with numbers you can defend.
The model below works for batch processes (food, chemicals, compounding) and for discrete parts made from coil, bar or resin. For the difference between the two words, see batch vs lot production.
This page covers the lot side only. The order header, operations, BOM lines and quantity reports are in our production work order data model, and this model plugs into its material issue and lot_no fields.
The item master says whether a material is lot tracked at all. Decide it per item, not per plant habit.
| Field | What it holds |
|---|---|
| item_ | Part or material number, e.g. RM-FLOUR-T55 |
| item_ | Raw, packaging, intermediate, finished |
| uom | Base unit: kg, L, pcs, m |
| tracking | None, lot or serial |
| shelf_ | Used to set expiry_ |
| qc_ | Yes means every new lot starts in Quarantine |
One table holds every lot: raw material, intermediate, rework and finished. A single table keeps the genealogy query simple, because every node in the graph has the same shape.
| Field | What it holds |
|---|---|
| lot_ | Internal lot number, unique, e.g. RM-0917-03 |
| item_ | What the lot contains |
| lot_ | Received, produced, rework, returned |
| supplier_ | Who delivered it (received lots only) |
| supplier_ | The supplier's own lot or batch number, exactly as printed |
| coa_ | Certificate of analysis or conformance document |
| receipt_ | Goods receipt and delivery note |
| batch_ | Batch record that produced it (produced and rework lots). Returned lots link to the original lot in source_ |
| qty_ | Quantity created and quantity left |
| mfg_ | Production and best before or retest date |
| status | See the status rules below |
Never overwrite the supplier's lot number with your own. Keep both, because the supplier will name its own number in a recall notice and you must find it in seconds.
One supplier lot can arrive in two deliveries. Give each receipt its own internal lot_id and let both carry the same supplier_lot_no, so a search on the supplier number returns both.
The batch record is the production order seen from the lot side. It needs only a few fields beyond the order itself.
| Field | What it holds |
|---|---|
| batch_ | Batch number, e.g. B-2451 |
| order_ | Link to the production work order |
| line / equipment | Where it ran, e.g. MIXER-02, PACK-01 |
| recipe_ | Formula or BOM version used |
| start_ | Actual start and end, in UTC |
| input_ | Totals derived from consumption and output records |
| mass_ | Calculated variance, see below |
| released_ | Who approved the batch record for release |
This is the table that makes traceability possible. One row per input lot per batch, never one row per item.
| Field | What it holds |
|---|---|
| consumption_ | Unique key |
| batch_ | The batch that used the material |
| input_ | The lot that was consumed |
| qty / uom | Quantity actually used, net of returns |
| consumed_ | When it was added |
| scan_ | Barcode scan, weighed at scale, manual entry |
If a batch uses the last 900 kg of one flour lot and 600 kg of the next, that is two consumption rows. Booking 1,500 kg against one lot is the most common way genealogy goes wrong.
| Record | Key fields |
|---|---|
| output | batch_ |
| handling_ | hu_ |
| shipment_ | shipment_ |
For most output, one batch makes one finished lot, and lot_id is the join key to the batch record. Serial numbers are only needed where each unit must be traced alone; see lot vs serial tracking.
Treat every lot as a node and every consumption record as a directed edge from the input lot to every output lot of that batch, and B-2454 below has two. The quantity on the edge says how much went across.
Because every batch creates a new lot, the graph has no cycles. Keep it that way: a lot can never be consumed into itself, and rework always gets its own lot_id.
A single chain is traceability, while the full branching tree behind one unit is genealogy. Our article on traceability vs genealogy explains when the extra depth pays off.
In SQL this is one recursive query (WITH RECURSIVE) over the consumption table. Add a depth counter and a visited list, so a bad data entry cannot loop forever.
One rule surprises people: a blended output lot is affected as a whole. If 900 kg of suspect flour went into a 2,000 kg mix, all 2,000 kg are suspect, because you cannot separate it again.
| Status | Consume or ship? | Typical trigger |
|---|---|---|
| Quarantine | No | Receipt or production, waiting for QC and COA check |
| Released | Yes | QC approval or batch record release |
| On hold | No | Suspected problem, complaint, open investigation |
| Rejected | No | Failed test; return, destroy or rework |
| Expired | No | expiry_ |
| Consumed | Nothing left | qty_ |
The rules that should be enforced by the system, not by a work instruction:
How a hold is run as a process, with owners and deadlines, is covered in quality hold process design.
A trace lists where material went. Mass balance proves that the list is complete.
Batch variance = inputs minus (good output + rework + scrap + samples)
Variance % = batch variance ÷ inputs × 100
Set a tolerance per process. A dry blend with no evaporation can hold a tight band such as ±0.5%, while a bake or dryer needs an expected moisture loss built into the formula first.
Run the same check on each raw material lot: received minus consumed minus on hand minus recorded losses should be close to zero.
A mill notifies a dry mix plant that its flour lot M-2409-117 may be contaminated. A search on supplier_lot_no finds one receipt: 24,000 kg, booked as internal lot RM-0917-03, with its COA on file.
Each pancake mix batch is 2,000 kg: 1,500 kg flour, 300 kg sugar, 150 kg milk powder, 40 kg raising agent and 10 kg salt.
Batches B-2451 to B-2457 used 1,500 kg each from RM-0917-03. B-2458 was the last batch before the line switched to a second mill's flour, so it used 900 kg from RM-0917-03 plus 600 kg of the new lot.
| Item | kg |
|---|---|
| Received | 24,000 |
| Consumed in 8 batches | 11,400 |
| Counted on hand | 12,570 |
| Recorded loss (torn bag) | 20 |
| Unexplained | 10 (0.04%) |
The 12,570 kg on hand goes On hold at once. The raw lot balance is well inside tolerance.
| Batch | Output, rework, scrap, samples | Variance |
|---|---|---|
| B-2451 | 1,980 + 0 + 12 + 2 | 6 kg, 0.3%, pass |
| B-2454 | 1,920 + 60 + 12 + 2 | 6 kg, 0.3%, pass |
| B-2455 | 1,930 + 0 + 12 + 2 | 56 kg, 2.8%, fail |
The other five batches match B-2451. B-2455 fails the ±0.5% band: 56 kg of mix, 56 packs if you sell 1 kg packs, are not in any record.
That is why mass balance matters in a recall. Until the 56 kg are found, you cannot say the product is not on a shelf somewhere.
The 60 kg from B-2454 were underweight packs, reopened and booked as rework lot RW-0921-01. A week later that lot was consumed into batch B-2461, made with clean flour.
B-2461 is therefore in scope. A trace that only follows the flour item would miss it, because the path runs flour, B-2454, RW-0921-01, B-2461.
| Customer | Lots | kg |
|---|---|---|
| Wholesaler A | B-2451, B-2452 (part) | 2,980 |
| Wholesaler B | B-2452 (part), B-2453 | 2,960 |
| Retail DC North | B-2454, B-2455 | 3,850 |
| Retail DC South | B-2456, B-2457 (part) | 2,980 |
| Food service distributor | B-2457 (part), B-2458 | 2,960 |
| Export customer | B-2461 (part) | 1,200 |
| Own warehouse | B-2461 (part) | 780 |
| Total | 9 lots | 17,710 |
Check the total from the output side: six batches at 1,980 kg, plus 1,920 (B-2454) and 1,930 (B-2455), is 15,730 kg. Add B-2461 at 1,980 kg and you get 17,710 kg, which matches the shipments plus stock.
So the answer is: 11,400 kg of suspect flour inside 17,710 kg of finished product, 16,930 kg at six customers, 780 kg in stock, plus 56 kg unaccounted for in B-2455.
Without the consumption records, the only safe answer would have been every batch made since the flour arrived. The 2 kg retained samples from each batch are now your best evidence, so send them to the lab before anything is destroyed.
B-2458 shows the pattern: two input lots, two consumption rows. The second mill's lot is now linked to B-2458 as well, so a future trace of that lot also returns B-2458.
Book rework as a new lot with its own lot_id, created by the batch it came from. Never add it back into stock under the original finished lot number, or the path breaks.
For when to rework and when to scrap, see scrap vs rework.
A raw lot consumed by two production orders simply has edges to two batches. Nothing special is needed, as long as consumption is booked per batch and not per day.
Silos and tanks that are topped up while running mix lots together.
Make each fill a new silo lot with edges from the delivery lot and the residue it landed on. Then link every silo lot present during a batch's start_ts to end_ts window.
A return comes back as a lot of type returned, linked to the original lot. It starts in Quarantine and never rejoins released stock without a decision.
In EU food law, Article 18 of Regulation (EC) No 178/2002 requires food and feed businesses to identify who supplied them and which businesses they supplied. This is the one step back, one step forward principle, and the information must be available to the authorities on demand.
The forward step covers business customers, not final consumers. Article 18 does not spell out internal links between input and output lots, but without them the one step forward covers everything you shipped.
Food contact materials, such as packaging and plastic parts that touch food, have a similar traceability duty under Article 17 of Regulation (EC) No 1935/2004.
Once a trace shows unsafe food has left your control, Article 19 of Regulation (EC) No 178/2002 requires you to withdraw it and inform the competent authority. For inputs of animal origin, such as milk powder, Implementing Regulation (EU) No 931/2011 also requires lot, quantity and date details from suppliers.
Beyond the law, food safety certification schemes and some automotive and industrial customers ask for documented traceability tests, often at least once a year. For food, see our HACCP compliance guide.
A common good practice target for a mock recall is to reach full traceability, with quantities reconciled, within 4 hours. Treat it as a benchmark to test against, and check the exact rule in the standard your customers audit you to.
Fabrico is not a lot traceability, MES or ERP lot system. It does not store lots, consumption records or shipments, and it does not run backward or forward traces.
Fabrico is an OEE platform with a full CMMS. It records machine history, downtime and short stops through PLC connections, IoT sensors and AI cameras.
On the maintenance side, your team creates maintenance work orders, runs preventive plans and records the spare parts consumed per work order, from web or mobile apps.
That matters in an investigation. Take a batch's start_ts and end_ts from your lot system, put them next to Fabrico's machine timeline, and your team can see which stops, repairs and part changes happened while that lot ran, and ask the AI assistant about that machine's history in plain language.
For how machine data and traceability records support audits together, read our audit-ready OEE traceability strategy.
Want to see the machine side of your next investigation? Book a 30 minute demo with a Fabrico consultant, no commitment, or contact us with your questions.
At minimum: item, lot, batch record, consumption, output, handling unit and shipment line. The consumption table, one row per input lot per batch, is the one that makes genealogy possible.
Start at the finished lot, find its batch, and list every input lot from the consumption records. Repeat for each produced or rework lot until you reach received lots with a supplier lot number.
It compares inputs with good output, rework, scrap and samples for a batch or a lot. A variance outside tolerance means some material is not in any record, so the trace is incomplete.
No. Only Released lots within their expiry date should be consumed or shipped, and the system should refuse the transaction otherwise.
Under Article 18 of Regulation (EC) No 178/2002, a food business must know who supplied each input and which businesses received its products. Internal lot links are not spelled out there, but they are what keep a recall small.