Crypto Tax Spreadsheet: A Minimal Layout That Works (and Where It Breaks)
It is the week before your filing deadline. You have a Coinbase CSV, a Kraken CSV, a half-remembered transfer to a hardware wallet, and a vague sense that you sold some ETH last spring. You open a blank sheet and start typing dates. Two hours later you have a crypto tax spreadsheet that mostly works, a column called gain??, and no idea whether the 0.3 ETH you sold on Kraken was the 0.3 ETH you bought on Coinbase in 2023 or the one you bought in 2025.
That is the gap I want to close here. Below is a minimal column layout that actually holds up, an honest description of when a spreadsheet is the right tool, and the three specific places it stops being one. At the end I'll explain where a local, single-file tool like Holdbound fits between "spreadsheet" and "pay-every-tax-year SaaS", including who should not bother with it. Full disclosure: I build Holdbound, so read the product parts with that in mind. The spreadsheet parts stand on their own.
When a spreadsheet is genuinely the right tool
A spreadsheet is the correct choice, not a compromise, if most of these are true:
- You trade on one exchange, or at most two.
- You made fewer than roughly 50 taxable events in the year (sells, swaps, spending crypto).
- You rarely move coins between accounts, or you move them in whole, easy-to-match chunks.
- You want to understand every number, not just trust one.
In that situation a sheet is cheaper, more transparent, and more auditable than anything else. An accountant can read it without a login. Don't let anyone talk you out of it.
The minimal crypto tax spreadsheet layout
The mistake almost everyone makes (I made it too, for two tax years) is to build one wide "trades" table and try to compute gains in the same rows. That works until the first partial sale. The layout that holds up has three tabs, and the first one is deliberately boring.
Tab 1: Transactions (one row per leg, never per "trade")
| Column | Example | Why it's there |
|---|---|---|
date_utc | 2025-03-14 09:22:10 | Use UTC for everything. Exchanges export in different zones and you will otherwise mis-order same-day trades. |
account | Kraken | The exchange or wallet the asset sat in. Needed for per-account lots (see below). |
type | buy / sell / transfer_out / transfer_in / fee | Keep the vocabulary tiny. Swaps are a sell row plus a buy row. |
asset | ETH | The thing whose quantity changes. |
qty | 0.3 | Positive for inflows, negative for outflows. Signed numbers make reconciliation formulas trivial. |
usd_value | 585.40 | Fair market value of this leg at the time, in USD. For a buy, what you paid; for a sell, what you received. |
fee_asset / fee_qty / fee_usd | ETH / 0.0005 / 0.98 | Fees deserve their own columns. Folding them into usd_value is where most sheets silently go wrong. |
ref | KRK-TX-88213 | Exchange transaction ID or on-chain hash. Your only hope of matching transfers later. |
notes | moved to Ledger | Free text. Future-you will be grateful. |
Two rules that make this tab work:
- A swap is two rows. Selling ETH for SOL is a
sell ETHrow (proceeds = USD value at that moment) and abuy SOLrow (cost basis = the same USD value). Trying to represent it as one row is how people lose the ETH disposal entirely. - Never compute gains here. This tab is a ledger. It should be possible to sort it, filter it, and sum
qtyper asset per account to get your current balance. If that sum doesn't match what the exchange shows, something is missing, and you have found out now rather than in April.
Tab 2: Lots
Every buy or transfer_in row becomes a lot:
lot_id | account | asset | acquired | qty_original | qty_remaining | cost_total_usd | cost_per_unit |
|---|---|---|---|---|---|---|---|
| L-0041 | Coinbase | ETH | 2023-11-02 | 1.0 | 0.7 | 1,850.00 | 1,850.00 |
cost_total_usd includes the purchase fee. qty_remaining is the column you decrement when you sell.
Tab 3: Disposals
Every sell (and every spend, and every fee paid in crypto) gets one row per lot consumed:
date | asset | qty | proceeds_usd | lot_id | cost_basis_usd | gain_usd | holding_days |
|---|---|---|---|---|---|---|---|
| 2025-03-14 | ETH | 0.3 | 584.42 | L-0041 | 555.00 | 29.42 | 498 |
Proceeds are net of the sell fee. holding_days is date - acquired from the matched lot; you'll want it because in the US a gain is long-term only if you held the coins more than one year, counting from the day after purchase, and long-term and short-term gains are taxed differently (the UK and Canada have no such distinction). The annual summary you give your accountant is just this tab, filtered by year, with the gains column summed in two buckets.
If you only ever buy on one exchange and sell whole lots, you can fill Tab 3 by hand in an evening. That is the good case.
The three places a crypto tax spreadsheet breaks down
1. Transfers between your own accounts
Moving 0.5 BTC from Coinbase to a hardware wallet is not a sale. But your Coinbase export shows an outgoing 0.5 BTC, your wallet shows an incoming 0.4998 BTC (network fee), and nothing in either file says "these are the same event." You have to match them yourself, by date, amount, and ideally transaction hash.
With five transfers a year this is a ten-minute job. With fifty, across four accounts, with amounts that never quite match because of network fees, it becomes the biggest source of errors in DIY crypto accounting; in my own sheets it was where every reconciliation mismatch traced back to. Miss one and your sheet either invents a taxable sale (overstating gains) or creates coins out of nothing (understating them).
This got harder in 2025. Under the IRS's 2024 final regulations, from January 1, 2025 cost basis must be tracked wallet-by-wallet (or exchange-account-by-account) rather than across all your wallets as one pool; Rev. Proc. 2024-28 gave a one-time safe harbor to assign pre-2025 lots to the wallets that held them. A transfer now has to carry its original lot (acquisition date and cost) from one account's lot table to another's, which in a spreadsheet means manually splitting and copying lot rows every time you move coins. Check the details with a tax professional, but the practical consequence is that Tab 2 needs an account column and you need to keep it honest.
2. FIFO across many lots
FIFO is easy to describe: the coins you sell are the oldest coins you own. It is miserable to do in a sheet once one sale spans several lots.
Say you bought ETH in eleven separate dollar-cost-average purchases, then sold 2.5 ETH. That sale might consume lot 1 entirely, lot 2 entirely, and 0.3 of lot 3. Your Disposals tab needs three rows with three different cost bases and three different holding periods, and lot 3's qty_remaining must be decremented so the next sale starts from the right place.
Spreadsheet formulas can do this, but they are fragile SUMIFS/INDEX constructions that break when you insert a row or sort the wrong tab. Most people do it by hand, which works until the second year, when you carry forward partially consumed lots and the sheet has 400 rows. At that point the error rate climbs, and you can't tell which number is wrong.
Average cost is simpler to compute, but it is a mutual-fund rule and is not a recognized method for crypto in the US (the IRS recognizes specific identification or, by default, FIFO). Outside the US it may be exactly what your jurisdiction requires: Canada uses a weighted-average adjusted cost base per coin across everything you own, and the UK's Section 104 pool uses a pooled average after its same-day and 30-day matching rules. The spreadsheet doesn't know which one you're allowed to use.
3. Fees
Fees are small, numerous, and paid in three different ways: in the quote currency (USD), in the asset you're trading (BNB, ETH), or in a third asset (exchange tokens for a discount). Each needs different handling:
- A fee in USD just adjusts cost basis or proceeds (on a US crypto-to-crypto swap the whole fee counts against the coin you gave up).
- A fee paid in crypto is itself a disposal of that crypto, with its own tiny gain or loss.
- A network fee on a transfer between your own wallets does not turn the transfer into a sale, but if the fee is paid in crypto the fee coins themselves are a small disposal. Whether that fee can 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.
A year of trading produces hundreds of these. None matters individually; collectively they shift your gain by a few percent and make your balances stop reconciling. The spreadsheet doesn't break dramatically here. It just quietly drifts.
Spreadsheet vs. local tool vs. SaaS
| Spreadsheet | Local tool (Holdbound) | Cloud SaaS (Koinly, CoinTracker, CoinLedger) | |
|---|---|---|---|
| Cost | $0 | Free 30-day trial, then $29 once (updates included 12 months, $15/yr after that and optional) | Tiered by transaction count, per tax year (see below) |
| Where your data lives | Your machine | Your machine (browser IndexedDB + JSON backup) | Their servers |
| Exchange import | Manual paste | CSV import, auto-detected for Binance, OKX, Coinbase, Kraken, plus a generic template | API sync + CSV, hundreds of integrations |
| Transfer matching | By hand | Automatic with manual override | Automatic |
| FIFO across lots | By hand or fragile formulas | Built in (FIFO and average cost) | Built in, multiple methods |
| DeFi / NFT / staking parsing | By hand | Not supported | Supported (varies) |
| Tax forms (e.g. Form 8949) | You build them | No. Exports CSV and an annual realized-gains summary only | Yes, plus TurboTax integration |
| Best for | <50 events, one exchange | Spot traders on a few CEXs who want the math done locally | Active traders, DeFi users, anyone who wants a finished form |
On SaaS pricing, since it changes: as of August 2026, CoinLedger's own pricing page lists Hobbyist at $49 (up to 100 transactions), Investor at $99 (up to 1,000), and Pro at $199+ (3,000+), each a one-time purchase per tax year. For Koinly, CryptoAdventure's 2026 review reports $49 / $99 / $199 per tax year at 100 / 1,000 / 3,000+ transactions, with higher tiers above that. For CoinTracker, ComparEdge's listing (as of July 2026) shows Base $59 (100), Prime $199 (1,000), and Ultra $599 (10,000) per tax year. I could not load Koinly's and CoinTracker's own pages directly, so treat those two as reported, not confirmed, and check before buying. The pattern across all three is the same: the price roughly doubles each tier and you pay again every year.
Where Holdbound fits, and who should not use it
Your trades stay on your computer. Pay once.
Holdbound is a single HTML file you download from https://holdbound.com/download and open in your browser. I built it that way on purpose: no signup, no API keys, and nothing of yours on a server. The only time it goes online is the refresh you press: live prices from CoinGecko, and alongside them a small version file from my site that powers the update notice. You import your exchange CSVs (Binance, OKX, Coinbase and Kraken are auto-detected; there's a generic template for anything else), it matches transfers between your accounts and lets you override any match, applies FIFO or average cost, and gives you realized and unrealized P&L and a yearly realized-gains summary you can export to CSV for whoever does your taxes. Data lives in the browser's IndexedDB with a one-click JSON backup and restore.
It is, deliberately, the three tabs above with the hard parts automated and nothing else. The first 30 days are a free, full-featured trial. After that it is $29, once — and that buys the software, not a year of it: every version released in the following 12 months is yours to keep and keeps working forever. Updates after that are $15 a year and optional; skipping them takes nothing away. Read-only applies to one case only — a trial that ended without a purchase — and even then everything stays viewable and exportable.
You should not use it if:
- You use DeFi, NFTs, staking rewards, or airdrops in any volume. I don't parse them. A spreadsheet or a SaaS tool will serve you better.
- You trade margin or futures. Spot only.
- You want a finished tax form. It exports data and summaries; it never produces Form 8949 or any country-specific form, and it gives no tax advice.
- You want API auto-sync so you never touch a CSV. That's a SaaS feature, and a reasonable one to pay for.
- You have under a few dozen transactions on one exchange. Honestly, use the spreadsheet layout above. It's free and you'll understand it.
I built it for the people in the middle, because that's where I was: patient spot investors on two to four exchanges, a few hundred transactions a year, enough transfers and DCA lots that the sheet has started to lie, but not enough activity to justify paying per-transaction every year for features they won't use.
FAQ
Can I do my crypto taxes in Excel?
Yes, if your activity is simple: one or two exchanges, few transfers, and whole-lot sales. Use three tabs (transactions, lots, disposals), keep fees in their own columns, and reconcile balances per asset per account before computing any gains. It gets unreliable once sales span many lots or transfers are frequent.
Is there a free crypto tax spreadsheet template?
The column layout in this article is the template; copy the three tables into a blank sheet. Be wary of downloadable templates that compute FIFO for you with hidden formulas: if you can't follow the logic, you can't check it, and checking it is the whole point of doing this in a spreadsheet.
How do I calculate FIFO for crypto in Google Sheets?
Keep a lots tab with a qty_remaining column. For each sale, consume lots in acquisition order, writing one disposal row per lot touched and decrementing qty_remaining. Doing it by hand is reliable up to maybe a hundred lots; past that, use a tool, because the formula versions are too easy to break with a sort or an inserted row.
Do I need to track cost basis per wallet?
For US taxpayers, yes: since January 1, 2025 the IRS's final regulations require cost basis to be tracked wallet-by-wallet (or exchange-account-by-account) instead of across all wallets as one pool; Rev. Proc. 2024-28 was the one-time safe harbor for assigning pre-2025 lots to the wallets that held them. Canada is the opposite — one weighted-average pool per coin across everything you own — and in the UK each token type has a single Section 104 pool per person. That's why the layout above has an account column on the lots tab: it lets you keep per-account lots where required and still sum across accounts where a single pool is required. Confirm how this applies to your situation with a tax professional.
Is a crypto tax spreadsheet safer than online software?
Privacy-wise, yes: a local file never leaves your computer, and a SaaS tool by definition holds your full trade history on its servers. Accuracy-wise, it depends entirely on you. That's the trade I tried to make with Holdbound: keep the privacy property of a local file and take over the error-prone arithmetic.
This article is for general information only — not financial or tax advice.