COPY INTO or Snowpipe, or pull from a market data API with a Python
pipeline. A Marketplace listing is the fastest. The data appears as a
read-only database in your account within minutes, with nothing to build
or maintain.
Loading files or running your own API pipeline gives you full control, but
you also take on keeping the adjusted price history correct.
The short answer
The rest of this post walks through each option, with SQL and the gotchas
that usually show up a few months in.
Option 1: Subscribe to a Snowflake Marketplace listing
Marketplace data is delivered through Snowflake’s secure data sharing. The provider’s tables show up as a database in your account. Nothing is copied, you don’t pay storage for it, and each day’s refresh appears without you doing anything. You only pay for the warehouse compute your queries use, plus the listing’s price if it’s a paid listing.1
Find the listing
Search the Snowflake Marketplace for stock price data. The Historical Stock Prices listing covers 50,000+ US stocks, ETFs and mutual funds with raw and adjusted OHLC back to each security’s listing date.
2
Get it
Click Get, choose the database name the listing will be mounted as (for example
STOCK_PRICES), and pick which roles can access it.3
Query it
Select that database and its schema in a worksheet and query the views directly.
- Coverage. Some listings cover only large caps such as the S&P 500. Others include small caps, ETFs and mutual funds. The Historical Stock Prices listing has about 18,500 stocks, 5,950 ETFs and 25,800 mutual funds in one table.
- History depth. Some listings start at a fixed year. Others go back to each security’s first trading day.
- Adjusted prices. Check that adjusted OHLC is included, and that the adjusted history is restated when splits and dividends post. See Adjusted Close vs. Close for why this matters.
- Delisted securities. If you backtest, check whether delisted tickers are included. Most listings, including ours today, cover securities currently listed, which introduces survivorship bias over long periods.
- Refresh time and price. Check when each day’s data lands and whether pricing is flat-rate or usage-based. Historical Stock Prices is $100/month flat, refreshed daily at 5:00 AM Pacific.
Option 2: Load files from cloud storage
If your vendor delivers flat files (CSV or Parquet) to a bucket, Snowflake can load them directly. Create a target table, point a stage at the bucket, and runCOPY INTO:
COPY INTO keeps load metadata and skips files it has already loaded, so
rerunning it is safe. The flip side is that if your vendor resends a
corrected file under the same name, it’s silently skipped. Have restated
files land under new names (a dated folder works well), or reload them with
force = true into a staging table.
To load new files automatically as they arrive, wrap the same COPY INTO
in a pipe with event notifications on the bucket:
Already have the raw data as a CSV? Upload it directly
If you already have price history in a CSV, for example an export from a vendor or a broker, you don’t need a bucket at all. In Snowsight, open the target table and use Load Data to upload the file through the browser. From SnowSQL or the Snowflake CLI,PUT the file into the table’s own
stage and copy it in:
MERGE them into the main table:
Option 3: Pull from a market data API
With no file feed available, the usual route is a Python job. It calls a market data API per ticker or in bulk, builds a DataFrame and writes it to Snowflake withwrite_pandas. Schedule it with Airflow, Dagster or a cron
job.
MERGE as above to move the staging table into
daily_prices.
Plan for this work before committing to an API pipeline:
- Rate limits. Free tiers often allow only tens to a few hundred calls a day. A full US backfill of tens of thousands of tickers needs a bulk endpoint or many days of throttled calls.
- Universe maintenance. New listings, ticker changes and delistings happen every week. Without a refreshed symbol list, the table drifts away from the market.
- Corporate actions. Detect new splits and dividends and refetch those securities’ full history, or adjusted prices go stale (see Option 2).
- Bad rows. Watch for zero or placeholder prices, duplicate days and stub rows before the real trading history begins. These break returns quietly.
- Licensing. Many free APIs, including unofficial Yahoo Finance wrappers, are for personal use only. Check the terms before loading the data into a shared warehouse.
Check your load
Whichever method you pick, run these two checks before trusting the data. First, there should be exactly one row per ticker per day:Which should you choose?
- You want to analyze prices, not maintain a pipeline: use a Marketplace listing.
- You already pay for a vendor’s flat-file feed: load the files from
storage with Snowpipe, and
MERGEfull-history refreshes. - You need a custom universe or a vendor with no Snowflake delivery: build the API pipeline, and budget time for corporate actions and monitoring.
F.A.Q.
Is there free historical stock price data in Snowflake?
Is there free historical stock price data in Snowflake?
Yes, you can try it free. The Historical Stock Prices listing comes with a free 30-day trial, so you can query the full dataset (50,000+ US stocks, ETFs and mutual funds with raw and adjusted history) before paying anything. After the trial it’s $100/month flat.
Do I pay storage for Marketplace data?
Do I pay storage for Marketplace data?
No. Shared data stays in the provider’s account and is mounted into yours as a read-only database. You pay only for the compute your queries use, plus the listing’s subscription if it has one.
Can I get ETF and mutual fund prices the same way?
Can I get ETF and mutual fund prices the same way?
Yes. The Historical Stock Prices listing keeps stocks, ETFs and mutual fund NAVs in the same table. Filter by
asset_class in security_vw (stock, etf or fund).Can I join Marketplace stock data with my own tables?
Can I join Marketplace stock data with my own tables?
Yes. A mounted listing is queried like any other database, so you can join it to your holdings, transactions or other Marketplace data such as FRED economic series in the same query.
Is this real-time data?
Is this real-time data?
No. Everything in this post is end-of-day data, one row per security per trading day. Intraday or real-time feeds need a streaming vendor and a different setup.