FIFO inventory calculator
Buy 100 units at 10 and 50 at 12, sell 120, and FIFO gives a cost of goods sold of 1,240 and ending inventory of 360: the 30 newest units at 12. Enter your lots oldest first. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Units sold
- 120
- Purchase count
- 2
- Units available
- 150
- Units remaining
- 30
- Goods available
- 1,600
First-in first-out inventory costing answers a close-period question that a single merchandising identity cannot: given the purchase lots still on the shelf and the units that left, what is ending inventory worth, and what is cost of goods sold? FIFO treats the oldest units as sold first, so remaining stock is valued at the newest unit costs. This FIFO inventory calculator accepts an ordered list of purchase batches — units and unit cost per lot, oldest first — plus units sold, consumes those units from the front of the queue, and returns both ending inventory value and cost of goods sold.
How FIFO costing turns purchase lots into COGS and ending inventory
First-in first-out is a cost-flow assumption, not a warehouse map. You send purchase batches in chronological order, oldest lot first: each row is a quantity of units bought at a stated unit cost. Opening stock is simply the first batch if those units arrived last period and are still on the books; there is no separate beginning-inventory field and no date stamp, because the engine never reads a clock.
Units sold are then peeled off the oldest remaining lots until the sold quantity is satisfied. Cost of goods sold is the sum of units taken from each consumed lot times that lot's unit cost. Ending inventory is the sum of units still sitting in later lots times those lots' unit costs.
The two figures add back to goods available — the total cost of every unit you started with — which is the same identity merchandising books use, except here both sides are derived from lots rather than from a plugged cost-of-goods-sold line. A textbook walk-through: one hundred units at ten, then fifty units at twelve, and one hundred twenty units sold.
FIFO takes the entire first lot (one thousand of cost) and twenty units from the second lot (two hundred forty), so cost of goods sold is one thousand two hundred forty and ending inventory is the leftover thirty units at twelve, or three hundred sixty. If units sold equal units available, ending inventory is zero and every lot is consumed. If units sold are zero, cost of goods sold is zero and ending inventory equals goods available.
What this calculator does not do is sort lots by a calendar date, apply last-in first-out, compute a weighted-average unit cost, convert currencies, or reconstruct the three-line identity beginning inventory plus net purchases minus cost of goods sold. Send the lots already ordered; the engine only walks them from the front and returns both values.
Where a FIFO inventory calculator earns its keep
Controllers and bookkeepers use a FIFO inventory calculator at close to turn the period's purchase lots and units sold into the two figures the income statement and the balance sheet both need: cost of goods sold and ending inventory under the first-in first-out cost-flow assumption their policy already names. Tax pack workpapers in jurisdictions that require or permit FIFO need the same walk pinned, not a spreadsheet that silently resorted the lots.
Auditors and lenders drop the same batches into a working paper so a closing-stock number that does not follow from the oldest lots is visible before it is signed off. Merchandisers who buy in rising markets use FIFO because remaining stock is valued at newer, typically higher unit costs, and they want that valuation without rebuilding a perpetual inventory engine.
This is a different search and a different job from the merchandising identity that subtracts a given cost of goods sold from beginning inventory plus net purchases, from days inventory outstanding, from inventory turnover, and from a physical count: those tools start from different inputs and answer different questions. Failed validation does not consume balance.
Keep lots in first-in order, keep units sold within units on hand, pin the rounded figures in tests, and you get a reproducible FIFO close for checklists, classroom oracles, and edge workers without standing up a warehouse engine of your own.
What you can do with it
Month-end and year-end FIFO close
Turn ordered purchase lots and units sold into cost of goods sold and ending inventory before the close pack is locked, then compare remaining layers with a physical count.
Income-statement COGS under FIFO policy
Value units issued at the oldest remaining unit costs so the cost-of-goods-sold line matches a first-in first-out accounting policy instead of a weighted average.
Audit working papers and tax FIFO schedules
Drop the same batches into a working paper so a closing-stock number that does not follow from the oldest lots is visible before it is signed off.
FAQ
How is FIFO inventory costing calculated?
Send purchase lots oldest first, plus units sold. The calculator consumes units from the front of the queue. Cost of goods sold is the cost of consumed units; ending inventory is the cost of units still in later lots. The two add back to goods available.
What happens if units sold exceed available inventory?
Units sold must be a finite number greater than or equal to zero and must not exceed the sum of lot units; overselling is not billed.
How do I send opening stock?
Put opening stock as the first purchase batch (oldest lot). There is no separate beginning-inventory field and no date stamp: chronological order is the array order.
Is this the same as ending inventory equals beginning plus purchases minus COGS?
No. That merchandising identity starts from three ledger totals and does not walk lots. This calculator derives both ending inventory and cost of goods sold from purchase batches under FIFO.
Can it calculate LIFO or weighted average cost?
No. It only applies first-in, first-out, taking sold units from the oldest lots first. It also does not sort lots by date, so enter them already in the order they were bought.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/fin/fifo-for-inventories \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"purchases":[{"units":100,"unit_cost":10},{"units":50,"unit_cost":12}],"units_sold":120}'const res = await fetch("https://api.kit.forhosting.com/fin/fifo-for-inventories", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"purchases": [
{
"units": 100,
"unit_cost": 10
},
{
"units": 50,
"unit_cost": 12
}
],
"units_sold": 120
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/fin/fifo-for-inventories",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"purchases": [
{
"units": 100,
"unit_cost": 10
},
{
"units": 50,
"unit_cost": 12
}
],
"units_sold": 120
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/fin/fifo-for-inventories", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"purchases":[{"units":100,"unit_cost":10},{"units":50,"unit_cost":12}],"units_sold":120}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"purchases":[{"units":100,"unit_cost":10},{"units":50,"unit_cost":12}],"units_sold":120}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/fin/fifo-for-inventories", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"purchases": [
{
"units": 100,
"unit_cost": 10
},
{
"units": 50,
"unit_cost": 12
}
],
"units_sold": 120
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "fin.fifo_for_inventories",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_items | 200 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
If units sold exceed units on hand the task fails with invalid_input instead of inventing a negative warehouse.
Input contract, response shape, and error behaviour
Zero units sold is allowed. Money amounts round half-up to two decimal places. Example: one hundred units at ten plus fifty units at twelve with one hundred twenty sold yields one thousand two hundred forty of cost of goods sold and three hundred sixty of ending inventory, with thirty units remaining in the second lot. POST a JSON body with two required fields. purchases is a non-empty array of lot objects, at most two hundred rows, each with units strictly greater than zero and unit_cost greater than or equal to zero; aliases batches, lots, and layers map to the same list so a worksheet can keep its column names. On each row, quantity and qty alias units, and cost, price, and cost_per_unit alias unit_cost. units_sold is the quantity issued during the period; aliases sold, quantity_sold, and qty_sold are accepted. Each numeric field may arrive as a JSON number or a numeric string. Missing fields, empty strings, and non-finite values — NaN, Infinity, or text that does not parse as a number — fail with invalid_input naming the field. A negative unit cost, a negative units_sold, or a lot whose units are zero or negative is rejected and is not billed. On success the body reports purchase_count, units_available, units_sold, units_remaining, goods_available as the total cost of every lot, cost_of_goods_sold, ending_inventory, remaining_layers as the leftover lots with units, unit_cost, and value, and a formula string restating the FIFO walk. Pair the JSON with your own physical count if you need a warehouse-level story; this endpoint returns the cost-flow valuation, not a cycle count, not LIFO, and not a currency conversion.
Technical questions
What does the FIFO inventory calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.