Calculate Inventory Turnover Ratio and Days to Sell Through
Inventory turnover connects the cost of products sold with the average value held in stock during the same period.
Run — free
Enter cost of goods sold, average inventory, and the number of days in the period to calculate both the turnover ratio and estimated days to sell through. The result helps retailers, wholesalers, and ecommerce operators compare inventory efficiency across products or reporting periods without mixing revenue, units, or mismatched time windows.
Prepare matching figures for a meaningful ratio
Start with cost of goods sold for one clearly defined reporting period, not sales revenue. Cost of goods sold reflects the recorded cost of inventory that actually left the business, while revenue includes markup and therefore produces a different and usually inflated ratio. Next, calculate average inventory value for that same period. A common method is to add beginning inventory and ending inventory and divide by two, although a monthly or weekly average can be more representative when stock levels fluctuate sharply. Both values must use the same currency and the same valuation basis. If cost of goods sold covers a quarter, average inventory must describe that quarter rather than the full year. Enter the actual length of the reporting period in days; use 365 for a full non-leap year, 90 or 91 for many quarters, or the exact count used internally. Consistent inputs matter more than choosing a particular reporting frequency because the ratio is only comparable when its numerator and denominator describe the same operating window.
Understand the turnover and sell-through calculations
The inventory turnover ratio is cost of goods sold divided by average inventory value. For example, a ratio of four means the business moved inventory equal to four times its average inventory investment during the measured period. Days to sell through translates that ratio into time by dividing the number of days in the period by the turnover ratio. A four-times annual turnover therefore corresponds to 91.25 days. The calculator keeps the entered period visible in the output and rounds calculated figures to six decimal places for stable reporting. Average inventory cannot be zero because division by zero has no defined business meaning, and negative inventory values are also rejected. Cost of goods sold must be positive because a zero or negative value cannot produce a useful finite selling-duration estimate. These results describe aggregate flow, not the exact age of an individual item. They should be interpreted as operating indicators derived from accounting values rather than as a promise that every unit will sell within the displayed number of days.
Use the result in operational decisions
Compare turnover over time, against a planned target, or among categories with similar economics. A rising ratio and falling days-to-sell figure may indicate better purchasing discipline, stronger demand, fewer slow-moving products, or stock shortages; the calculator alone cannot identify which explanation applies. A low ratio can point to excess stock, weak sales, obsolete items, seasonal buildup, or a deliberate availability strategy. Always pair the result with stockout rates, gross margin, lead time, demand variability, and markdown activity before changing replenishment rules. Comparisons across unrelated industries can be misleading because grocery, apparel, luxury goods, and industrial parts naturally operate at different speeds. For seasonal businesses, compare equivalent periods year over year instead of treating one peak quarter as representative of an entire year. When automating the calculation, preserve the source period and valuation method with each result so reviewers can reproduce it. The browser calculation is convenient for individual checks, while API requests cost $0.002 each and support repeatable dashboards, scheduled reporting, and category-level monitoring.
What you can do with it
Review quarterly inventory efficiency
Convert quarterly COGS and average inventory into a comparable turnover ratio and an estimated number of days to sell through.
Compare product categories
Calculate the metric consistently for categories with similar economics to identify unusually slow or fast inventory movement.
Monitor replenishment performance
Track changes in turnover alongside stockouts, lead times, and margins when evaluating purchasing and replenishment policies.
FAQ
What formula does the calculator use?
Inventory turnover ratio equals cost of goods sold divided by average inventory. Days to sell through equals period days divided by that ratio.
Should I use sales revenue or cost of goods sold?
Use cost of goods sold. Revenue includes markup and is not measured on the same cost basis as inventory value.
How do I calculate average inventory?
A common estimate is beginning inventory plus ending inventory, divided by two. More frequent observations can give a better average when stock changes substantially.
Why is zero average inventory rejected?
The turnover formula divides by average inventory, so a zero value would make the ratio undefined.
Is a higher inventory turnover always better?
No. Higher turnover may reflect efficient stock management, but it can also accompany shortages or lost sales. Review it with availability, margin, and lead-time metrics.
What does an API calculation cost?
Each API request costs $0.002. The calculator on this page can be used for individual browser-based checks.
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/ecom/inventory-turnover-ratio \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"cost_of_goods_sold":480000,"average_inventory":120000}'const res = await fetch("https://api.kit.forhosting.com/ecom/inventory-turnover-ratio", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"cost_of_goods_sold": 480000,
"average_inventory": 120000
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/ecom/inventory-turnover-ratio",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"cost_of_goods_sold": 480000,
"average_inventory": 120000
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/ecom/inventory-turnover-ratio", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"cost_of_goods_sold":480000,"average_inventory":120000}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"cost_of_goods_sold":480000,"average_inventory":120000}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/ecom/inventory-turnover-ratio", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"cost_of_goods_sold": 480000,
"average_inventory": 120000
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "ecom.inventory_turnover_ratio",
"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.
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. |