Auction house alerts
A website and phone app that watches all 184 World of Warcraft auction houses (the in-game marketplaces) and alerts players the moment the exact item they want is listed.
Video coming soon
Video coming soon
Video coming soon
By the numbers
What it takes to watch every auction house, every hour, on one Linux server. Numbers from October 2026.
Scale
- auctions read every hour, in four regions
- 5.7M
- auction houses on 558 realms
- 184
- rows of price history since May; the database grew from 1 MB to 69 GB
- 130M
Speed
- to read all 2.9M auctions in Europe
- ~15 s
- for the hourly price update across all four regions
- ~35 s
- for the slowest of 24,805 logged web requests
- 1.5 s
Reliability
- alerts delivered in the last 30 days
- 3,968
- errors replaying 139 days of prices into the new engine
- 0
- deploys since mid-August, each with hash checks and a rollback copy
- 134
The story
Why I built it, and what it does today.
Picture a low-level character geared to be as strong as the game allows for its level range. That’s twinking, and it’s the corner of World of Warcraft I keep coming back to. I’ve played since Wrath of the Lich King in 2009, and every version since.
The catch is the gear. The pieces we chase are rare, and each one is sold on a single realm’s auction house. Europe alone has 92 of them. So the routine was the same for all of us: log in on one realm, check, log out, try the next. Ten realms, twenty, some days thirty, several times a day. More searching than playing.
I didn’t want a second job inside a game. I wanted a computer to do the looking. The problem: I’d only ever written small PowerShell scripts for work, and anything bigger had always felt like unknown ground I stayed away from.
So I started with what I knew. In June 2025 a PowerShell window, on a virtual machine on my own PC, began asking Blizzard’s API about one item at a time. Even that first window had a button called Calibrate Item, because the API never tells you what the game shows. One of the first alerts it ever sent: a Singing Crystal Axe on Silvermoon, listed for 1.3 million gold.
Then it kept growing, and I grew with it. Every wall turned out to be a step. Python when PowerShell ran out. A Discord bot when other players wanted alerts too. A web app, a rented server, then Linux, PostgreSQL and Redis. Things I thought were impossible one week were running the next.
Along the way a friend from the twink community saw where it was heading and asked to join. Almost a year later we still build it together, each covering the other’s blind spots, mostly because it’s fun to build something that helps the community.
It costs us servers, backups and AI tools, and it’s free for everyone anyway, with every feature. Nobody gets an edge by paying; everyone plays on the same field. The plan is for ads to cover the bills.
Fifteen months in, it reads 5.7 million auctions an hour so nobody has to. And when I log in now, I play.
What it does
- Alerts for the exact version. Max price, item level, required level, sockets, extra stats, raid difficulty, even a pet’s level and quality. Alerts arrive as a phone push, an email, a Discord DM or in the app.
- One auction house for every realm. Browse it like in-game with categories and filters, with listings grouped by exact item version and price charts going back 139 days.
- “Is this a good price?” Every item version gets a usual price, so a listing shows as low, typical or high.
- Everything around it. Discord and Google login, flood and spam protection, moderation tools, an AI support chat and game data in 9 languages.
How it grew
Fifteen months, from a PowerShell window to what it is today. Click any screenshot to enlarge it.
-
A PowerShell window on a virtual machine on my PC, asking Blizzard’s API about one item at a time. When it found one, a Discord webhook posted the find.
-
Other players want in, so a Python Discord bot takes over. Everyone gets their own private channels, with buttons and forms to add items. SQLite holds the data; Europe and North America only.
-
Three windows running side by side: the PowerShell app, the Discord bot and a live scan log. Then the first real website (Flask), with email alerts, reachable through a Cloudflare Tunnel.
-
The PowerShell window retires. Python services take over, along with the first item-level engine. The dashboard gets a real design, then filters and categories. A native phone app gets built and shelved: an installable web app does the job better.
-
The big move. Windows to an Ubuntu server, SQLite to PostgreSQL, plus Redis, nginx and systemd, all in one month. Google login, an installable app with push, Korea and Taiwan, and the first auction house browser across every realm.
-
Found a caching bug that could show one user’s session to someone else, and fixed it in three layers: nginx, headers and cookies. Lesson learned: a cache is a security decision.
-
Required level worked out for 28.5M rows of history without a single API call. Then a rename, with a new design and its own domain. Game data in 9 languages follows in September.
-
Grown-up habits. Every deploy gets hash checks and a rollback copy (134 so far), and moderators get proper tools.
-
A new price engine. The old one called almost everything a deal, because it compared the cheapest of 92 realms with a typical one. Rebuilt from the ground up: 139 days of history replayed with zero errors, and 54 GB became 7.9 GB. It’s the pop-up in the AH browser at the top.
Behind the scenes
What was hard, what I’m proud of, what didn’t make it, and how I work.
- Hardest part
- Working out what an item actually is. An auction only gives an item ID and a list of “bonus IDs”. The item level players see comes from scaling curves that differ per item family, and Blizzard changed them in patch 12.0.5. Wrong number, wrong alerts. It took four rounds from January to September, ending with 23 rules checked against in-game screenshots.
- Proudest of
- That I understand how all of it works, so I can predict problems instead of reacting to them. And a few things in particular: searching by required level, which Blizzard’s API doesn’t even have; mapping every variation of every item; and keeping it fast and reliable on a small budget.
- How I build
- With AI as a pair programmer. It helps me understand code, plan flows, pick my own designs apart, weigh solutions and write a lot of the code. The ideas and the decisions are mine, and I make sure I understand how every part works.
- Thrown away
- A native phone app (an installable web app does the job), the PowerShell window, SQLite, cached API responses after the session bug, subscription tiers, and average prices, after bait listings pushed a 2,000 g item’s average past 80,000 g.
- Learned
- Running Linux services (systemd, nginx, fail2ban), PostgreSQL with 100M+ row tables (partitions, indexes, one bulk query instead of an 85-minute loop), Redis, OAuth, web push, and that a cache can be a security hole.
- Built with
- Python · Flask · PostgreSQL · pgBouncer · Redis · nginx · Ubuntu · Cloudflare · JavaScript · React PWA · discord.py










