Google Discover — Complete Technical Architecture

The most comprehensive analysis of Google Discover's internal systems, derived from SDK instrumentation, telemetry constants, and client-side observable behavior.

276 DISCOVER_ events 56 telemetry counters 13 cluster types 14 state path categories 51 runtime feature flags 150 GWS experiments 29 feed structure cards analyzed 18 PERSONAL_UPDATE subtypes 9 content pipelines 93 days usage tracked 45 fact-checked findings 12 SDK modules analyzed

Discover Content Pipeline — 9 IDENTIFIED Stages End-to-End COMPLETE ARCHITECTURE

PUBLISHER GOOGLE INFRASTRUCTURE USER DEVICE ───────── ───────────────────── ─────────── Publishes ──────────────▶ ┌────────────────────────────────────────┐ content │ STAGE 1: CONTENT INGESTION │ │ Googlebot crawl → index │ │ Entity extraction pipeline │ │ KG MID assignment (/m/xxxxx) │ │ │ └───────────────┬────────────────────────┘ │ ┌───────────────▼────────────────────────┐ │ STAGE 2: OG TAG PARSING [SDK-VERIFIED] │ │ SchemaOrg parser (dkpg.java) → │ │ MetadataWrapper │ │ Schema.org JSON-LD checked FIRST, │ │ then OG, then twitter:*, then HTML │ │ │ │ og:image → twitter:image → │ │ og:image:secure_url → │ │ twitter:image:src → image │ │ │ │ Schema.org (TEXT_TYPE_TITLE) → │ │ og:title → twitter:title → title │ │ │ │ Schema.org (TEXT_TYPE_PUBLISHER) → │ │ og:site_name → author │ │ og:locale → inLanguage → "en" │ │ │ │ article:content_tier + │ │ isAccessibleForFree │ │ │ │ Blocking: nopagereadaloud, notranslate │ │ Output → ContentMetadata protobuf │ └───────────────┬────────────────────────┘ │ ┌───────────────▼────────────────────────┐ │ STAGE 3: CONTENT CLASSIFICATION │ │ Content type: │ │ BREAKING_NEWS (+ other types) │ │ Note: EVERGREEN_VIBRANT is a UI color │ │ palette name (ftsb.java), NOT a │ │ content classification type │ │ Cluster assignment: │ │ neoncluster, deeptrends, freshvideos │ │ geotargetingstories, mustntmiss │ └───────────────┬────────────────────────┘ │ ┌───────────────▼────────────────────────┐ │ STAGE 4: COLLECTION GATE │ │ filter_collection_status (bupa.java) │ │ → ALL content from domain blocked │ │ filter_entity_status (bupa.java) │ │ → per-URL content filtered │ │ Path: /client_streamz/android_gsa/ │ │ discover/app_content/ │ └───────────────┬────────────────────────┘ │ ┌───────────────▼────────────────────────┐ │ STAGE 5: USER INTEREST MATCHING │ │ Interest Graph (shared infra) │ │ BroaderUserInterest { │ │ MID, NAME, CONFIDENCE, IMPORTANCE │ │ } │ │ Match: content_MIDs ∩ user_MIDs │ │ (ember_item_matched_retrieval_mids │ │ is Ember tab/image search, NOT │ │ Discover — from dzby.java) │ └───────────────┬────────────────────────┘ │ ┌───────────────▼────────────────────────┐ │ STAGE 6: RANKING (SERVER-SIDE) │ │ Server receives ContentMetadata from │ │ Stage 2 (title, image, site_name, │ │ locale, paywall flag) │ │ │ │ Client-confirmed inputs: │ │ Image quality (LOW_QUALITY_IMAGE) │ │ Freshness (freshness_delta_in_seconds│ │ Historical CTR (click_count/show_ct) │ │ Client-confirmed event: │ │ PCTR_MODEL_TRIGGERED (generic enum) │ │ │ │ ⚠ pCTR model runs server-side — │ │ actual inputs not visible in client │ │ SDK │ └───────────────┬────────────────────────┘ │ ┌───────────────▼────────────────────────┐ │ STAGE 7: FEED ASSEMBLY │ │ MAIN_FEED │ │ └─ COLLECTION (publisher groups) │ │ └─ CLUSTER (13 types) │ │ └─ CARD (individual) │ │ DISCOVER_ATF_RENDER_START/END │ └───────────────┬────────────────────────┘ │ ┌───────────────▼────────────────────────┐ │ STAGE 8: DELIVERY │ ──▶ User Device │ gRPC: tng.ga.discover.streaming │ Feed displays │ Background: 24h WorkManager sync │ in MINUS_ONE │ Beacon: server-push content │ or MAIN_FEED │ Cache: stream_cache_hit/miss │ └───────────────┬────────────────────────┘ │ Per-URL metrics ◀───────────────────────────▼ click_count ┌────────────────────────────────────────┐ show_count │ STAGE 9: FEEDBACK LOOP │ dismissal_count │ Dismissals → collection filter │ engagement_time_msec │ Follows → interest graph (shared) │ (GA4 standard, not │ │ Discover-specific) │ │ │ NAIADES → personalization (shared) │ │ Hearts/Saves → personalization │ └────────────────────────────────────────┘

pCTR Model (Predicted Click-Through Rate) SDK-CONFIRMED

SDK Evidence: The string PCTR_MODEL_TRIGGERED was extracted from the Google Search SDK. However, deeper analysis reveals it is in a generic telemetry event enum alongside ~100+ non-Discover events (PAYMENTS_*, KEYBOARD_*, PARTICLE_*, etc.). It is NOT in a Discover-specific class.
SDK Fact Check Correction: The MAX_HIT_WEIGHT scoring formula (MUL _MAX_HIT_WEIGHT (DIV (MAX _CLICK_COUNT 0) (ADD 1 (MAX _CLICK_COUNT 0)))) exists in the SDK, but the containing class works with SuggestRequest/SuggestResponse protos and CrossProfileIcingApi — it is the on-device Icing search suggest scoring, NOT Discover ranking. Zero Discover-related strings appear near this formula.

pCTR Model — What Client SDK Actually Shows

ClaimSDK EvidenceVerdict
pCTR model existsPCTR_MODEL_TRIGGERED event string presentEXISTS (but generic enum, not Discover-specific)
og:title is a pCTR inputog:title and PCTR are in separate SDK modules with ZERO class overlap. ContentMetadata (OG output) not referenced in scoring module.NOT CONFIRMED in client SDK
MAX_HIT_WEIGHT is Discover's scoring formulaThe containing SDK module operates on SuggestRequest/SuggestResponse, not Discover protos. ZERO overlap with OG metadata classes.NOT CONFIRMED — this is Icing search suggest

Confirmed Client-Side Ranking Signals

Input SignalSourceSDK Evidence
Image qualityog:image + dimension checksLOW_QUALITY_IMAGE, image_width, image_height
FreshnessContent agefreshness_delta_in_seconds
Historical CTRPer-URL metricsclick_count / show_count
Thumbnail downloadImage fetchEMBER_FEED_THUMBNAILS_DOWNLOADED
Image load failureError trackingimage_load_failure_count (telemetry)
Key distinction: The pCTR model almost certainly runs server-side on Google infrastructure. The client extracts og:title into a ContentMetadata protobuf and sends it to discover-pa.googleapis.com, but the actual pCTR evaluation is not visible in the client-side SDK. Whether og:title is a pCTR input is plausible but cannot be confirmed from SDK analysis alone.

Open Graph Tag Parsing — The 6 Page-Level Signals MANDATORY SDK-DEOBFUSCATED

Critical finding: The parser (dkpg.java, self-described as SchemaOrg{parsedMetatags, jsonLdScripts}) handles significantly more than 6 signals. In addition to the 5 OG tags and 1 article meta tag below, it also parses: twitter:image, twitter:title, twitter:image:src, author, title, inLanguage, isAccessibleForFree, image (generic), and Schema.org JSON-LD structured data. The 6 OG tags listed here are the primary signals, but the parser's scope is broader. All handled within a single SDK module.
TagSDK EvidenceHandlerRoleRequired
og:imageCONFIRMEDImage CallableCard thumbnail. No og:image = no card rendered. EMBER_FEED_THUMBNAILS_DOWNLOADED fails.MANDATORY
og:titleCONFIRMEDTitle SupplierCard title text. Extracted into ContentMetadata protobuf. pCTR input plausible but unconfirmed.MANDATORY
og:site_nameCONFIRMEDTitle SupplierPublisher name on card header. Attribution display.Recommended
og:localeCONFIRMEDLocale ExtractorContent language/region. Matched against user locale for feed eligibility.Recommended
og:image:secure_urlCONFIRMEDFallback SupplierHTTPS variant of image URL. Preferred over HTTP.Optional
article:content_tierCONFIRMEDPaywall DetectorPaywall classification: free / metered / locked. Affects card treatment and user expectation.Recommended

Deobfuscated OG Metadata Pipeline (from SDK analysis)

HTML PAGE │ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ STAGE_METATAGS_EXTRACTION │ │ Extracts all <meta> tags + JSON-LD scripts from page HTML │ └──────────────────┬───────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ SchemaOrg Parser │ │ Stores: ImmutableList<ParsedMetatag> + JSON-LD scripts │ │ Query methods: │ │ byName(name) → Optional<ParsedMetatag> (by name attr) │ │ byProperty(name) → Optional<ParsedMetatag> (for og: tags) │ │ typedExtract(name, class) → Optional<T> │ │ multiValue(name, fn) → Stream │ └──────────────────┬───────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ MetadataWrapper │ │ Wraps SchemaOrg parser for downstream consumers │ └──────────────────┬───────────────────────────────────────────────────┘ │ ┌────────────┼────────────┬───────────────┐ ▼ ▼ ▼ ▼ ┌───────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │ Title │ │ Image │ │ Locale │ │ Paywall │ │ Supplier │ │ Supplier │ │ Extractor│ │ Detector │ │ │ │ │ │ │ │ │ │ og:title │ │ og:image │ │ og:locale│ │ content_ │ │ og:site_ │ │ fallback │ │ → lang │ │ tier │ │ name │ │ chain │ └──────────┘ │ │ │ author │ │ │ │ │ └─────┬─────┘ └────┬─────┘ └─────┬─────┘ │ │ │ ▼ ▼ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ ContentMetadata Protobuf │ │ url title (from og:title chain) │ │ language site_name (from og:site_name) │ │ canonical_url image (from og:image chain) │ │ has_paywall flags (bitfield) │ └──────────────────┬───────────────────────────────────────────────────┘ │ ▼ Discover Feed Cards (via ModernContentViewer / Silk)

Fallback Chains (SDK-verified)

SDK analysis reveals exact fallback order. When the primary OG tag is missing, the app tries alternatives in strict sequence. These chains are hardcoded in the Title and Image Supplier classes.
SignalFallback Chain (in order)SDK Handler
TitleSchema.org (TEXT_TYPE_TITLE) → og:titletwitter:titletitle (HTML name attr)Title Supplier + Fallback Supplier (dkri.java:1088-1092, dknl.java:27-29)
Imageog:imagetwitter:imageog:image:secure_urltwitter:image:srcimageImage Callable + Fallback Supplier (dkri.java:1100, dkpj.java switch cases 0,2,3,4)
PublisherSchema.org (TEXT_TYPE_PUBLISHER) → og:site_nameauthor (HTML name attr)Title Supplier (dkri.java:1097-1099)
AuthorSchema.org (TEXT_TYPE_AUTHOR) → author (HTML name attr)Title Supplier
Languageog:localeinLanguage (JSON-LD typed) → hardcoded "en"Locale Extractor + Title Supplier
Paywallarticle:content_tier + isAccessibleForFree (JSON-LD boolean)Paywall Detector

Blocking Metatags (SDK-verified)

The Paywall Detector checks for blocking metatags that prevent content from being processed. When found, the pipeline throws: "The page contains blocking metatag: %s". Two values found (from dkri.java:304-309): nopagereadaloud is ALWAYS checked (unconditional), while notranslate is CONDITIONALLY checked — only when a server config flag is not the default value. Note: these halt the article content extraction/readout parser, not necessarily the Discover card rendering pipeline. They are in the same codebase but may be separate processing paths.

Image Requirements

RequirementDetails
Minimum width1200px for hero card format. Smaller = thumbnail card (lower CTR).
Quality checkLOW_QUALITY_IMAGE flag marks images below threshold
Load trackingelements_interaction/image_load_failure_count (telemetry counter)
Robots.txtImage URL must NOT be blocked by robots.txt
FormatJPEG, PNG, WebP. DISCOVERY_CARD_WEBP_IMAGE_SUPPORT confirmed.

Discover Integration Points (SDK-verified)

IntegrationEvidence
Discover API endpointdiscover-pa.googleapis.com in SDK
Content viewer consistencysilk_discover_consistency_port
Datastore updatessilk_discover_datastore_update_port
Dismiss handlingsilk_discover_dismiss_port
Content viewer renderingsilk_modern_content_viewer_portModernContentViewer
Content opening eventDISCOVER_CONTENT_VIEWER_OPEN

Discover Freshness Decay Buckets PARTIAL

Freshness signals exist in the codebase but their direct connection to Discover ranking is not fully confirmed. freshness_delta_in_seconds appears in eblv.java (Smartspace weather/air quality metrics, not Discover). staleness_in_hours appears in the same weather metrics class. The bucket strings (1_TO_7_DAYS, etc.) appear in bemp.java:215 inside GestureSettingsPreferenceFragment, not a Discover class. The strings exist, but their confirmed scope is broader than Discover alone.
BucketWindowWeight
1_TO_7_DAYS1-7 days oldHighest freshness weight
8_TO_14_DAYS8-14 days oldMedium freshness weight
15_TO_30_DAYS15-30 days oldLowest freshness weight
staleness_in_hours30+ daysContinuous staleness decay

Personalization Infrastructure Feeding Discover 4 layers

Note: Layers 1 and 2 below (Geller/AIP and NAIADES) are shared Google infrastructure — they serve Google Assistant, Search, and other products, not just Discover. Discover consumes their outputs but does not own these systems. Layers 3 and 4 are Discover-specific.
┌─────────────────────────────────────────────────────────────────────┐ │ LAYER 1: Geller / AIP Interest Graph [SHARED INFRASTRUCTURE] │ │ Per-user on-device interest data (synced via Geller synclets) │ │ Serves: Google Assistant, Search, Discover, and other products │ │ BroaderUserInterest { MID, NAME, CONFIDENCE, IMPORTANCE } │ │ Discover reads from this store for entity-based matching │ ├─────────────────────────────────────────────────────────────────────┤ │ LAYER 2: NAIADES Personalization [SHARED INFRASTRUCTURE] │ │ Google-wide personalization system with 19 content subtypes │ │ Discover consumes NAIADES signals to populate its feed │ │ Subtypes include: MID_BASED, QUERY_BASED, SPORTS, TRENDING, │ │ WPAS, RECALL_BOOST, FINANCE, FLIGHT_DEALS, SHOPPING_PRICE, etc. │ ├─────────────────────────────────────────────────────────────────────┤ │ LAYER 3: Persistent State [DISCOVER-SPECIFIC] │ │ /persistent/follows/* — followed topics/entities │ │ /persistent/heart/* — liked content │ │ /persistent/save/* — saved content │ │ /persistent/tombstone_*/data — dismissed content │ ├─────────────────────────────────────────────────────────────────────┤ │ LAYER 4: Engagement Signals │ │ engagement_time_msec (GA4 standard — app-level, not │ │ article-level; from chvn.java, standard Firebase Analytics) │ │ GetDiscoverEngagementLevel, session_user_engagement │ └─────────────────────────────────────────────────────────────────────┘

NAIADES — 18 Content Subtypes SHARED INFRASTRUCTURE

Shared system: NAIADES is a Google-wide personalization system, not Discover-exclusive. These subtypes describe how personalized content enters various Google surfaces. Discover is one consumer of NAIADES signals. Each subtype has a matching PERSISTENT_LOGGING variant for cross-session tracking.
SubtypeMeaningPersistent Logging
MID_BASED_NAIADESEntity-driven personalization (Knowledge Graph MIDs)
QUERY_BASED_NAIADESSearch-history-driven personalization
RANKING_CHANGERanking adjustment signal
RECALL_BOOSTBoosted retrieval priority from candidate pool
WPASWeb Publisher Articles Signal (Google News Publisher Center)
QUERY_FOLLOWMatched to queries user explicitly follows
SPORTSSports content with dedicated treatment
FINANCE_TRIGGEREDFinance content triggered by interest
FLIGHT_DEALSFlight deals content
SHOPPING_PRICEShopping price update content
MEGASITELINKSMegasitelinks content type
UPCOMING_DATES_TRIGGEREDUpcoming dates/events
HISTORICAL_SIRIUSHistorical Sirius content
CACHE_EXPIREDCache-expired content refresh
MULTIPLE_TRIGGERINGContent triggered by multiple signals simultaneously
TRENDINGTrending content✓ (long + medium duration)
TRENDING_WITH_LABELTrending content with topic label
TRENDING_AITN_WITH_LABELAITN trending with label
Key insight: WPAS means Google News Publisher Center registration gives articles a distinct classification that may receive different ranking treatment. RECALL_BOOST literally increases retrieval priority from the candidate pool.

Content Filtering — Two-Level Architecture BINARY KILL SWITCH

Two-Level Filtering

LevelTelemetry CounterScopeEffect
Collectionfilter_collection_statusEntire publisher/domainALL content from collection blocked
Entityfilter_entity_statusIndividual URLOne item filtered
SDK evidence: The Discover-specific filter metrics are filter_collection_status and filter_entity_status from bupa.java, tracked at /client_streamz/android_gsa/discover/app_content/. There is NO graduated suppression — it's binary. And there is NO equivalent "boost collection" flag anywhere in the system. Note: isCollectionHiddenFromEmberFeed (from boov.java, CollectionDetailsData) controls the Ember tab (a separate visual image discovery tab), NOT the Discover feed.

Suppression Mechanisms 5 methods

MechanismSDK StringDescription
Counterfactual holdbackSHOW_SKIPPED_DUE_TO_COUNTERFACTUALContent withheld for A/B experiments
Counterfactual deliveryDELIVERED_COUNTERFACTUALContent delivered in counterfactual group
Fetched counterfactualFETCHED_COUNTERFACTUALContent fetched but suppressed
Visibility repressedVISIBILITY_REPRESSED_COUNTERFACTUALVisibility explicitly repressed (Google-wide VE logging from eyxv.java, not Discover-specific — used across Assistant, Lens, Search, etc.)
Rug pullbackground_refresh_rug_pull_countCards withdrawn after being pushed
Counterfactual variants found in SDK: CLIENT_COUNTERFACTUAL, SUBTYPE_COUNTERFACTUAL_DUMMY, DATA_USAGE_COUNTERFACTUAL_EXPERIMENT, SUBTYPE_ENTITY_PREVIEW_COUNTERFACTUAL, SUBTYPE_PROMPT_EXPANSION_COUNTERFACTUAL, SUBTYPE_MODELESS_BACK_TO_ALL_COUNTERFACTUAL, SUBTYPE_MODELESS_EASY_SWITCH_COUNTERFACTUAL — indicating counterfactual experiments run across multiple system components.

Beacon Push System — Server-Initiated Content 5 events

Content type limitation: From bqmt.java, Beacon handles exactly two content types: ordinal 0 = SportsScoreAmbientDataDocument and ordinal 1 = InvestmentRecapAmbientDataDocument. Any other content type triggers: "Unsupported BeaconContent type: %s" and is rejected. Beacon is a narrow pipeline for sports scores and investment recaps only.
EventSDK EvidenceRole
DISCOVER_BEACON_PUSH_RECEIVEDCONFIRMEDPush received from server
DISCOVER_BEACON_PUSH_ACCEPTEDCONFIRMEDPush accepted (budget/quality passed)
DISCOVER_BEACON_PUSH_REJECTEDCONFIRMEDPush rejected (budget/quality/pref failed)
DISCOVER_BEACON_PUSH_FINISHEDCONFIRMEDPush processing completed
DISCOVER_BEACON_CONTENT_PUSHCONFIRMEDContent push type identifier

Beacon Infrastructure

EventRole
DISCOVER_BEACON_SEARCH_WRITE_START/END/FAILEDSearch integration for beacon content
DISCOVER_BEACON_SEARCH_DOCUMENT_CONVERSION_START/END/FAILEDDocument conversion for search indexing
DISCOVER_BEACON_RESOURCE_DOWNLOAD_START/END/FAILED/SKIPPEDResource download for beacon content
DISCOVER_BEACON_WORK_MANAGER_ENQUEUED/EXECUTION_STARTWorkManager scheduling for beacon tasks
DISCOVER_BEACON_PREFERENCE_OPENED/OPEN_INTENT_RECEIVEDUser beacon preference management
donated_sports_documents_countSports docs pushed to local search index
dropped_sports_notifications_countSports notifications dropped
incoming_sports_notifications_countIncoming sports notification count
search_cleared_countBeacon search index data cleared

Streaming gRPC Protocol Real-time feed

gRPC Services (SDK-Extracted)

ServiceRole
google.internal.discover.discofeed.feedrenderer.v1.DiscoverFeedRendererFeed content rendering
google.internal.discover.discofeed.streamingfeedrenderer.v1.DiscoverStreamingFeedRendererStreaming feed rendering
google.internal.discover.discofeed.actions.v1.DiscoverActionsUser action processing
google.internal.discover.channels.v1.DiscoverChannelsRendererTopic channel rendering
google.internal.discover.discofeed.homestack.v1.DiscoverHomestackFeedRendererHomestack widget feed
tng.ga.discover.streamingReal-time streaming protocol
preprod-discover-pa.googleapis.comPre-production API endpoint

Streaming Lifecycle Events

EventPhase
DISCOVER_STREAMING_CONNECTION_STARTConnection initiated
DISCOVER_STREAMING_INITIALIZATION_SENTInit payload sent
DISCOVER_STREAMING_INITIALIZATION_ACKNOWLEDGEDServer acknowledged init
DISCOVER_STREAMING_ACTION_PAYLOAD_SENTUser action sent
DISCOVER_STREAMING_ACTION_PAYLOAD_ACKNOWLEDGEDServer acknowledged action
DISCOVER_STREAMING_TOKEN_UPDATE_SENTToken refresh sent
DISCOVER_STREAMING_NEXT_PAGE_REQUEST_SENTPagination request
DISCOVER_STREAMING_NEXT_PAGE_RESPONSE_RECEIVEDPagination response
DISCOVER_STREAMING_DATA_OPERATIONS_PAYLOAD_RECEIVEDData operations received
DISCOVER_STREAMING_FEED_CLEAN_UP_REQUEST_SENTFeed cleanup request
DISCOVER_STREAMING_FEED_CLEAN_UP_RESPONSE_RECEIVEDCleanup response
DISCOVER_STREAMING_CONNECTION_CLOSEDConnection closed
DISCOVER_STREAMING_CONNECTION_RETRYReconnection attempt

Web Stories (STAMP) — Separate Pipeline BYPASSES pCTR

Web Stories bypass standard ranking. They have a dedicated inline rendering pipeline (INLINE_STAMP_VIEWER_FRAGMENT), carousel placement (INLINE_STAMP_VIEWER_SLIDE_FRAGMENT), and their own recommendation engine (STAMP_VIEWER_RECOMMENDATIONS). Standard entity matching and pCTR history are NOT required.
EventSDK EvidenceRole
STAMP_VIEWER_OPEN_FROM_DISCOVERCONFIRMEDWeb Story opened from Discover feed
STAMP_VIEWER_OPEN_FROM_SEARCHCONFIRMEDWeb Story opened from Search results
STAMP_VIEWER_OPEN_FROM_DEEPLINKCONFIRMEDWeb Story opened from deeplink
INLINE_STAMP_VIEWER_FRAGMENTCONFIRMEDInline rendering in feed (not behind click)
INLINE_STAMP_VIEWER_SLIDE_FRAGMENTCONFIRMEDCarousel slide placement
STAMP_VIEWER_RECOMMENDATIONSCONFIRMEDOwn recommendation engine
STAMP_VIEWER_RECOMMENDATIONS_READY_BEFORE_USER_REACHED_ENDCONFIRMEDRecommendations preloaded before story ends
SEARCH_WEB_STORYCONFIRMEDWeb Story in search results

Paid Discover Ads (Demand Gen) BYPASSES ALL ORGANIC

Paid ad cards bypass ALL organic signals. Entity matching, pCTR history, domain authority — none required. A brand new domain can appear in Discover feeds within hours via Google Ads Demand Gen campaigns.
EventSDK Evidence
DISCOVER_ADS_CARD_CLICKCONFIRMED — paid ad card click event
DISCOVER_ADS_BOC_ICONCONFIRMED — Back-of-Card "Ad" icon
FEED_AD_WTACONFIRMED — "Why This Ad" transparency
discover-adsCONFIRMED — ads subsystem identifier

Feed Hierarchy & Cluster Types 13 types

MAIN_FEED └── COLLECTION (publisher/topic groups) └── CLUSTER (content clusters, 13 types) └── CARD (individual content items)
Cluster TypeDescription
neonclusterPrimary content cluster
geotargetingstoriesLocation-based stories
deeptrendsfableDeep trend narratives
deeptrendsTrending topics
freshvideosRecent video content
mustntmissPriority/must-read content
newsstoriesheadlinesBreaking news headlines
homestackWidget cards (weather, sports)
garamondrelatedarticlegroupingRelated article groups
trendingugcUser-generated trending content
signinlureUser acquisition / sign-in prompt
iospromoCross-platform promotion
moonstoneInternal codename cluster

Fetch Eligibility Pipeline — 3-Stage Gating DSE LOCK-IN

EventSDK EvidenceStage
FETCH_ELIGIBILITY_STARTCONFIRMEDCheck begins
FETCH_ELIGIBILITY_END_LOCALCONFIRMEDStage 1: Local device checks
FETCH_ELIGIBILITY_END_NETWORKCONFIRMEDStage 2: Server validation
FETCH_ELIGIBILITY_END_GMSCORECONFIRMEDStage 3: Google Mobile Services

Ineligibility Reasons

ReasonSDK String
Discover disabledINELIGIBLE_DISCOVER_DISABLED
Non-Google search engineINELIGIBLE_DISCOVER_DISABLED_BY_DSE
Enterprise policyINELIGIBLE_DISCOVER_DISABLED_BY_ENTERPRISE_POLICY
User-level blockUSER_INELIGIBLE_FOR_DISCOVER
DSE lock-in: INELIGIBLE_DISCOVER_DISABLED_BY_DSE means if a user changes their default search engine to anything other than Google, Discover is automatically disabled. Search engine choice directly controls content feed access.

SDK Persistent User State — 14 Categories COMPLETE STATE MODEL

14 persistent state categories observed via SDK runtime state capture. All user interactions with Discover are stored as key-value pairs under the /persistent/ namespace, with paths dynamically created per content item. This reveals the complete data model for how Discover tracks user behavior. Path counts vary per user — structure and category names are universal.
/persistent/ ├── do_{id} + dismiss_overlay_{id} ──── N paths (content dismissal tracking) ├── heart/ID_TYPE_CANONICAL_URL/{url} ── N paths (liked/hearted content) ├── follows/{entity_or_mid} ──────────── N paths (followed topics/publishers) ├── article_content_model_data_{id} ──── 32 paths (article content state) ├── tombstone_{id}/data ──────────────── N paths (permanently dismissed content) ├── save/{id} ────────────────────────── N paths (bookmarked articles) ├── expandable_text/{id}/expansion_state 18 paths (text expand/collapse) ├── subscriptions/{entity} ───────────── 13 paths (topic subscriptions) ├── content_on_back/{id}/SURVEY_ON_CLICK 6 paths (back-button surveys) ├── cardMenuActiveSubmenu ────────────── 3 paths (card menu state) ├── gallery/{id}/slide_index ─────────── 2 paths (carousel position) ├── discoverfeed/appState ────────────── 1 path (feed session state) ├── game-content-data-/{entity} ──────── 1 path (game content) └── waa_state ────────────────────────── 1 path (Web & App Activity state)

Dismiss Overlay System per-content

Architecture: Every content dismissal creates TWO entries: /persistent/do_{contentID} (the dismiss action) and dismiss_overlay_{contentID} (the overlay UI state). This dual-write pattern enables both server-side sync and local UI persistence. Content IDs are 64-bit signed integers.
Path PatternFunctionCount
/persistent/do_{id}Records that user opened the dismiss overlay for contentPer-content IDs
dismiss_overlay_{id}Tracks the actual dismissal state within the overlayPaired with do_{id}
Version suffix 2]Serialized version marker for state synchronization25 trailing

Heart/Like System per-URL

Key pattern: /persistent/heart/ID_TYPE_CANONICAL_URL/{canonical_url}. Likes are keyed by the article's canonical URL, not by an internal ID. This means the like signal is directly tied to the URL and feeds back into personalization ranking.
URL PatternContent Types
Standard article URLs (major publishers)News articles, features
YouTube videos (youtube.com/watch?v=)Video content
Social media posts (x.com/*/status/*)Social media posts
Niche/specialty publisher URLsSpecialized content

Follow/Subscribe System per-entity

Dual system: Follows use /persistent/follows/{entity} with /g/ (Google KG) or /m/ (Freebase MID) prefixes. Subscriptions are a parallel key: /persistent/subscriptions/{entity}. Each follow also has a timestamp_identifier for ordering.
Path PatternEntity TypeExamples
/persistent/follows//m/{mid}Freebase MID entities/m/0xxxx_, /m/0yyyy_, /m/0zzzz (demo MIDs)
/persistent/follows//g/{id}Google KG entities/g/11xxxxxxxxx, /g/11yyyyyyyyy (demo KG IDs)
/persistent/follows/{name}Named publishers{publisher_name} (demo — publisher names redacted)
/persistent/subscriptions/{entity}Parallel subscription keySame entities as follows

Tombstone System per-content

Permanent suppression: Each tombstone at /persistent/tombstone_{contentID}/data permanently prevents that content from resurfacing. Content IDs in tombstones match the dismiss overlay IDs, creating a three-layer dismissal chain: do_{id}dismiss_overlay_{id}tombstone_{id}/data.

Save/Bookmark System per-content

Pattern: /persistent/save/{contentID}. Saved articles share the same 64-bit content IDs used across the entire state model. This allows cross-referencing between saved, liked, dismissed, and expanded content.

Additional State Categories

CategoryPath PatternFunction
Text Expansion/persistent/expandable_text/{id}/expansion_stateTracks whether user expanded AI summary or article text
Content Interaction/persistent/content_on_back/{id}/SURVEY_ON_CLICK/{timestamp}/...Tracks back-button survey responses, tap state, long-click duration
Card Menu/persistent/cardMenuActiveSubmenuWhich card menu submenu is currently active
Gallery/persistent/gallery/{id}/slide_indexCurrent position in carousel galleries
Feed State/persistent/discoverfeed/StateOverall feed session state
Game Content/persistent/-game-content-data-/{entity}Gaming content state
WAA State/persistent/waa_stateWeb & App Activity toggle state
SEO implication: The state model reveals that Discover maintains a per-URL engagement graph across hearts, saves, dismissals, and text expansion. Publishers whose articles receive high heart + save + expansion rates build persistent positive signals. Conversely, tombstoned content is permanently blacklisted from that user's feed.

Runtime Feature Flags — 51 Flags Across 15 Categories SDK EVIDENCE

51 runtime feature flags captured from SDK state. These Category.flag_name flags control Discover rendering, video handling, content viewer behavior, weather widgets, sports widgets, and AI summaries in real-time.
CategoryCountFlags
ContentViewer13enable_creator_header_in_video_anchor_content, enable_creator_header_in_viewer, enable_deep_dive_entry_point_for_aio_videos, enable_deep_dive_entry_point_for_videos, enable_divider_in_video_viewer_anchor, enable_extra_padding_in_video_anchor, enable_font_updates, enable_icon_entrypoint_for_non_embeddable_videos, enable_status_bar_scrim_protection, enable_video_anchor_expanded_tap_target, enable_viewer_header_back_button, force_immersive_initial_state, use_icon_entry_point_button
HomestackFeed9enable_chance_of_rain_on_weather_widget, enable_cta_on_weather_widget_, enable_divider_after_homestack, enable_divider_with_utilities, enable_greater_sign_as_weather_cta, enable_high_and_low_on_weather_widget, enable_sds_aligned_sports_widget_status_chip, enable_chance_of_rain_and_high_low_on_weather_widget_with_precip_icon, enable_chance_of_rain_and_high_low_on_weather_widget_with_precip_text
PrefabsRendering9disable_ai_summary_disclaimer, disable_creator_header_secodary_image, disable_gallery_horizontal_swipe_on_minus_one, enable_ai_summary_alternative_expandable_text, enable_favicon_outline, enable_increased_header_height_for_aio, enable_vertically_centered_gallery_buttons, title_expands_ai_summary, title_overlay_cta_arrow
TenForwardVideoPackaged3enable_xuikit_rendering_for_header_and_anchored_content, enable_framework_multi_state_viewer, enable_lfv_viewer
SportsWidget3disable_sports_widget_design_tweaks_status_pill, enable_status_tweaks_for_all_sports, enable_status_tweaks_live_text_color_for_all_sports
DiscoverPostContentRendering3append_open_content_text_to_post_body, move_post_title_above_media, enable_post_singleton_source_cta_on_footer
HomestackChrome2enable_homestack_on_bling, enable_homestack_on_clank
DiscoverGaramondRendering2apply_fake_garamond_header, show_publisher_in_footer
DiscoverArticleContentRendering1enable_title_overlay_for_non_aio_articles
DiscoverCreatorProfileLinkRendering1increase_header_height_with_secondary_text
DiscoverRenderNext1use_discover_time_stamp_text
DiscoverRowCompositeRendering1enable_hiding_and_showing_carousel
HomestackBentoFramework1enable_follow_widget_for_trending_sports
HomestackTopOfFeed1homestack_containment
TweedRendering1enable_mvr_prefab_full_bleed_ui_mobile_web
Key flag insights:
HomestackChrome.enable_homestack_on_clank — "Clank" is Chrome's internal codename, confirming Homestack integration with Chrome
PrefabsRendering.disable_ai_summary_disclaimer — flag to remove "Generated with AI" disclaimers
title_expands_ai_summary — clicking a title can auto-expand the AI summary
apply_fake_garamond_header — can simulate related-article groupings synthetically
DiscoverRowCompositeRendering.enable_hiding_and_showing_carousel — controls carousel visibility dynamically

Server Experiment Allocation — 150 Active A/B Tests LIVE SESSION

~150 GWS (Google Web Server) experiment IDs observed in SDK session state. Format: gws:NNNNNNN. Each represents a server-side A/B test or feature rollout controlling ranking, rendering, and feed composition. Stored in SESSION::ServerExperimentIds. Actual IDs redacted — format and scale are authentic.

Experiment ID Format

MetricValue
Total experiments per session~150
ID formatgws:NNNNNNN (7–9 digit numeric)
ID range spanPrimary cluster + occasional high outliers

What This Proves

At any given time, a single user is enrolled in ~150 concurrent experiments. These experiment IDs control:

  • Content ranking algorithm variants
  • UI layout and card rendering changes
  • Personalization model experiments
  • Freshness decay parameters

Experiment ID Format (Demo)

gws:7XXXXXXXgws:7XXXXXXXgws:7XXXXXXXgws:7XXXXXXXgws:7XXXXXXX... ×145 more ...
Key insight: The ~150 IDs cluster in a narrow numeric range, suggesting they originate from the same experiment allocation epoch. Occasional high outliers (9XXXXXXX, 10XXXXXXXX range) indicate legacy or cross-system experiments persisting across sessions.

Per-Card Diagnostic Metadata — Internal Signal Architecture 8 SIGNALS PER CARD

Every card in the Discover feed carries internal diagnostic metadata beyond what users see. These 8 meta-label fields were captured from live SDK state on each feed entry.
Meta LabelObserved ValueSignificance
Panoptic Source ChannelPer-card channel identifierIdentifies the source pipeline (e.g., neoncluster, geotargetingstories) that surfaced this content
DocFingerprint14-char alphanumeric hash (e.g., tDSTsgTVG0c5FM)Unique document fingerprint for deduplication across sessions and devices
Web and App Activity EnabledBooleanWhether WAA is active — controls personalization eligibility
Discover Personalization EnabledBooleanWhether per-user interest personalization is active for this card
NeoformId8-char hash (e.g., uoPWxbzo)Neoform rendering template identifier — maps to specific card layout variant
Is Feature PersonalizedBooleanWhether this specific card was personalized (vs. generic/trending)
Is User Signed-InBooleanSigned-in state affects which signals feed the ranking model
Sherlog URLURL or "Not opted in to Sherlog"Google's internal debugging/logging system URL for this card render — when present, enables detailed server-side diagnostics

Additional Per-Card Signals

SignalExamplePurpose
Card TitleFull article title as servedTitle as delivered to the ranking model
Card URLCanonical content URLThe URL Discover associates with this content
Card categoryTopic entities (e.g., "Winter storm, Road conditions, Meteorology")Entity tags used for interest matching
Need bundle TypeContent delivery classificationHow the card was bundled for delivery

Card Menu Actions (per card)

Each card exposes a standardized menu with these actions:

More options See less content like this Not interested in a topic Don't show content from [Publisher] Report this Submit a report Misleading or sensational Violent or repulsive Hateful or abusive Intrusive or too personal Send feedback
Publisher block: The fake_publisher_block_menu_line string reveals the publisher-level block UI. When a user selects "Don't show content from [Publisher]", it creates a filter_collection_status event that blocks ALL content from that domain — not just the specific article.

SDK Configuration Payloads — 4 Core Config Files SERIALIZED DATA

4 serialized configuration payloads captured from SDK runtime. These control Discover's eligibility, language, refresh scheduling, and growth tracking.
ConfigSizeKey FieldsDecoded Value
DiscoverEligibility2 BField 1: booleantrue — Discover is eligible for this user
DiscoverLanguage4 BField 1 → Field 4: booleanfalse — Language not manually selected (auto-detected)
RefreshMetadata9 BField 1: timestamp (microseconds)Last refresh: 202X-XX-XX XX:XX:XX UTC
GrowthTracking13.2 KBField 5: feature milestones; Field 6: daily usage79 days tracked (2025-11-25 → 2026-02-23), 2 feature milestones

GrowthTracking Deep Dive

Feature Milestones

FeatureStartEndMilestones
Feature 12025-08-032025-09-22Aug 19, Sep 22
Feature 22025-09-222025-10-14Oct 14

Usage Tracking

MetricValue
Days tracked93 days
First seen2025-07-18
Last seen2025-10-19
Entries (Field 6)95 daily usage records
Implication: Google tracks per-user Discover usage at daily granularity. 93 days of continuous usage data feeds into engagement models, affecting content ranking, experiment allocation, and potentially pCTR calibration for that user.

Feed Session State

FieldValue
Active FeedMAIN_FEED
Session State Size9,145 bytes
Root NodeTYPE_UNDEFINED::root::0
Tree Structurechildgroup.f::828783447
Rendering State Key/discoverfeed/renderingstate
Last Interaction202X-XX-XX XX:XX:XX (Unix: 1766996656)

Live Feed Structure — Card Composition & AI Summary Flags DEMO DATA

Representative feed sample observed from SDK state. Each entry includes the full content card with title, source, AI summary flag, URL count, internal path count, and serialized size. ~59% of articles had AI-generated summaries attached. Titles and sources below are demo placeholders illustrating the structure — actual content redacted for privacy.
#Title (demo)Source (demo)AIURLsPathsSize (B)
1Major weather system brings record conditions to eastern seaboard...Regional News Outlet AAI1814~12.7K
2Senior lawmaker makes bold prediction ahead of midterm cycle...National News NetworkAI1914~12.8K
3Creator Profile Link card(Creator card)1921~13.8K
4Federal agency releases large cache of previously undisclosed records...News Outlet BAI1914~13.2K
5Professional sports team extends historic winning streak...(Sports)AI2014~12.7K
6Two neighboring nations reach diplomatic agreement after tensions...Wire ServiceAI2014~13.1K
7Creator card — [Business Publisher]Follow [Business Publisher]1318~11.9K
8League team dominates rival in late-season matchup...Sports/LeagueAI1814~12.8K
9Creator card — [Entertainment Publisher]Follow [Entertainment]1819~11.7K
10Creator card — [International News Outlet]Follow [International News]1318~10.5K
11Creator card — [Major Newspaper]Follow [Major Newspaper]1816~14.2K
12Upcoming year to feature rare astronomical events...(Science)AI1913~12.7K
13Creator card — [Cable News Network]Follow [Cable News]1018~10.1K
14Creator card — [Education Publisher]Follow [Education]1018~10.4K
15–16Creator cards (various)(Creator cards)1018~10.5K
17Emergency services respond to infrastructure incident in metro area...Local TV StationAI1814~12.6K
18Creator card (various)(Creator card)1018~10.5K
19Iconic cultural figure passes away at advanced age...International BroadcasterAI2014~13.0K
20Creator card (various)(Creator card)1219~13.8K
21Government agency announces new policy affecting travelers...National BroadcasterAI1914~12.8K
22Creator card (various)(Creator card)1018~10.7K
23Centenarian veteran honored at professional sporting event...Sports Team MediaAI1914~12.9K
24Military government proceeds with disputed electoral process...International News ServiceAI1914~13.0K
25New research reveals health concerns linked to everyday consumer product...(Health)AI1313~11.7K
26Creator card — [Finance Publisher]Follow [Finance]1819~11.9K
27Civilian population faces humanitarian crisis amid ongoing conflict...International News ServiceAI2014~13.2K
28Significant seismic event detected near island nation's coast...Global News ChannelAI1914~13.0K
29Region braces for extreme cold as arctic weather system approaches...Regional TV StationAI2014~13.0K

Feed Composition Analysis

Content Distribution

TypeCount%
News articles with AI summaries1759%
Creator profile link cards (follow CTAs)1241%

Size Statistics

MetricValue
Avg card size (articles)~12,800 bytes
Avg card size (creator)~11,400 bytes
Total feed payload~350 KB for 29 cards
Key findings:
59% AI penetration — the majority of news articles now carry ***Generated with AI, which can make mistakes disclaimers
41% creator cards — nearly half the feed is "Follow [Publisher]" creator profile link cards, using the NDiscoverCreatorProfileLinkRendering.increase_header_height_with_secondary_text flag
Each article card carries ~23 feature flags, ~14–21 internal paths, and ~13–20 URLs (content + thumbnails + icons + share links + support links)
Signed-in AI summaries are gated behind PrefabsRendering.title_expands_ai_summary and PrefabsRendering.disable_ai_summary_disclaimer

Growth Tracking & Usage Analytics LONGITUDINAL DATA

Multi-month continuous tracking of Discover usage observed via SDK-level analytics. This proves Google maintains per-user daily engagement histories at the SDK level, feeding into personalization, experiment allocation, and user-tier classification. Dates and durations below are demo values — structure and field names are authentic.

Tracking Window

PeriodValue
First observation2025-07-18
Last observation2025-10-19
Duration93 days (continuous)
Daily records95 entries (some gaps filled)

What Gets Tracked

  • Daily active usage (binary: used/not used)
  • Feature milestone progression
  • Feed refresh timestamps (microsecond precision)
  • Session state sizes
  • Experiment allocation persistence
SEO implication: Users with longer engagement histories likely receive different content treatment than new users. The growth tracking data feeds into user-tier classification, which may affect pCTR model parameters, experiment bucket selection, and personalization depth.

Event Catalog — 89 of 276 DISCOVER_ Events KEY CATEGORIES

276 unique DISCOVER_ event constants extracted from the SDK. The 89 most important events are shown below, organized by lifecycle phase. Remaining events cover ads, beacon push, stamp/stories, multi-language, eligibility, engagement, and other subsystems.

Launch & Initialization (18 events)

DISCOVER_LAUNCHDISCOVER_LAUNCH_FINISHEDDISCOVER_LAUNCH_FINISHED_OFFLINE
DISCOVER_LAUNCH_FOREGROUND_STARTDISCOVER_UI_STARTINGDISCOVER_FRAGMENT_INSTANTIATE
DISCOVER_VIEW_SHOWNDISCOVER_VISIBLE_TO_USERDISCOVER_HIDDEN_FROM_USER
DISCOVER_ENABLEDDISCOVER_DISABLED_USERDISCOVER_AUTO_ENABLED
DISCOVER_AUTO_ENABLE_ELIGIBLEDISCOVER_INELIGIBLE_USERDISCOVER_STATE
DISCOVER_HOME_FEED_VIEW_CONTROLLER_INSTANTIATEDISCOVER_NON_HOME_FEED_VIEW_CONTROLLER_INSTANTIATEFIRST_DRAW_DONE_DISCOVER_GOOGLE_APP

Feed Requests & Responses (21 events)

DISCOVER_FEED_REQUEST_STARTDISCOVER_FEED_REQUEST_SENTDISCOVER_FEED_REQUEST_SUCCESS
DISCOVER_FEED_REQUEST_FAILUREDISCOVER_FEED_REQUEST_FINISHEDDISCOVER_FEED_RESPONSE_RECEIVED
DISCOVER_INTERACTIVE_FEED_REQUEST_STARTDISCOVER_INTERACTIVE_FEED_REQUEST_FINISHEDDISCOVER_BACKGROUND_FEED_REQUEST_START
DISCOVER_HOMESTACK_FEED_REQUEST_STARTDISCOVER_CHANNELS_FEED_REQUEST_STARTDISCOVER_VIEWER_FEED_REQUEST_START
DISCOVER_SINGLE_WEB_FEED_REQUEST_STARTDISCOVER_PINNED_CONTENT_FEED_REQUEST_STARTDISCOVER_RELATED_VIDEOS_FEED_REQUEST_START
DISCOVER_FEED_TUNING_REFRESH_REQUEST_STARTDISCOVER_REQUEST_BACKEND_DISCOFEEDDISCOVER_REQUEST_BACKEND_GWS
DISCOVER_REQUEST_BACKEND_UNSPECIFIEDDISCOVER_REQUEST_SERVER_NETWORK_SPLITDISCOVER_REQUEST_BUILDER

Pagination (14 events)

DISCOVER_NEXT_PAGEDISCOVER_NEXT_PAGE_STARTDISCOVER_NEXT_PAGE_END
DISCOVER_NEXT_PAGE_END_OFFLINEDISCOVER_NEXT_PAGE_EAGER_STARTDISCOVER_NEXT_PAGE_SILENT_START
DISCOVER_NEXT_PAGE_REQUEST_STARTDISCOVER_NEXT_PAGE_FEED_REQUEST_STARTDISCOVER_PAGINATION_NEXT_PAGE
DISCOVER_FEED_PAGINATION_STARTDISCOVER_FEED_PAGINATION_ENDDISCOVER_FEED_PAGINATION_REQUEST_FINISHED
DISCOVER_SILENT_PAGINATION_STARTDISCOVER_SILENT_PAGINATION_END

Refresh & Update (18 events)

DISCOVER_REFRESHDISCOVER_REFRESH_SUCCESSDISCOVER_REFRESH_ERROR
DISCOVER_REFRESH_DISABLEDDISCOVER_REFRESH_FETCH_SUCCEEDEDDISCOVER_REFRESH_FETCH_FAILED
DISCOVER_REFRESH_DISPLAY_CANCELLEDDISCOVER_REFRESH_PILL_TAPDISCOVER_REFRESH_PILL_TAP_START
DISCOVER_REFRESH_PILL_TAP_ENDDISCOVER_REFRESH_PILL_PREPARATIONDISCOVER_REFRESH_PILL_PREPARATION_END
DISCOVER_MANUAL_REFRESHDISCOVER_MODEL_REFRESH_STARTDISCOVER_MODEL_REFRESH_END
DISCOVER_MODEL_REFRESH_DECISION_STARTDISCOVER_MODEL_REFRESH_DECISION_ENDDISCOVER_RELOAD_FINISHED

TNG (The Next Google) Events (18 events)

DISCOVER_TNG_INTERACTIVE_REFRESHDISCOVER_TNG_INTERACTIVE_REFRESH_STARTDISCOVER_TNG_INTERACTIVE_REFRESH_COMPLETED
DISCOVER_TNG_PULL_TO_REFRESH_STARTDISCOVER_TNG_PULL_TO_REFRESH_SUCCESSDISCOVER_TNG_PULL_TO_REFRESH_ERROR
DISCOVER_TNG_PULL_TO_REFRESH_CANCELDISCOVER_TNG_PULL_TO_REFRESH_DISABLEDDISCOVER_TNG_BACKGROUND_REFRESH_START
DISCOVER_TNG_BACKGROUND_REFRESH_SUCCESSDISCOVER_TNG_BACKGROUND_REFRESH_FAILUREDISCOVER_TNG_BACKGROUND_REFRESH_COMPLETE
DISCOVER_TNG_ACTION_UPLOAD_STARTDISCOVER_TNG_ACTION_UPLOAD_SUCCESSDISCOVER_TNG_ACTION_UPLOAD_FAILURE
DISCOVER_TNG_ACTION_UPLOAD_COMPLETEDISCOVER_TNG_TAP_TO_UPDATE_STARTDISCOVER_TNG_HOME_TAB_REFRESH_START

Discover Telemetry Counters — 56 Instrumentation Points COMPLETE LIST

56 telemetry instrumentation points extracted from the SDK. These counters track every measurable aspect of Discover feed behavior, from cache performance to streaming connections.
CategoryCounter
Surfacesurface_name
Attentionattention_log
Foldingfolding_state
GCfeeds_gc_count, persisted_feeds_post_gc_count
Session closesession_close/enqueue, session_close/refresh, session_close/ineligible
Actionsclient_actions_count
Authresponse_auth_refresh, missing_auth_header_count
Search boxsearch_box_click_count
Cachestream_cache_hit_count, stream_cache_miss_count, stream_cache_cleared_count
Feed showsuggestions_shown_count, minus_one_feed_show_count
Refresh pillrefresh_pill_hidden_count, scrolled_till_refresh_pill_delta_count
URL fetcherurl_fetcher/request_count, url_fetcher/http_error_count
Offlinecui/offline_to_online_count, cui/next_page_response_received
Trim memoryminusone/on_trim_memory_count
Streamingstreaming_connection_lock, streaming_connection_unlock, streaming_connection_duration, streaming_session_type_mismatch_v2, streaming_next_page_response_received, streaming_connection_reopened_due_to_session_switch, streaming_connection_state_when_sending_client_actions_failed
Filteringcontent/filter_entity_status, content/filter_collection_status
Refreshbackground_refresh_for_type_count, background_refresh_rug_pull_count, deferred_background_refresh_count, background_refresh_scheduled_delay, background_refresh/schedule_attempt
Contentcontent_viewer_empty_data_count, discover_subtree_content_fetch_duration
Beaconbeacon/search_cleared_count, beacon/donated_sports_documents_count, beacon/dropped_sports_notifications_count, beacon/incoming_sports_notifications_count
Scrollscroll_while_viewport_hidden_count
Back to topback_to_top_button_shown_count
TNGclassic_minus_one_created_in_tng, touches_on_orphaned_minusone_window_count, minus_one_non_gced_window_count
Notificationfeed_launch_from_notification_appflow_count
Imageelements_interaction/image_load_failure_count
Gesturesgesture_exclusion/count, gesture_exclusion/total_height
On-deviceon_device_content/metadata_size
Sessionsession/exception_v1_v2_difference_count
SRSsrs/hydration_status

Fact Check — Findings Verified Against SDK Evidence VERIFIED

Methodology: Every finding was cross-referenced against strings extracted directly from the Google Search SDK. "CONFIRMED" means the exact string was found. "PARTIAL" means strong indirect evidence exists.
FindingSDK EvidenceVerdict
pCTR model exists and is triggeredPCTR_MODEL_TRIGGERED — exists as event string, but in a generic telemetry enum, not a Discover-specific classPARTIAL
og:image is mandatory for card renderingog:image + EMBER_FEED_THUMBNAILS_DOWNLOADEDCONFIRMED
og:title feeds into rankingog:title extracted into ContentMetadata protobuf and sent to server. No direct client-side link to pCTR scoring. The pCTR model is server-side.PARTIAL
article:content_tier parsed for paywallarticle:content_tier — exact stringCONFIRMED
isCollectionHiddenFromEmberFeed is booleanisCollectionHiddenFromEmberFeed= (field assignment pattern) — confirmed as boolean, but on CollectionDetailsData (boov.java) for the Ember tab, not the Discover feed. The Discover-specific filters are filter_collection_status / filter_entity_status from bupa.java.PARTIAL
filter_collection_status counter existsfilter_collection_status telemetry counterCONFIRMED
filter_entity_status counter existsfilter_entity_status telemetry counterCONFIRMED
Counterfactual suppression mechanismSHOW_SKIPPED_DUE_TO_COUNTERFACTUAL, DELIVERED_COUNTERFACTUAL, FETCHED_COUNTERFACTUAL, VISIBILITY_REPRESSED_COUNTERFACTUALCONFIRMED
Rug pull mechanism existsbackground_refresh_rug_pull_countCONFIRMED
Beacon push system (5 events)All 5 DISCOVER_BEACON_PUSH_* events confirmedCONFIRMED
Web Stories have dedicated pipelineINLINE_STAMP_VIEWER_FRAGMENT, STAMP_VIEWER_RECOMMENDATIONSCONFIRMED
Paid ads in Discover feedsDISCOVER_ADS_CARD_CLICK, DISCOVER_ADS_BOC_ICONCONFIRMED
18 PERSONAL_UPDATE subtypes18 Discover-specific subtypes extracted from SDK (3 AIM-only excluded)CONFIRMED
Freshness measured in secondsfreshness_delta_in_seconds — string exists but appears in eblv.java (Smartspace weather/air quality metrics), not a confirmed Discover classPARTIAL
3 freshness decay buckets1_TO_7_DAYS, 8_TO_14_DAYS, 15_TO_30_DAYS — strings exist but appear in bemp.java (GestureSettingsPreferenceFragment), not a confirmed Discover classPARTIAL
Staleness measured in hoursstaleness_in_hours — string exists but appears in eblv.java (weather metrics), not a confirmed Discover classPARTIAL
Geller interest graph syncs via named synclets (shared infra, consumed by Discover)SYNCLET_NAME_ASSISTANT_AIP_TOP_ENTITIES_PERIODIC_REFRESHCONFIRMED
276 DISCOVER_ events276 unique DISCOVER_ prefixed strings extractedCONFIRMED
56 Discover telemetry counters56 unique instrumentation points for Discover feed behaviorCONFIRMED
6 gRPC servicesAll 6 service paths extracted including streaming variantCONFIRMED
WPAS content type from Publisher CenterSUBTYPE_PERSONAL_UPDATE_WPASCONFIRMED
RECALL_BOOST increases retrieval prioritySUBTYPE_PERSONAL_UPDATE_RECALL_BOOSTCONFIRMED
DSE lock-in disables DiscoverINELIGIBLE_DISCOVER_DISABLED_BY_DSECONFIRMED
Enterprise policy can disable DiscoverINELIGIBLE_DISCOVER_DISABLED_BY_ENTERPRISE_POLICYCONFIRMED
WebP image supportDISCOVERY_CARD_WEBP_IMAGE_SUPPORTCONFIRMED
Multi-language feed supportdiscover_multi_language_visibility, DISCOVER_MULTIPLE_LANGUAGE_PAGE_LINKCONFIRMED
Beacon push bypasses normal rankingBeacon pipeline separate from ranking events; ACCEPTED/REJECTED suggests filteringPARTIAL

Findings from SDK State Capture 15 additional

FindingEvidenceStatus
14 persistent state categories track all user interactions14 path categories under /persistent/ namespace captured from SDK stateCONFIRMED
Hearts/likes are keyed by canonical URL, not internal ID/persistent/heart/ID_TYPE_CANONICAL_URL/{url} pattern observedCONFIRMED
Follows use Knowledge Graph MIDs (/m/) and KG IDs (/g/)Follow paths with /m/ and /g/ prefixes + named publishersCONFIRMED
Tombstones create permanent per-content suppression/persistent/tombstone_{id}/data paths matching dismiss overlay IDsCONFIRMED
Three-layer dismissal chain (do → dismiss_overlay → tombstone)Dismiss paths + tombstones share same content IDsCONFIRMED
51 runtime feature flags across 15 categoriesAll Category.flag_name flags captured from rendered feed cardsCONFIRMED
~150 concurrent GWS experiments per session150 gws:NNNNNNN IDs from SESSION::ServerExperimentIdsCONFIRMED
Majority of articles carry AI-generated summariesObserved articles with ***Generated with AI disclaimerCONFIRMED
Significant portion of feed entries are creator follow cardsFeed contains NDiscoverCreatorProfileLinkRendering cardsCONFIRMED
Per-card diagnostic metadata includes 8 signal fieldsPanoptic Source, DocFingerprint, WAA, NeoformId, Sherlog, etc. on every cardCONFIRMED
Growth tracking covers 90+ days of daily usageGrowthTracking payload: daily records spanning multiple monthsCONFIRMED
DiscoverEligibility is a single boolean config2-byte serialized config: Field 1 = trueCONFIRMED
Feed tree: TYPE_UNDEFINED::root::0 → COLLECTION → CLUSTER → CARDRoot node, childgroup.f, and 13 cluster types observed in session stateCONFIRMED
HomestackChrome.enable_homestack_on_clank confirms Chrome = ClankFeature flag with "clank" (Chrome's internal codename) in SDK stateCONFIRMED

Findings from SDK Deobfuscation 4 additional (double fact-checked)

Methodology: Google Search SDK extracted → 12 modules (100MB) → decompilation → class/method tracing. Each finding verified independently twice (forward trace: OG→classes→Discover; reverse trace: Discover→viewer→metatags→OG).
FindingEvidenceStatus
OG tags exist exclusively in a single SDK module (5 tags, 0 in other 11 modules)Binary search across all 12 SDK modules: og:title×1, og:image×2, og:image:secure_url×1, og:locale×1, og:site_name×1 — all in one module onlyCONFIRMED
Title fallback chain: Schema.org (TEXT_TYPE_TITLE) → og:title → twitter:title → titleDeobfuscated Title Supplier + Fallback Supplier shows exact Optional.or() chain with const-string instructions. Schema.org JSON-LD checked first via dkri.java:1088-1092 + dknl.java:27-29.CONFIRMED
Image fallback chain: og:image → twitter:image → og:image:secure_url → twitter:image:src → imageDeobfuscated Image Callable + Fallback Supplier shows 5-step Optional.or() fallback. From dkpj.java: case 0 = twitter:image, case 2 = og:image:secure_url, case 3 = twitter:image:src, case 4 = image. After og:image (from dkri.java:1100).CONFIRMED
Blocking metatags nopagereadaloud and notranslate halt pipelinePaywall Detector: const-string "nopagereadaloud" + "notranslate" checked via Stream.concat → filter → allMatch, throws "The page contains blocking metatag: %s"CONFIRMED
Summary: 39 of 47 findings fully confirmed against SDK evidence. 8 findings partially confirmed — pCTR model existence (generic enum, not Discover-specific), og:title→ranking link (plausible, server-side), isCollectionHiddenFromEmberFeed (confirmed boolean but Ember tab not Discover), freshness_delta_in_seconds (exists in Smartspace weather class eblv.java), 3 freshness buckets (exist in gesture settings bemp.java), staleness_in_hours (weather metrics), beacon bypass (inference). Zero findings contradicted by evidence. pCTR/scoring claims corrected after deobfuscation revealed MAX_HIT_WEIGHT formula belongs to Icing search suggest, not Discover.