New Module: ZeroGPU Real Time Data - #4906
Open
amaan-ai20 wants to merge 1 commit into
Open
Conversation
amaan-ai20
marked this pull request as draft
August 12, 2026 11:15
amaan-ai20
marked this pull request as ready for review
August 12, 2026 18:51
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New Module: ZeroGPU Real Time Data
This PR adds
zerogpu.rtd, a general module that enriches an incoming OpenRTB request with IAB content categories derived from the publisher's domain.On each auction the module resolves the domain from the bid request, classifies it with ZeroGPU's
zlm-v1-iab-domain-classifiermodel, and appends the resulting categories to{site,app,dooh}.content.dataas Seller-Defined contextual segments underext.segtax: 6(IAB Content Taxonomy 2.2).Because the segments are written to standard First Party Data fields, every bidder in the auction can read them — no bidder-specific integration is required, per the Module Rules requirement that RTD modules make data available cross-bidder.
Documentation PR: prebid/prebid.github.io#6700
The auction never waits on ZeroGPU
The hook reads an in-process cache and does no I/O. On a cache miss the auction proceeds unenriched and the classification is fetched in the background, so subsequent auctions on that domain are enriched from memory.
This matters because the classification call takes roughly 0.9s measured against the live API — far too long to sit in front of bidders. Measured hook cost is ~15µs whether the domain is cached or not.
Consequences of the design, all deliberate:
Shutdown()cancels in-flight warm-ups and waits for them, so no goroutine outlives the host.Every failure mode is fail-open: a slow, unreachable, or erroring API leaves auctions unenriched. The module never rejects a request, never delays one, and never creates bids.
Stage choice
processed_auction_request— the last point at which the request is still shared by every bidder, after stored requests are merged, and where account-level config is available. Running atbidder_requestwould warm the same domain once per bidder.Privacy
The default configuration sends only a domain to ZeroGPU and writes only contextual data. No user identifiers, device data, or geographic information leave Prebid Server, and nothing is written to user-scoped ORTB fields. Under the default configuration the module has no user privacy implications.
enrich_user_audienceis opt-in and defaults tofalse. When enabled it writes IAB Audience Taxonomy 1.1 segments touser.data. It is off by default for two reasons, both documented in the module README and on the docs page:add-a-module.mdrequires a module supplying user-level data to check theenrichUfpdActivity Control, and PBS-Go does not currently expose activity controls to modules, so the module cannot perform that check on the host's behalf.The module does not create bids and does not add pixels to creatives.
Configuration
api_keyis the only required parameter; everything else has a working default. A complete host configuration is inmodules/zerogpu/rtd/sample/pbs_example.json, and all parameters are documented inmodules/zerogpu/rtd/README.md.The group
timeoutonly has to cover an in-memory cache read, so a small value is correct. It is unrelated totimeout_ms, which bounds the background warm-up and never applies to the auction path.account_filter.allow_listrestricts a host-enabled module to specific accounts.Testing
./validate.sh --nofmtpasses — full unit test suite plusgo vet, no failures. Module coverage is 97.7% of statements (go test ./modules/zerogpu/rtd -cover), above the 90% requirement, and the package is clean under-race.Coverage includes both wire-level and behavioural cases: every documented ZeroGPU status (400/401/403/420/500), malformed and empty responses, each domain-resolution fallback, domain normalization, cache hit/miss, negative-cache TTL selection, concurrent warm-up collapsing, shutdown behaviour, each enrichment flag, account allow-list, and the request both with and without
ext.prebid.data.bidders(which determines whether core's FPD processing redistributes the injected segments per bidder).Notes for reviewers
modules/builder.gois regenerated withmake build-modules. Only the twozerogpuadditions are included; the pre-existingscientiamobileimport alias in that file differs from current generator output and has been left untouched to keep this diff scoped.sample/pbs_example.jsonrather thansample/pbs.jsonbecause the repository's.gitignorecontainspbs.*, which matches at any depth and would silently exclude the file. This follows the existingscientiamobile/wurfl_devicedetectionprecedent.prebid@zerogpu.ai, also registered in.github/workflows/scripts/codepath-notification.