FIFO Cost Basis Crypto: FIFO vs Average Cost, One Worked Example
You bought some bitcoin on Coinbase in January, bought more on Kraken in March, moved a chunk to a hardware wallet, and sold part of it in June. Now you want one number: how much did you actually gain? Coinbase shows a gain that assumes it knows everything you own. Kraken shows a different number. Neither is right, because neither can see the other.
This is a FIFO cost basis crypto problem, and it is not hard once you see the mechanics. I will walk through cost basis from scratch, run the same three trades through FIFO and average cost so you can see where they diverge, then cover the two mistakes that break most people's numbers. You can follow every step with a pen and a calculator.
What cost basis actually is
Cost basis is what you paid to acquire an asset, including the fees it cost you to acquire it. When you sell, your gain or loss is:
gain = net proceeds − cost basis of the units you sold
Net proceeds means the sale amount after the sell-side fee. Cost basis means the purchase amount plus the buy-side fee. That is the entire concept. Everything else in this article is about one question: when you bought at several different prices and sell only some of your coins, which purchase price do you use?
The answer is a "lot selection method." FIFO and average cost are the two you will meet most often.
The worked example: three trades
I will use the same trades for both methods. Round numbers, one asset, no transfers yet.
| # | Date | Action | Amount | Price | Fee | Cash in/out |
|---|---|---|---|---|---|---|
| 1 | Jan 10 | Buy | 1.0 BTC | $30,000 | $30 | −$30,030 |
| 2 | Mar 5 | Buy | 0.5 BTC | $40,000 | $20 | −$20,020 |
| 3 | Jun 20 | Sell | 0.8 BTC | $50,000 | $40 | +$39,960 |
Before the sale you hold 1.5 BTC with a total cost basis of $50,050. The June sale nets $39,960 after the $40 fee. The only question is what the 0.8 BTC you sold "cost."
Method 1: FIFO (first in, first out)
FIFO assumes the coins you sell are the oldest ones you own. You keep a list of purchase lots in date order and consume them from the top.
Step 1 — list your lots with per-unit basis (fees included):
- Lot A: 1.0 BTC, cost $30,030 → $30,030 per BTC
- Lot B: 0.5 BTC, cost $20,020 → $40,040 per BTC
Step 2 — sell 0.8 BTC from the oldest lot. Lot A has 1.0 BTC, so all 0.8 come from it.
- Cost basis of units sold: 0.8 × $30,030 = $24,024
Step 3 — compute the gain.
- $39,960 − $24,024 = $15,936 realized gain
Step 4 — update what is left.
- Lot A: 0.2 BTC remaining, basis $6,006
- Lot B: 0.5 BTC remaining, basis $20,020
- Total: 0.7 BTC, remaining basis $26,026
Notice that under FIFO, the two remaining pieces keep their own identities. The next sale will consume the rest of Lot A first, then start on Lot B.
Method 2: Average cost
Average cost blends every unit you hold into a single pool with one per-unit price. Each time you buy, you recompute the average. When you sell, every unit leaves at that average.
Step 1 — compute the pooled average before the sale.
- Total cost: $30,030 + $20,020 = $50,050
- Total units: 1.5 BTC
- Average: $50,050 ÷ 1.5 = $33,366.67 per BTC
Step 2 — sell 0.8 BTC at the average.
- Cost basis of units sold: 0.8 × $33,366.67 = $26,693.33
Step 3 — compute the gain.
- $39,960 − $26,693.33 = $13,266.67 realized gain
Step 4 — update what is left.
- 0.7 BTC at $33,366.67 = $23,356.67 remaining basis
Same trades, same cash, and the reported gain is $2,669 lower under average cost. Nothing shady happened. FIFO matched the sale against your cheapest coins (the January lot), so it recognized more of the gain now. Average cost spread the higher March price across every unit.
Side by side, and why the difference is timing, not magic
| FIFO | Average cost | |
|---|---|---|
| Basis of 0.8 BTC sold | $24,024.00 | $26,693.33 |
| Realized gain on June sale | $15,936.00 | $13,266.67 |
| Remaining basis (0.7 BTC) | $26,026.00 | $23,356.67 |
Now sell the remaining 0.7 BTC later at $45,000 with a $30 fee (net proceeds $31,470):
| FIFO | Average cost | |
|---|---|---|
| Basis of final 0.7 BTC | $26,026.00 | $23,356.67 |
| Gain on second sale | $5,444.00 | $8,113.33 |
| Total realized gain, both sales | $21,380.00 | $21,380.00 |
Once you have sold everything, both methods land on the same total, because total proceeds minus total cost is the same no matter how you slice it. The method only changes which year the gain shows up in, and therefore which tax rate and which holding period apply. That is why it matters, and why you cannot casually switch methods from one year to the next without your remaining basis going wrong.
Which one should you use? That depends on where you file. In the US, the IRS recognizes specific identification (with contemporaneous records) or, by default, FIFO, applied wallet-by-wallet since 2025; average cost is a mutual-fund rule and is not a recognized method for crypto. In Canada, gains on crypto held as capital property use a weighted-average adjusted cost base per coin across everything you own; you cannot choose FIFO or specific lots. In the UK, HMRC matches a sale first to any buys of the same token on the same day, then to buys in the 30 days after the sale, and only then to the Section 104 pool, where each token carries the pool's average cost. Rules change and have edge cases, so confirm with a professional in your jurisdiction. The mechanics above are the same everywhere; only the permitted choice differs.
Why your exchange cannot compute this for you
Every exchange's "gains" tab has the same blind spot: it only knows about coins that were bought and sold on that exchange.
Go back to the opening scenario. Buy 1 BTC on Coinbase for $30,000, withdraw it to Kraken, sell it there for $50,000. From Kraken's point of view, 1 BTC arrived from nowhere and was sold for $50,000. Kraken has three bad options: show a $50,000 gain (zero basis), show a $0 gain (basis equals deposit-day price), or show nothing. From Coinbase's point of view, you still hold that coin. Both reports are internally consistent and both are wrong.
This is not laziness; the exchanges genuinely do not have the data. US exchanges began sending Form 1099-DA for 2025 sales (proceeds only); cost basis appears only for coins bought and kept on that same platform from 2026 onward, so a deposit from an external wallet arrives without its history attached and your own wallet-level records remain the source of truth. The only party that can link the Coinbase purchase to the Kraken sale is you, which makes cross-account cost basis a bookkeeping job that sits above the exchanges: every buy, sell, and transfer from every venue in one timeline, under one method.
The two mistakes that break most people's numbers
Mistake 1: ignoring fees
Skipping fees always moves your numbers against you: you overstate gains and understate losses. In the example, computing the June sale without fees gives a FIFO gain of $16,000 instead of $15,936. Sixty-four dollars is small. Across a few hundred trades on an exchange charging 0.1% to 0.5% per side, it is not.
Rule of thumb: a fee paid in cash gets added to basis (on a buy) or subtracted from proceeds (on a sell); on a US crypto-to-crypto swap the whole fee counts against the coin you gave up. A fee paid in the crypto itself, which is common for withdrawals, is a small disposal of that coin at its market value that day, and the amount that arrives is smaller than the amount you sent. Whether a fee on a transfer between your own wallets can then be added to your cost basis is something the IRS, HMRC and CRA have not addressed; most tax tools treat it conservatively as neither deductible nor basis-increasing.
Mistake 2: missing or mismatched transfers
A transfer between your own accounts is not a sale and not a purchase. If your records treat the withdrawal as a sale and the deposit as a buy, you invent a taxable event and reset the holding period on coins you never sold. If your records drop the transfer entirely, the receiving account has coins with no basis, which is the $50,000-gain problem above.
The fix is to match each withdrawal to its corresponding deposit and carry the original lots across. The tell-tale sign of an unmatched transfer is a coin balance on one account that goes negative, or one that appears with no purchase behind it. Network fees make exact matching fiddly: you send 0.5 BTC, 0.4995 arrives, and the 0.0005 difference is the fee, not a rounding error.
Smaller ones that still bite
- Crypto-to-crypto trades. Swapping ETH for SOL is a sale of ETH and a purchase of SOL at that moment's fair value, not "still invested."
- Mixing methods mid-stream. FIFO for one sale and average cost for the next leaves a remaining basis that belongs to neither.
- Wrong currency. Bought in EUR, reporting in USD? Convert each trade at that day's rate, not today's.
Doing it by hand, in a spreadsheet, or with software
For a handful of trades a year on one exchange, I honestly think a spreadsheet is the best tool. One sheet of lots, one sheet of sales, a FIFO column you fill in by hand. You will understand every number, and it costs nothing.
In my experience it breaks down at roughly two or more exchanges plus a self-custody wallet, a few dozen trades, and transfers between them. Matching transfers by hand and consuming partial lots across years is where errors creep in.
Hosted crypto tax services exist for exactly this and are good at it: API sync, DeFi and NFT handling, country-specific filing forms. The trade-off is the pricing model. All three major ones charge per tax year, tiered by transaction count.
| Service (as of Aug 2026) | Entry paid tier | Middle tier | Source |
|---|---|---|---|
| CoinLedger | $49 for up to 100 transactions | $99 for up to 1,000 | coinledger.io pricing page, checked Aug 2026; one-time purchase per tax year |
| Koinly | $49 for up to 100 transactions | $99 for up to 1,000 | As reported in 2026 reviews by Milk Road and CryptoAdventure; per tax year |
| CoinTracker | $59 for up to 100 transactions | $199 for up to 1,000 | As reported by Comparedge's pricing tracker, July 2026; per tax year |
Prices move, and the Koinly and CoinTracker figures are second-hand, so check the vendors' pages before deciding. The structural point is stable: you pay again every tax year, and a busier year pushes you into a pricier tier.
Where Holdbound fits, and who should not use it
Your trades stay on your computer. Pay once.
Full disclosure: I build Holdbound, so read the product parts with that in mind. It is a single HTML file you download from https://holdbound.com/download and open in your browser. There is no account, no server, and no API key; I built it to keep your trade data in your browser (IndexedDB) on your own machine, with one-click JSON backup and restore. It works offline apart from the refresh you ask for, which fetches live prices from CoinGecko and, in the same action, a small version file from my site so it can tell you a new release exists. It imports CSV exports from Binance, OKX, Coinbase, and Kraken (plus a generic template), matches transfers between your accounts with a manual override, and computes FIFO or average cost with fees included. You get realized and unrealized P&L, a trade journal with notes, a holding-period view comparing realized P&L on trades held under 7 days against those held over 90 days (performance windows, not tax categories), and a CSV export plus an annual realized-gains summary you can hand to whoever prepares your return.
I built it to do exactly the bookkeeping job in this article and deliberately nothing more. The full app is free for 30 days; after that it is $29 once. Every version released in the following 12 months is yours to keep and keeps working forever; renewing for more updates is $15 a year and optional. If the trial ends without a purchase the app goes read-only — you can still open it, view everything and export all your data; only adding transactions and refreshing prices stop. That is the only case: once you have paid, nothing is ever switched off, including if you let the optional renewal lapse. You cannot add new transactions or refresh prices. Renewing, or buying the one-time license, restores full use.
You should not use it if:
- You need country-specific tax forms generated for you. It exports raw data and yearly summaries only. Koinly, CoinTracker, and CoinLedger do forms; Holdbound does not.
- You are active in DeFi, NFTs, staking protocols, or liquidity pools. It parses spot trades and transfers only, and I have no plans to change that in v1.
- You trade margin or futures. Spot only.
- You want API auto-sync and never want to touch a CSV. I made it import-based on purpose, so nothing ever connects to your exchange accounts.
- You have a dozen trades a year on one exchange. Use the spreadsheet. Seriously.
If you are a buy-and-hold investor with a few exchanges and a cold wallet who wants correct FIFO numbers without an annual bill, I think it is a good fit. If your situation is more complicated than that, it probably is not.
FAQ
Is FIFO the best cost basis method for crypto? "Best" depends on your goal and your jurisdiction. In the US it is the default whenever you have not specifically identified lots with contemporaneous records, and since 2025 it is applied wallet-by-wallet. In a rising market FIFO recognizes larger gains sooner because it sells your oldest, usually cheapest, coins first; it also tends to make more of your sales long-term (held more than one year, counted from the day after purchase).
Can I switch from average cost to FIFO? Mechanically, yes, but only by recomputing your entire history under the new method; otherwise the remaining basis is inconsistent. Whether you are allowed to switch, and how often, is a jurisdiction question, so check with a professional first. For US filers, average cost was never a recognized crypto method, so the real job is rebuilding your history under FIFO or specific identification; in Canada the weighted-average adjusted cost base is mandatory, and in the UK the same-day and 30-day matching rules followed by the Section 104 pool are, so there is nothing to switch to.
How do I calculate cost basis for crypto transferred between wallets? A transfer between accounts you control is not a sale. Carry the original purchase date and cost over to the receiving account, and treat any network fee paid in the coin as a small disposal at that day's price. Never let the deposit appear as a new purchase at zero cost.
Do fees count toward cost basis in crypto? Yes. Fees paid to acquire an asset are added to its cost basis; fees paid to sell are subtracted from proceeds. Ignoring them always overstates your gain.
Why doesn't Coinbase (or Kraken, or Binance) show my correct gains? Because each exchange only sees trades made on that exchange. Anything you deposited from elsewhere arrives with no purchase history, so the exchange either guesses or leaves the basis blank. Only a record that spans all your accounts can compute it correctly.
This article is for general information only — not financial or tax advice.