OpenAdServer

Purple target-shaped logo on a white card, above three badges reading FastAPI, PyTorch CTR and Real-time eCPM.

Self-hosted ad serving in Python, FastAPI and PyTorch

OpenAdServer is an ad server you run on your own infrastructure. On paper, when an app or website asks it to fill a slot, it filters campaigns by targeting and budget, scores each remaining ad with a PyTorch click-prediction model and returns the top ones by eCPM, with tracking URLs attached. The publisher would keep control of its inventory and data instead of going through an ad network.

As things stand, the server doesn't start: the code at the latest commit, from December 21, 2025, stops on an ImportError at launch, and the maintainer hasn't answered the issue that reports it.

JSON targeting rules and one eCPM formula per bid type

  • Five pipeline stages, one module each: candidate retrieval by targeting, filters, prediction, ranking and a final rerank.
  • Per-campaign targeting rules stored as JSON, as allow or block lists: countries and cities, device OS and brand, age range, interests.
  • Four bid types reduced to one eCPM: CPM counts as is, CPC is multiplied by the predicted click rate, CPA by the predicted click and conversion rates, and oCPM reuses the CPC formula.
  • Daily and hourly frequency caps per user, plus a budget filter that excludes a campaign once its daily budget, its total budget or the advertiser's balance runs out.
  • Three click-prediction models (logistic regression, factorization machine, DeepFM) and scripts to train and compare them on the Criteo dataset. On 100,000 rows, logistic regression gets the best AUC (0.7577 against 0.7178 for DeepFM), and the README recommends it for production.

README says v1.0, the code fails to start

The package is still called LiteAds and declares itself alpha. pyproject.toml ships liteads 0.1.0 marked "Development Status :: 3 - Alpha", while the README calls it "v1.0 (Current)" and "production-ready". The repository holds five commits, made between November 30 and December 21, 2025, and has no tag or release.

The latest commit raises an ImportError on launch. event_service.py, loaded at startup, imports AdEvent and EventType from liteads.models, which defines neither. Issue #3, opened on February 3, 2026, reports the container restarting in a loop on this error. Another user asked for an update on October 26, 2026; the maintainer still hasn't replied.

The README's commands call a module that isn't in the repository. It runs openadserver.ad_server.main and openadserver.trainer.train_ctr, but the only package is liteads, and its trainer folder holds only empty files. The clone link points to pysean/openadserver, which GitHub can't find.

No management API and no admin interface. Apart from health probes and /metrics, the app serves only /api/v1/ad and /api/v1/event. The campaign, creative and advertiser CRUD routes listed in the README are absent from the code; the React dashboard and the campaign management API are planned for v1.1. Advertisers, campaigns and targeting rules go straight into PostgreSQL.

PostgreSQL, Redis and PyTorch either way. docker-compose.yml runs PostgreSQL 15 and Redis 7, capped at 256 MB, next to the server. Nginx and Prometheus with a bundled Grafana dashboard are optional profiles. PyTorch is one of the package's core dependencies.

The published latencies were measured without PostgreSQL or Redis. The stress test runs on in-memory SQLite and FakeRedis with no network hop: P99 comes out at 10.02 ms with logistic regression and 14.13 ms with DeepFM, against the "<10ms P99" in the feature list. The README itself expects 10 to 20% more I/O overhead once PostgreSQL and Redis are in the loop.

Pitched as a self-hosted alternative to Google Ad Manager, aimed at SMBs. The README says Google Ad Manager takes a 20 to 30% revenue share and sets its own Python stack against Revive Adserver's PHP. Gaming companies, app developers, researchers and students are also on its list. OpenRTB 2.5, header bidding and VAST video are on the v2.0 roadmap, with no date.