Skip to main content
By Fruit Stand Team · October 31, 2026 · Guides There are three ways to get historical stock prices into Snowflake: subscribe to a Snowflake Marketplace listing, load files with 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.
Once it’s mounted, the 10-year total return of three tickers is one query:
Check these points when comparing stock price listings:
  • 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 run COPY 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:
The downside is that a CSV is a snapshot. It stops at the last day in the file, so every time you want newer prices you have to get a new file and upload it again. That’s fine for a one-off analysis, but for anything that needs current prices, use a scheduled load or a Marketplace listing that refreshes for you. The catch: append-only loading gets adjusted prices wrong. Every split or dividend changes the adjusted price of every earlier day for that security. A pipe that only appends new days leaves stale adjusted history in place. Returns then jump on ex-dividend dates. Plan to land full-history refreshes in a staging table and 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 with write_pandas. Schedule it with Airflow, Dagster or a cron job.
Then run the same 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:
Second, every ticker should be current:
The first query should return nothing. The second lists tickers that have stopped updating. They may be delisted or renamed, or a load may have failed.

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 MERGE full-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.

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.
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.
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).
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.
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.
To skip building the pipeline, start a free 30-day trial of the Historical Stock Prices listing on the Snowflake Marketplace. It has daily raw and adjusted OHLC for 50,000+ US stocks, ETFs and mutual funds, refreshed every morning. The schema and more queries are in the dataset docs. Questions? Reach out at contact@fruitstand.dev.