How to Use Product Performance in Amazon: Step-by-Step Tutorial
Updated October 2026
Discover which Amazon products sell best and optimize your inventory strategy with data-driven insights
Introduction to Amazon Product Performance Analysis
As an Amazon seller, one of the most useful questions is: "Which products should I focus on?" Product performance analysis answers it by putting units, revenue, margin and returns side by side for each product, so you can see which ones earn their place and which ones do not.
This tutorial computes those numbers with pandas from three files you can export: your order lines, a cost sheet, and a returns report. Sales alone cannot give margin or return rate, so the tutorial shows exactly where costs and returns are joined in. The figures in every output block come from a synthetic data set generated for this tutorial (16 invented products, about 3,900 order lines), not from a real seller, so your numbers will differ.
Fulfillment method also affects product economics; see Amazon FBA vs FBM performance for that comparison.
What You'll Accomplish
By following this step-by-step tutorial, you will:
- Understand what the key product metrics measure and which files each one needs
- Export and prepare your order, cost and returns files
- Compute units, revenue, margin and return rate per product
- Identify top and weak products relative to your own catalog
- Turn the findings into inventory, pricing and advertising tests
Prerequisites and Data Requirements
What You Need
- Order history for the period you want to study, as a CSV with one row per order line. Several months give steadier product comparisons than a few weeks
- A cost for every SKU: A standard order report does not include your product cost, so keep a cost sheet (SKU, unit cost, and the fee rate you pay) of your own
- A returns report for the same period, as a CSV
- Python with pandas, or a spreadsheet if you rebuild the same steps there
Which Amazon reports provide each file, and how far back they go, depends on your account and marketplace and changes over time. Check Seller Central's current help pages for the report names and limits; this tutorial does not rely on any specific one.
Step 1: Understand Product Performance Metrics
Metrics This Tutorial Computes
1. Units Sold
Total units on shipped order lines for each product. Cancelled and pending lines are left out.
2. Revenue
Item price times quantity on shipped lines, before Amazon fees, returns and costs.
3. Profit Margin
(Revenue minus units times unit cost minus fees) divided by revenue. It needs your cost sheet and a fee rate. It leaves out advertising, storage and shipping unless you add them to the calculation.
4. Return Rate
Returned units divided by units sold. It needs the returns report. Recent orders look better than they are because some returns have not arrived yet.
Metrics That Need Other Data
- Inventory turnover (units sold divided by average inventory) needs inventory levels, which an order export does not contain.
- Conversion rate (orders divided by visitors) needs traffic data, also not in an order export.
Pick the metrics that match your goal: cash flow points to turnover, brand building to margin and returns.
Step 2: Check Your Data Sources
- Orders: confirm you can export order lines with SKU, product name, quantity, item price, order status and order date
- Costs: confirm every SKU you sell has a unit cost in your cost sheet
- Returns: confirm you can export returns with the order, SKU and quantity
- Product keys: make sure the SKU is spelled the same in all three files, since the join depends on it
If any SKU is missing a cost, the code in Step 4 stops with an error rather than reporting a margin that is wrong.
Step 3: Export Your Amazon Files
Export your order report for the period, with every order status included, and your returns report, both as CSV or tab-separated text. Report names and menus change, so follow Seller Central's current help for the exact steps. Save them as orders.csv and returns.csv, and keep your cost sheet as costs.csv.
The code expects these columns, so rename the ones in your report to match:
orders.csv:order_id, order_date, order_status, sku, product_name, quantity, item_pricecosts.csv:sku, unit_cost, fee_rate(fee rate as a fraction of revenue)returns.csv:order_id, sku, returned_qty
Check the order statuses in your file. The code treats "Shipped" as a sale; if your report uses different words, change that one line.
Step 4: Compute Product Performance with pandas
Units and Revenue per Product
This code keeps shipped lines, totals units and revenue per SKU, and shows how concentrated revenue is.
import pandas as pd
orders = pd.read_csv("orders.csv", parse_dates=["order_date"])
print(orders["order_status"].value_counts().to_string())
# Only shipped orders count as sales; cancelled and pending lines are left out
sold = orders[orders["order_status"] == "Shipped"].copy()
sold["revenue"] = sold["item_price"] * sold["quantity"]
by_sku = (sold.groupby(["sku", "product_name"])
.agg(units=("quantity", "sum"), revenue=("revenue", "sum"))
.reset_index().sort_values("revenue", ascending=False).reset_index(drop=True))
by_sku["share_pct"] = by_sku["revenue"] / by_sku["revenue"].sum() * 100
by_sku["cum_share_pct"] = by_sku["share_pct"].cumsum()
print(by_sku.head(6).round(1).to_string())
top = max(1, round(len(by_sku) * 0.2))
print(f"Top {top} of {len(by_sku)} products ({top / len(by_sku):.0%}) earn {by_sku['cum_share_pct'].iloc[top - 1]:.1f}% of shipped revenue")
Expected Output
order_status
Shipped 3508
Cancelled 236
Pending 158
sku product_name units revenue share_pct cum_share_pct
0 SKU-03 Blue Light Glasses 1130 62037.0 30.9 30.9
1 SKU-15 Screen Cleaner 1103 44660.5 22.2 53.2
2 SKU-08 Travel Mug 592 41209.1 20.5 73.7
3 SKU-11 Notebook Set 209 10048.7 5.0 78.7
4 SKU-13 Mouse Pad 207 9488.9 4.7 83.4
5 SKU-02 Laptop Stand 134 7922.1 3.9 87.4
Top 3 of 16 products (19%) earn 73.7% of shipped revenue
Add Margin and Return Rate
Margin and return rate need the cost sheet and the returns file. This code joins both on SKU. Groups are defined against the median of your own products, so about half the products fall on each side by construction; they rank products against each other and say nothing about whether a margin is good in absolute terms.
costs = pd.read_csv("costs.csv") # sku, unit_cost, fee_rate: your own cost sheet and Amazon fee rate per SKU
returns = pd.read_csv("returns.csv") # order_id, sku, returned_qty: from your returns report
ret = returns.groupby("sku")["returned_qty"].sum().rename("returned_units")
perf = (by_sku.merge(costs, on="sku", how="left")
.merge(ret, left_on="sku", right_index=True, how="left"))
perf["returned_units"] = perf["returned_units"].fillna(0)
assert perf["unit_cost"].notna().all(), "every SKU needs a cost"
perf["profit"] = perf["revenue"] - perf["units"] * perf["unit_cost"] - perf["revenue"] * perf["fee_rate"]
perf["margin_pct"] = perf["profit"] / perf["revenue"] * 100
perf["return_rate_pct"] = perf["returned_units"] / perf["units"] * 100
med_rev, med_margin = perf["revenue"].median(), perf["margin_pct"].median()
perf["group"] = (perf["revenue"] >= med_rev).map({True: "high revenue", False: "low revenue"}) + " / " + \
(perf["margin_pct"] >= med_margin).map({True: "high margin", False: "low margin"})
cols = ["product_name", "units", "revenue", "margin_pct", "return_rate_pct", "group"]
print(perf[cols].head(8).round(1).to_string())
print(perf["group"].value_counts().to_string())
print(f"Total shipped revenue ${perf['revenue'].sum():,.2f}, profit ${perf['profit'].sum():,.2f} "
f"({perf['profit'].sum() / perf['revenue'].sum() * 100:.1f}%)")
Expected Output
product_name units revenue margin_pct return_rate_pct group
0 Blue Light Glasses 1130 62037.0 33.8 5.6 high revenue / high margin
1 Screen Cleaner 1103 44660.5 25.7 5.7 high revenue / low margin
2 Travel Mug 592 41209.1 36.4 8.4 high revenue / high margin
3 Notebook Set 209 10048.7 35.3 12.4 high revenue / high margin
4 Mouse Pad 207 9488.9 31.2 7.2 high revenue / low margin
5 Laptop Stand 134 7922.1 11.0 0.0 high revenue / low margin
6 Pen Pack 169 5970.8 30.8 2.4 high revenue / low margin
7 Desk Lamp 302 4795.8 28.1 21.5 high revenue / low margin
group
high revenue / low margin 5
low revenue / high margin 5
high revenue / high margin 3
low revenue / low margin 3
Total shipped revenue $200,723.87, profit $63,345.51 (31.6%)
Step 5: Interpret Your Results
- Concentration: in this synthetic data the top 3 of 16 products earn 73.7% of shipped revenue. Your share will differ; the code prints it for your catalog.
- High revenue, low margin: Screen Cleaner earns the second most revenue at a 25.7% margin, against 33.8% to 36.4% for the products above and below it. Look at its cost, fee rate and price.
- High return rate: Desk Lamp has a 21.5% return rate in this data; check the product, its listing and its reviews before changing anything else.
- Low volume: a margin or return rate computed from a few dozen units is noisy. Check the units column before trusting either.
Questions to Ask Your Data
- Which products carry the revenue, and how much would you lose if one stopped selling?
- Which products have the highest return rates, and are they recent orders whose returns have not all arrived?
- Are there seasonal patterns? Compare the same months a year apart, not neighboring months.
- Which products have declining sales over the period? Split the period into months and compare.
When you compare two products or two periods, remember that differences can be chance; testing for statistical significance is the way to check.
Step 6: Take Action Based on Insights
These are tests to run, not guaranteed improvements. Change one thing at a time and compare against your own numbers.
Inventory
A common reorder estimate is average daily sales times lead time times a safety factor. The factor is a judgment about how much demand varies and how costly a stockout is, not a fixed rule:
daily_units, lead_time_days, safety_factor = 25, 45, 1.5
units_needed = daily_units * lead_time_days * safety_factor
print(f"{daily_units} units/day x {lead_time_days} days x {safety_factor} = {units_needed:,.1f}, order {int(-(-units_needed // 1)):,} units (rounded up)")
Expected Output
25 units/day x 45 days x 1.5 = 1,687.5, order 1,688 units (rounded up)
For slow sellers, work out what the stock costs you in storage and tied-up cash before deciding to clear it.
Pricing and Advertising
- Test a price change on one product at a time and watch units and margin together; a higher price can lower units enough to lower profit.
- Check advertising spend by product against that product's profit, not its revenue.
- For products with a high return rate, read the return reasons and fix the listing or the product first.
Product Decisions
Before dropping a product, check whether it sells alongside others and whether its low margin is a cost problem you can fix.
Run It on Your Own Amazon Export
Export your Amazon orders as a CSV and upload it at MCP Analytics. The analysis runs a per-product breakdown of units and revenue on your file and shows the result with the method used. You choose the columns; nothing connects to your Amazon account.
Next Steps with Amazon Analytics
- Repeat purchase by product: which products bring customers back
- Seasonality: compare the same months across years before stocking up
- Bundles: find products that are bought together
Troubleshooting Common Issues
Issue: The Code Stops With "every SKU needs a cost"
A SKU in your orders is missing from the cost sheet, or is spelled differently. List the missing ones with set(by_sku["sku"]) - set(costs["sku"]) and add them.
Issue: Garbled Characters
Save the file as UTF-8, or pass encoding="utf-8" or the file's actual encoding to pd.read_csv.
Issue: Top Products by Revenue Are Not Profitable
Revenue is not profit. Sort by profit instead of revenue, and add advertising and storage costs to the calculation if you want them included.
Issue: Return Rates Look Too Low
Returns arrive after the order. Recent orders will show lower return rates than they will end up with, so compare periods that are old enough for most returns to have been recorded.
Issue: Few Rows After Filtering
Check the order status values in your file. If your report does not call a completed sale "Shipped", the filter keeps nothing.
Your turn
Bring your own data and the question you actually need answered.
MCP AnalyticsData science by email Send us your data and your question, and we will reply. ds@mcpanalytics.ai
Explore more: Amazon Seller Analytics: all tools, tutorials, and guides →