Udemy prices change daily — so I built a free price tracker
DEV Community

Udemy prices change daily - so I built a free price tracker

If you've ever bought a Udemy course, you've probably seen this: the same course costs one price on Monday and a fraction of it on Thursday. One course I watch was listed at $110 and sold for under $20 a few days later.

Udemy doesn't show price history. The "sale ends in 6 hours!" banner tells you nothing about whether the price will be even lower next week.

So I started checking prices every morning and publishing what I saw: CourseLens. This post covers how it's built for $0/month, and the two bugs that made it show wrong prices for weeks without me noticing.

What it does

  • Every morning, it records the real price of each listed course (no login, no cookies, the price an anonymous visitor sees).
  • Each course page shows a price chart and the periods when it was cheaper.
  • A /sale/ page shows whether a sitewide sale is on right now.
  • Each course has an RSS feed that fires when the price drops.

The stack

GitHub Actions (daily cron) └─ Python: fetch prices → append to JSON in the repo → commit

Cloudflare Pages (watches the repo) └─ build.py: JSON → static HTML (no framework, no database)

  • No server, no database. Price history is a JSON file committed to the repo. Git is the database, and git log is the audit trail.
  • One Python script builds every page. No framework. The build also runs the test suite; if a test fails, the build fails and the previous version stays live.
  • Staging first. Every change goes to a staging branch, gets checked, then fast-forwards to main. (I learned this the hard way, see below.)
  • Cost: GitHub Actions free tier + Cloudflare Pages free tier + a domain.

Bug 1: three weeks of prices in the wrong currency

CourseLens has a second regional edition that shows prices in a local currency. For three weeks, that edition showed prices about a hundred times too low.

What happened: I was traveling when I wrote the fetcher, and the network I was on happened to get local-currency prices back. I assumed that was the default and didn't ask for a currency. GitHub Actions runners sit in US data centers. They got dollar amounts, and my code put the local currency symbol in front of them. A $15 course suddenly looked like it cost pocket change.

Lesson: never rely on an implicit default that depends on where the code runs. Set the region and currency explicitly, for every market, and add a test that fails if the currency comes back wrong.

Bug 2: US prices stuck for weeks because of time zones

To save requests, I only refreshed the US edition's prices when the other regional edition detected that a sale had started or ended. It seemed reasonable: Udemy sales are sitewide, so one market should tell you about the other.

They aren't in sync. Sales start and end on local time boundaries, so two markets can be a day apart. When the other edition saw "no change", the US edition never refreshed, and some of its pages showed prices up to 85% below the real one.

Lesson: don't make one market's data depend on another market's events. The fix was boring: refresh every US course every day, unconditionally. It costs a few extra requests and removes a whole class of bugs.

What I'd tell anyone building a price tracker

  • Store every observation, not just the latest price. You can't recompute history later.
  • Treat "unchanged" as data. A day with no change is still an observation.
  • Make the build your safety net. Tests that run inside the deploy are worth more than tests you remember to run.
  • Write down every incident. Neither bug above was caught by an automated check. I now keep a "lessons" file that I read before every change.

Try it

If you watch a specific course, subscribe to its price-drop RSS feed from its page.

Disclosure: course links on CourseLens are Udemy affiliate links. Prices and scores are not affected by that.

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.