# How to backfill years of minute bars

US minute history comes as a paginated API, a flat-file drop or a one-off CSV purchase. Adjustment, delisted tickers and the licence decide it.

*https://stockmarketstack.com/how-to/backfill-minute-bars · next to Stock Market Data APIs*

**Answer:** Minute bars for US equities are sold three ways: paginated from an API, downloaded as flat files, or bought once as zipped CSV. Alpaca reaches back to 2016 for free on one exchange; FirstRate Data and Kibot sell decades of it outright. What decides the purchase is not the price but the adjustment, the delisted tickers and the licence you get with them.

## The tools that do this

*In the order this page recommends trying them. Paid placement does not affect this order.*

1. [Alpaca Market Data](https://stockmarketstack.com/tools/alpaca-market-data.md) — Minute bars from 2016 over paginated REST. The free tier is IEX only, so its volumes are one venue's; $99 a month buys the consolidated tape.
2. [Massive](https://stockmarketstack.com/tools/massive.md) — Minute aggregates plus S3 flat files from $29 a month, but the history window is what the tier buys — 5 years at Starter, 20+ at Advanced.
3. [FirstRate Data](https://stockmarketstack.com/tools/firstrate-data.md) — One payment for 1-minute bars from January 2000 across 16,304 tickers, roughly 7,000 delisted, unadjusted and adjusted series side by side.
4. [Kibot](https://stockmarketstack.com/tools/kibot.md) — The same shape reaching back to 1998, three parallel series per ticker — but the vendor's own answer on survivorship bias is 'partially'.
5. [Databento](https://stockmarketstack.com/tools/databento.md) — Exchange-sourced bars billed by the uncompressed gigabyte with no minimum term. The right shape for one month of one symbol, not an archive.
6. [AlgoSeek](https://stockmarketstack.com/tools/algoseek.md) — Leased 90-field minute bars from 2007 with delisted names included, from $1,500 a month on a twelve-month term. No exchange fees on history.

## The short way

If you want US equity minute bars going back to 2016 and you are willing to paginate for them,
[Alpaca](https://stockmarketstack.com/tools/alpaca-market-data) is the shortest route with a free key:

```python
from alpaca.data.historical import StockHistoricalDataClient
from alpaca.data.requests import StockBarsRequest
from alpaca.data.timeframe import TimeFrame
from datetime import datetime

client = StockHistoricalDataClient("YOUR_API_KEY", "YOUR_SECRET_KEY")

request = StockBarsRequest(
    symbol_or_symbols=["SPY"],
    timeframe=TimeFrame.Minute,
    start=datetime(2016, 1, 1),
    end=datetime(2016, 2, 1),
)

bars = client.get_stock_bars(request).df    # multi-index DataFrame
```

Underneath it is one REST endpoint, and the three parameters that decide what you get back are
easier to see there than through the client:

```text
GET https://data.alpaca.markets/v2/stocks/bars
    ?symbols=SPY
    &timeframe=1Min
    &start=2016-01-01
    &end=2016-02-01
    &adjustment=all        # raw | split | dividend | spin-off | all
    &feed=sip              # sip | iex | boats | otc
    &limit=10000
    &page_token=<from the previous response>
```

`limit` caps at 10,000 and the documentation is explicit that it counts data points across every
symbol rather than per symbol, so a multi-symbol request is not ten times the page. Anything
longer comes back with a `next_page_token` you hand straight back as `page_token`. That loop is
the whole job, and it is also the whole problem: a regular US session is 390 minutes, so one
ticker-year is about 98,000 bars and ten pages, and a thousand tickers over ten years is a script
that runs for days.

`adjustment` and `feed` are the two that quietly change the numbers rather than the volume of
them. Both are discussed below.

## What the options are

**Paginate an API.** [Alpaca](https://stockmarketstack.com/tools/alpaca-market-data) as above: stock history to 2016 on both
plans, no flat files and no Parquet, so a backfill is JSON pages and nothing else. The free plan
is the IEX feed alone and the paid one is $99 a month for the consolidated tape; a brokerage
account and its onboarding are mandatory either way.

**Flat files on a subscription.** [Massive](https://stockmarketstack.com/tools/massive) — the vendor that traded as
Polygon.io until October 2025 — serves minute aggregates over REST and the same data as flat
files over an S3-compatible interface, which is the difference between ten thousand requests and
one `aws s3 sync`. Read the history window rather than the headline price: Basic is free and
holds two years, Starter at $29 a month holds five, Developer at $79 ten, and the 20-plus-year
archive starts at Advanced, $199. The $29 and $79 tiers are 15-minute delayed, which does not
matter for a 2019 backfill and matters a great deal if the same key is also feeding something
live.

**Buy the archive once.** [FirstRate Data](https://stockmarketstack.com/tools/firstrate-data) sells zipped CSV you keep:
1-minute, 5-minute, 30-minute, hourly and daily bars, stocks and ETFs from January 2000, at
$599.94 for 16,304 stock tickers or $839.94 for the combined bundle. [Kibot](https://stockmarketstack.com/tools/kibot) is the
same shape a little further back — minute and daily bars from 1998, gzipped CSV, $990 for all US
stocks and ETFs. Both ship unadjusted and adjusted series side by side, which is the feature that
matters most and is invisible on a pricing page. Neither is sliceable: a FirstRate bundle is
organised by ticker range and always carries the full history, so there is no way to ask for one
symbol or one year out of it.

**Meter it by the byte.** [Databento](https://stockmarketstack.com/tools/databento) has no subscription floor on historical
data and bills the uncompressed gigabyte, which makes it the only sensible purchase when the
requirement is one month of forty symbols rather than an archive. Bars are aggregated from the
same exchange feed the live product reads, and the historical and live clients return identical
record types.

**Lease the researched version.** [AlgoSeek](https://stockmarketstack.com/tools/algoseek) leases US equity data from 2007 —
delisted names included — with minute bars carrying up to 90 fields rather than plain OHLCV:
VWAP, trade count, buy and sell pressure, spread statistics. It comes with a security master that
follows a ticker through mergers and delistings, and nightly-recalculated adjustment factors. It
is $1,500 a month for a single dataset on a twelve-month minimum, and when the term ends you
delete the files.

The split in that list is one decision, not five. An API is cheap to start and expensive to
finish; a bought archive is the reverse. Everything else follows from which end of that you are
on.

## Where this breaks

**The exchange licence is not in the vendor's price.** US consolidated equity prices are
administered under plans with their own published charge list, and on the schedule as published
the numbers are the exchange's rather than any vendor's: $45 a month per display device for a
professional subscriber using one or two of them, $1.00 a month per non-professional subscriber,
$2,000 a month for non-display use of Network A last-sale information and the same again for
quotation information, and $1,000 a month for redistribution on each network. None of that is
avoidable by choosing a cheaper reseller, because none of it is the reseller's money.

For a backfill the good news is that most of it does not apply: AlgoSeek states that its
historical data carries no exchange fees in any asset class, and the one-time vendors sell an
archive rather than a feed. What survives is redistribution, and it survives inside the vendor's
own licence rather than the exchange's. FirstRate Data permits derived charts and analysis and
forbids handing users raw rows, and is explicit that dropping the volume column does not help.
Kibot grants internal use on two computers and says the restriction outlives cancellation.
Alpaca answers it in one line: you cannot redistribute Alpaca API data. If anything downstream of
your database is a chart other people can see, that is the clause to read first.
[Why real-time stock data is so expensive](https://stockmarketstack.com/guides/real-time-market-data-fees) has the mechanics
of the live side.

**Adjusted bars are a view, not a fact.** Alpaca's `adjustment` parameter takes `raw`, `split`,
`dividend`, `spin-off` and `all`, and the values combine. That flexibility is the warning: a
series pulled with `adjustment=all` is computed against the corporate-action history *as it
stands today*. Store it, wait for a 4-for-1 split, and every row you already wrote is now wrong
by a factor of four relative to a fresh pull — not because anybody made a mistake, but because
the question "what did this trade at" was answered in a currency that keeps being redenominated.
The fix is to store unadjusted bars plus the split and dividend table and adjust on read, which
is why FirstRate Data and Kibot both ship three parallel series and why reconciling against a
broker statement needs the unadjusted one. [Why adjusted close
differs](https://stockmarketstack.com/guides/why-adjusted-close-differs) is the long version.

**The tickers that stopped trading are the ones that matter.** A universe assembled from what
trades today has already removed every company that failed, and a backtest over it is measuring a
group selected for having survived. The vendors differ sharply here and say so. FirstRate Data
carries roughly 7,000 delisted names among 16,304, suffixed `-DELISTED` so a reused symbol does
not collide, while stating plainly that the universe is incomplete and thins with age. Kibot
answers the same question with "partially" — delisted names are included by how liquid they were
at delisting — and warns that one symbol file can hold two unrelated companies separated by a
gap. AlgoSeek includes delisted securities from 2007 and maintains a security master to keep them
distinct. If the question is index membership rather than mere existence,
[Norgate Data](https://stockmarketstack.com/tools/norgate-data) does that job at daily resolution and
[historical index constituents](https://stockmarketstack.com/guides/historical-index-constituents) explains why it is a
separate purchase.

**Sessions are a boundary you have to choose, not one you inherit.** NYSE's own calendar puts the
core session at 9:30 a.m. to 4:00 p.m. ET, order entry in the pre-opening session from 6:30 a.m.,
and a late session of 4:00 p.m. to 8:00 p.m. on NYSE American, NYSE Arca, NYSE National and NYSE
Texas rather than on the Tape A market itself. Vendors draw their own lines inside that. Kibot
ships pre-market from 8:00 AM and after-hours to 6:30 PM ET, and says filtering is looser outside
the regular session so spikes get through. FirstRate Data timestamps the start of each bar in US
Eastern — except crypto, which is UTC — and omits zero-volume bars entirely, so a gap means no
prints rather than missing data. Alpaca puts overnight activity behind a separate `boats` feed
value. Three consequences follow: your 09:30 bar may or may not include the opening auction, your
bar count per day is not constant, and two vendors' "daily volume" will differ by whatever each
decided extended hours meant. Pick one definition, write it down, and filter at load time rather
than at query time.

**The files are larger than the estimate.** FirstRate Data's stock bundle is 28 GB zipped and the
combined bundle 40 GB; Databento's own documentation tells you to move from streaming to batch
download past 5 GB. A billion rows is not a CSV directory and it is not a Postgres table either.
[Storing tick data without regretting it](https://stockmarketstack.com/guides/storing-tick-data) covers the shapes that work,
and [ArcticDB](https://stockmarketstack.com/tools/arcticdb), [QuestDB](https://stockmarketstack.com/tools/questdb) and [DuckDB](https://stockmarketstack.com/tools/duckdb) are the
cards behind it. Decide the storage layer before the download, because re-ingesting 40 GB because
you partitioned by symbol instead of by date is a weekend.

## If you outgrow this

**When you need somewhere that is not the United States**, everything above stops.
[Tick Data](https://stockmarketstack.com/tools/tickdata) is the card that goes furthest: roughly thirty equity markets on
five continents, sold by the symbol-year under a perpetual licence, with London from January
2000, Euronext from April 2002 and Tokyo, Hong Kong, Sydney and São Paulo from 2008. The minimum
order is $1,000 for a new client.

**When a bar stops being enough**, the next thing is the tape itself — trades and quotes, from
which you can build any bar you like and answer questions a bar cannot, such as where inside the
spread a print landed. [Databento](https://stockmarketstack.com/tools/databento) and [AlgoSeek](https://stockmarketstack.com/tools/algoseek) both sell
it, and both will tell you that US equities have no order book to buy: the consolidated tape is
top-of-book, so depth exists in futures and nowhere else.

**When the backfill becomes a pipeline**, the job stops being a download and starts being
storage, scheduling and reconciliation. That is [tick data storage](https://stockmarketstack.com/categories/tick-data-storage)
rather than this page.

**If daily bars would have done**, they usually would have, and they are three orders of
magnitude smaller — [how to download historical prices in
Python](https://stockmarketstack.com/how-to/download-historical-prices-in-python) is the cheaper version of this question.

The rest of the field is in [market data APIs](https://stockmarketstack.com/categories/market-data-apis).

## FAQ

### How much disk does a decade of US minute bars actually take?

Tens of gigabytes compressed for a broad equity universe, and that is before you store more than one adjustment. FirstRate Data's stock bundle is 28 GB zipped and its combined bundle 40 GB; its tick archive, which is a different product, is 2.4 TB. A regular session is 390 minutes, so one ticker-year is roughly 98,000 rows and a 10,000-name universe is a billion rows a decade. CSV in a directory stops being workable long before that.

### Should I store adjusted or unadjusted bars?

Unadjusted, plus the corporate-action table, and adjust on read. An adjusted series is a view computed from a split and dividend history that keeps changing, so the file you wrote last year and the file you write today will disagree about the same session. FirstRate Data and Kibot both ship unadjusted and adjusted series in parallel precisely so you can reconcile the two.

### Can I resell or republish the minute bars I bought?

Almost certainly not, and the restriction usually survives the purchase. FirstRate Data permits derived charts and analysis but not handing users raw rows, and says removing the volume column does not change that. Kibot's licence is internal use on two computers and outlives cancellation. Alpaca states plainly that its API data cannot be redistributed. Read the licence before the price list.

### Is a free minute-bar feed good enough to backtest on?

It depends entirely on which venue it came from. Alpaca's free plan is IEX only, and Alpaca's own worked example has IEX carrying 12,630 of a day's 535,136 Apple trades — so the volume, the VWAP and the high and low of those bars are one venue's, not the market's. For learning the request shape it is fine. As a price series it is a different instrument.

## Sources

1. [Historical stock bars — API reference](https://docs.alpaca.markets/reference/stockbars) — Alpaca, read 2026-09-21
2. [Market data — alpaca-py documentation](https://alpaca.markets/sdks/python/market_data.html) — Alpaca, read 2026-09-21
3. [Schedule of Market Data Charges](https://www.ctaplan.com/publicdocs/ctaplan/Schedule_of_Market_Data_Charges.pdf) — Consolidated Tape Association, read 2026-09-21
4. [Holidays and Trading Hours](https://www.nyse.com/trade/hours-calendars) — New York Stock Exchange, read 2026-09-21

*Last updated 2026-09-21. A reference page, corrected in place — not a dated post.*
