Free vs Paid Stock APIs: Real Cost at 10K-1M Requests

Disclosure: As an Amazon Associate, I earn from qualifying purchases. Some links in this post are affiliate links — they cost you nothing extra.
⚡ Key Takeaways
  • yfinance is free but requires 15+ hours of retry logic and caching to handle 100K+ requests/month reliably
  • Polygon Starter ($29/month) beats Alpha Vantage Basic ($50) on both price and latency for real-time data up to 4.3M requests
  • At 1M requests/month, Polygon Developer ($99) is half the cost of Alpha Vantage Premium with faster response times
  • Engineering time to work around free tier rate limits typically costs $500-750 in labor, negating any API savings
  • Interactive Brokers TWS API offers free real-time data if you already pay for market subscriptions, but setup takes 4+ hours

The $0 Plan Will Cost You More Than the $50 One

Most developers pick a free stock data API, hit the rate limit after two weeks, then panic-migrate to a paid tier mid-production. I’ve watched this happen four times in the last year — always with the same shocked realization: the “free” plan was bleeding money through engineer time, retry logic, and half-baked caching.

Here’s the math nobody shows you upfront. A free API with 5 requests/minute sounds fine until you’re polling 20 tickers every 10 seconds. That’s 120 requests/minute. You’ll burn through rate limits in 25 seconds, then spend three days building a priority queue, debounce system, and Redis cache just to stay under quota. Meanwhile, a $50/month plan with 100K requests would’ve handled it out of the box.

This post compares five stock data APIs — yfinance, Alpha Vantage, Polygon, Marketstack, and Finnhub — at three usage tiers: 10K, 100K, and 1M monthly requests. I’ll show you the actual dollar cost, hidden fees, and engineering overhead at each level. The winner depends entirely on your request pattern, but the free tier is almost never the cheapest option when you factor in your time.

Close-up of a financial graph on a screen showing stock market trading data and trends.
Photo by AlphaTradeZone on Pexels

yfinance: Free Forever, But You’ll Pay in Other Ways

yfinance scrapes Yahoo Finance, so there’s no API key, no signup, no rate limits listed anywhere. It just… works. Until it doesn’t.

The problem is that Yahoo Finance occasionally blocks requests if you hammer it too hard. No clear threshold, no error message explaining why — your script just starts returning None for prices. The unofficial rate limit seems to be around 2000 requests/hour based on my testing, but it varies by IP and time of day.

import yfinance as yf
import time

# This works fine for small batches
tickers = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'TSLA']
data = yf.download(tickers, period='1d', interval='1m')
print(data.head())

At 10K requests/month, yfinance is unbeatable. That’s roughly 333 requests/day or 14 per hour — well under any soft limit. Cost: $0. Engineering overhead: minimal, just add a 1-second delay between tickers to be safe.

But at 100K requests/month (3,333/day, 139/hour), you’re in the danger zone. Yahoo might throttle you randomly. You’ll need:

  • Retry logic with exponential backoff (2-3 hours to implement)
  • Request caching to dedupe identical calls (4-6 hours for Redis integration)
  • Rotating user agents or proxy rotation if you get soft-banned (another 3-5 hours)

That’s 10-15 hours of engineering time. If your hourly rate is $50, that’s $500-750 in labor. The “free” tier just cost you more than a year of Alpha Vantage’s cheapest paid plan.

And at 1M requests/month? Forget it. You’ll get blocked within days. yfinance is not designed for production workloads at that scale.

Enjoying this article? Get more like it delivered to your inbox. Subscribe to the newsletter

Alpha Vantage: $50/Month Seems Expensive Until You Do the Math

Alpha Vantage’s free tier gives you 25 API calls/day and 5 calls/minute. That’s 750 requests/month — useless for anything beyond a toy project.

Their paid tiers:

  • Basic: $50/month, 120 calls/minute, 30K calls/day (900K/month)
  • Premium: $250/month, 600 calls/minute, 75K calls/day (2.25M/month)
  • Enterprise: Custom pricing, unlimited calls

At 10K requests/month, the free tier technically covers you (750 calls), but you’ll exhaust it in 3-4 days if you’re polling during market hours. The Basic plan feels like overkill — you’re paying $50 for capacity you won’t use.

But at 100K requests/month, Basic is perfect. You get 900K capacity for $500 so you’re paying $501 per request. No retry logic needed, no caching required, no rate limit gymnastics. Just call the API.

import requests
import os

API_KEY = os.getenv('ALPHA_VANTAGE_KEY')
url = f'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=AAPL&interval=1min&apikey={API_KEY}'

response = requests.get(url)
if response.status_code == 200:
    data = response.json()
    print(data['Time Series (1min)'])
else:
    print(f"Error: {response.status_code}")

At 1M requests/month, you’d need Premium ($502) since Basic caps at 900K. That’s $503 per request — still reasonable if you’re pulling real-time intraday data for 50+ tickers.

The hidden cost? Alpha Vantage’s API is slow. Average response time is 800-1200ms in my experience, compared to 200-400ms for Polygon. If you’re building a low-latency trading bot, that delay matters. And yes, I covered this in detail comparing latency across providers.

Polygon: The Developer-Friendly Option That Scales

Polygon is the API I reach for when I’m building something that might actually grow. Their pricing is transparent, documentation is excellent, and response times are consistently under 300ms.

  • Free: 5 calls/minute (7,200/month)
  • Starter: $504/month, 100 calls/minute (4.32M/month)
  • Developer: $505/month, 1000 calls/minute (43.2M/month)
  • Advanced: $506/month, 5000 calls/minute (216M/month)

At 10K requests/month, the free tier covers you with room to spare. But unlike yfinance, Polygon enforces rate limits strictly — you get a 429 status code if you exceed quota, which makes error handling straightforward.

import requests
import time

API_KEY = os.getenv('POLYGON_API_KEY')
url = f'https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/minute/2023-01-09/2023-01-09?apiKey={API_KEY}'

response = requests.get(url)
if response.status_code == 429:
    print("Rate limit hit, waiting 60 seconds...")
    time.sleep(60)
    response = requests.get(url)

data = response.json()
print(data['results'][:5])

At 100K requests/month, Starter ($507) is the best deal here. You get 4.32M capacity for less than Alpha Vantage Basic, and the API is faster. The only downside: Polygon’s free and Starter tiers have a 15-minute delay on market data. If you need real-time quotes, you’re forced into Developer ($508).

At 1M requests/month, Developer handles it easily at $509 — half the cost of Alpha Vantage Premium. This is where Polygon wins on pure economics.

Marketstack: The Budget Option Nobody Talks About

Marketstack is a lesser-known player with ridiculously cheap pricing:

  • Free: 100 calls/month
  • Basic: $500/month, 10K calls/month
  • Professional: $501/month, 100K calls/month
  • Business: $502/month, 500K calls/month

At 10K requests/month, Basic ($503) is the cheapest paid option by far. That’s $504 per request — 10x cheaper than Alpha Vantage.

The catch? Marketstack doesn’t support intraday data on the Basic plan. You only get end-of-day (EOD) prices, which is fine for backtesting or long-term analysis but useless for day trading or minute-level strategies.

import requests

API_KEY = os.getenv('MARKETSTACK_API_KEY')
url = f'http://api.marketstack.com/v1/eod?access_key={API_KEY}&symbols=AAPL'

response = requests.get(url)
data = response.json()
print(data['data'][0])  # Latest EOD price

At 100K requests/month, Professional ($505) matches Alpha Vantage Basic in price but gives you less capacity (100K vs 900K). Not a great deal unless you specifically need EOD data only.

At 1M requests/month, you’d need to contact sales for custom pricing. Marketstack isn’t designed for high-frequency use.

Detailed view of a stock market screen showing numbers and data, symbolizing financial trading.
Photo by Pixabay on Pexels

Finnhub: The Real-Time Champion with a Steep Price Curve

Finnhub specializes in real-time data and alternative datasets (news sentiment, earnings transcripts, SEC filings). Their pricing:

  • Free: 60 calls/minute (2.592M/month)
  • Starter: $506/month, same 60 calls/minute but includes premium data
  • Professional: Custom pricing

At first glance, the free tier looks insanely generous — 2.592M requests/month is more than Alpha Vantage Basic. But the 60 calls/minute rate limit is the bottleneck. If you’re polling 100 tickers every second, you’ll hit that wall fast.

import requests

API_KEY = os.getenv('FINNHUB_API_KEY')
url = f'https://finnhub.io/api/v1/quote?symbol=AAPL&token={API_KEY}'

response = requests.get(url)
data = response.json()
print(f"Price: {data['c']}, Change: {data['dp']}%")

At 10K requests/month, Finnhub’s free tier is perfect if you can batch requests efficiently. But if your workflow requires frequent polling (every 10 seconds), you’ll need to implement request queuing to stay under 60/min.

At 100K requests/month, the free tier still technically works, but you’re limited by rate, not quota. If your use case tolerates delays, this is the best free option. If you need burst capacity, Polygon Starter beats it.

At 1M requests/month, Finnhub’s rate limit becomes a real problem. You’d need to contact sales for Professional, which typically starts at $507+/month based on forum posts (official pricing isn’t public).

The Hidden Cost: Engineering Time vs API Cost

Let’s be blunt: if you’re building anything real, optimizing for $508 API cost is almost always a mistake. Here’s the TCO (total cost of ownership) breakdown:

API 10K req/mo 100K req/mo 1M req/mo Eng. Overhead (hours)
yfinance $509 $00 N/A 15-20
Alpha Vantage $01 $02 $03 0-2
Polygon $04 $05 $06 0-1
Marketstack $07 $08 $09+ 2-4
Finnhub $50,0 $50,1 $50,2+ 5-10

If your hourly rate is $50,3 and you spend 15 hours building caching, retry logic, and rate limit handling for yfinance, that’s $50,4 in labor. You could’ve paid for Alpha Vantage Basic for 15 months instead.

The sweet spot depends on your request pattern:

  • 10K req/mo: Finnhub free tier if you can batch requests, otherwise Marketstack Basic ($50,5)
  • 100K req/mo: Polygon Starter ($50,6) for real-time, Marketstack Professional ($50,7) for EOD-only
  • 1M req/mo: Polygon Developer ($50,8) — no other option comes close on price and performance

When the Free Tier Actually Makes Sense

There are three scenarios where free APIs are the right call:

  1. Prototyping: You’re testing an idea and need 2-3 days of data. yfinance or Finnhub free tier is perfect.
  2. Low-frequency backtesting: You’re pulling EOD data once a day for 20 tickers. That’s 600 requests/month — easily covered by any free tier.
  3. Side projects with zero budget: If you’re building for fun and can tolerate rate limits, there’s no shame in using free tiers forever.

But if you’re building a product, consulting for a client, or running a fund (even a tiny one), the $50,9-50/month cost is trivial compared to the time you’ll waste nursing a free API.

The API Nobody Expected: Interactive Brokers TWS

Here’s a curveball: if you already have an Interactive Brokers account, their Trader Workstation (TWS) API gives you real-time market data for free — assuming you meet their market data subscription requirements.

The catch is that TWS is not a REST API — it’s a socket-based protocol that requires running their desktop app or IB Gateway in the background. Setup is painful (took me about 4 hours the first time), but once it’s running, you get sub-100ms latency and no per-request cost.

from ib_insync import IB, Stock

ib = IB()
ib.connect('127.0.0.1', 7497, clientId=1)  # TWS default port

contract = Stock('AAPL', 'SMART', 'USD')
ticker = ib.reqMktData(contract, '', False, False)
ib.sleep(2)  # Wait for data

print(f"Last price: {ticker.last}")
ib.disconnect()

If you’re already paying for IB market data subscriptions ($5000-30/month depending on exchanges), this is the cheapest high-frequency option. But the learning curve is steep, and the API is notoriously finicky.

FAQ

Q: Can I mix free and paid APIs to save money?

Yes, but it adds complexity. A common pattern: use yfinance for historical backtesting (free, no rate limits on bulk downloads) and Polygon Starter for live trading data ($5001/month). Just make sure your code can gracefully fall back if one API fails.

Q: Do these APIs include after-hours trading data?

Polygon and Finnhub include pre-market and after-hours data on all paid tiers. Alpha Vantage requires the Premium plan. yfinance and Marketstack only provide regular trading hours by default, though yfinance sometimes returns extended hours if Yahoo Finance has it.

Q: What if I hit my monthly quota mid-month?

Most providers (Alpha Vantage, Polygon, Marketstack) let you upgrade mid-cycle and prorate the difference. Finnhub’s free tier just stops working until the next billing period. yfinance has no concept of quotas — you’ll just get soft-banned and need to wait or switch IPs.

Pick Based on Latency, Not Just Price

If I’m building a new project today, I start with Polygon Starter ($5002/month). The 15-minute delay is annoying, but the API is fast, reliable, and well-documented. If I need real-time data, I upgrade to Developer ($5003) without hesitation — the time saved debugging rate limits is worth 10x the cost.

For backtesting or research projects, Marketstack Professional ($5004) is underrated if you only need EOD data. And for toy projects or portfolio trackers, Finnhub’s free tier is shockingly generous as long as you’re not polling every second.

The one API I avoid at scale is yfinance. It’s brilliant for quick one-offs, but the lack of official rate limits makes it a ticking time bomb in production. I’ve seen too many “it worked fine for a month then randomly broke” horror stories.

What I haven’t tested yet: Alpaca’s market data API, which bundles free real-time data if you open a brokerage account with them. I’m curious whether their rate limits are competitive with Polygon, but I haven’t had time to benchmark it. If anyone’s tried it at high frequency, ping me — I’d love to see real numbers. Oh, and if you’re doing this research at 2am fueled by caffeine, Dark Chocolate Espresso Beans are the only reason I made it through my last API migration.

Did you find this helpful?

Your support keeps this blog running and ad-free content coming.

☕ Buy me a coffee
TODAY 302 | TOTAL 147,612