CigarBid Auction Monitor — Deal Scoring & Alerts

Overview

A price-intelligence tool for CigarBid, watching a user's own list of search terms across both auction formats the site runs. Classic lots are ascending-bid, so it captures the current winning bid, quick-buy price, units claimed against units available, close time and the full bid ladder. Free Fall lots descend in price instead, so every drop is recorded as a timestamped floor event — which is what lets the system learn how fast a cycle moves and where a given lot historically bottoms out. Every active lot is then scored 0–100 and tiered HOT / WATCH / SOFT / PASS, with alerts on anything above the threshold.

The engineering constraint shaped the whole design: it runs on a 512 MB VPS, and Chromium alongside Postgres does not fit in that. Postgres was dropped for embedded SQLite in WAL mode behind a custom async connection pool; Chromium runs single-process with a 128 MB JS heap cap and images blocked; scrape concurrency is pinned at one and the container is capped at 420 MB. CigarBid itself sits behind Cloudflare, so collection uses stealth automation, rotating user agents, human-cadence typing and randomised delays, with a block detector and retry when it still trips.

The scoring is deliberately unwilling to be confident before it has grounds. A lot with no confirmed closing history is capped at 70 and can never reach HOT; a benchmark built only from live floors caps at 60; Free Fall walks a four-phase gate from no data through one observed floor, then several, and only reaches the full range once real closes are on record. The timing model is built for a person, not a sniping bot — it peaks 1 to 6 hours before close, when the price has settled but there is still room to act, and drops to almost nothing inside the final 15 minutes.

Outcome

A single-user price-intelligence tool that turns an auction site with no price history into one with benchmarks, surfacing lots trading below their own historical closes — and doing it inside a 512 MB VPS, which is what forced the SQLite-over-Postgres and single-process-Chromium design the rest of the system is built around.

Screens & Demos

CigarBid Auction Monitor — Deal Scoring & Alerts

Architecture & Pipeline

  1. 01

    Watchlist

    User-defined search terms

  2. 02

    Stealth Browser

    Playwright · anti-bot bypass

    • Playwright
  3. 03

    Classic Lots

    Bid ladder · units · close time

  4. 04

    Free Fall Lots

    Timestamped price drops

  5. 05

    SQLite (WAL)

    11 tables · async pool

    • SQLite
  6. 06

    Closed-Lot History

    Benchmarks from real closes

  7. 07

    Scoring Engine

    Price · competition · timing

  8. 08

    Confidence Gate

    Caps score until history exists

  9. 09

    Tiering

    HOT · WATCH · SOFT · PASS

  10. 10

    Alerts & Dashboard

    Email · Discord · Flask

    • Flask

End-to-end flow, in order. Scroll sideways on a narrow screen.

Key Features

  • Runs in 512 MB of RAM — SQLite in WAL mode replacing Postgres, single-process Chromium with a 128 MB heap cap, concurrency pinned at 1, container capped at 420 MB
  • Cloudflare handling: stealth automation, rotating user agents, human-cadence typing (50–150 ms per keystroke), randomised step delays and a block detector with retry
  • Both auction formats: ascending Classic lots with their full bid ladder, and descending Free Fall lots tracked drop by drop
  • Timestamped floor events per Free Fall lot, learning cycle speed and where a lot historically bottoms out
  • 0–100 deal score tiered HOT / WATCH / SOFT / PASS, with a configurable alert threshold
  • Classic scoring: 50% price against the historical midpoint of past winning bids, 30% competition, 20% timing
  • Competition weighting halves when two or fewer units remain, and switches to outbid value once a lot is fully claimed
  • Free Fall scoring: 65% gap against the expected floor, 35% urgency blended from time left and observed drop cadence
  • FLOOR_IMMINENT, ALL_TIME_LOW and FINAL_CYCLE flags on Free Fall lots
  • Confidence gating — no confirmed close history caps a lot at 70, live-floor-only benchmarks cap at 60, so nothing reaches HOT on thin evidence
  • Timing model built for a human in the loop: peaks 1–6 hours before close, near-zero inside the final 15 minutes
  • Five independent services under supervisor loops, each restarting on crash without taking the others down
  • Three scrape cadences: watchlist search every 120 minutes, live bids every 30, rescoring every 30
  • Fuzzy matching of listings to watchlist terms at a 98% threshold
  • Flask dashboard: watchlist management, separate Classic and Free Fall deal views, per-product bid history, live time-to-close, scraper status, log viewer
  • Alerts by email with a Resend → Brevo → SMTP fallback chain, plus Discord webhooks, every attempt logged
  • One-shot Docker deploy script that rebuilds, rolls the stack, health-checks the dashboard and preserves the SQLite volume