How the X Algorithm Blending Pipeline Interleaves Content and Ads

The blending pipeline converts raw candidate posts and ads into an ordered FeedItem stream by partitioning inputs, selecting a strategy-specific blender via the AdsBlenderType parameter, and interleaving items through gap computation and placement assignment before finalizing positions.

The xai-org/x-algorithm repository implements this orchestration logic in the home-mixer service. The blending pipeline interleaves content and ads through a three-stage Rust pipeline that separates organic content from promotional material, applies configurable spacing strategies, and assembles the final user feed with deterministic positioning.

Stage 1: Partitioning Raw Candidates

The process begins in home-mixer/selectors/blender_selector.rs, where the BlenderSelector::select method receives a heterogeneous Vec<FeedItem> containing mixed candidate types. The internal helper partition_feed_items splits this raw input into distinct collections:

  • Organic posts
  • Advertisements (ads)
  • "Who-to-follow" modules
  • Prompts
  • Push-to-home posts
  • Frames
  • Feed surveys

This separation ensures that each content category can be processed with specialized logic before final assembly. The partitioned vectors are then passed to the appropriate blending implementation based on query parameters.

Stage 2: Selecting a Blending Strategy

The pipeline determines interleaving behavior through the AdsBlenderType query parameter. The selector matches this parameter string to a concrete AdsBlender implementation:

  • safe_gap – Uses self.safe_gap_blender to enforce minimum safe distances between ads and organic posts
  • partition_organic_low_risk – Employs self.partition_organic_blender to place ads in slots that split the safe-post pool evenly with additional safety checks
  • multi_risk – Invokes self.multi_risk_blender to place ads based on computed risk scores
  • time_gap – Instantiates a TimeGapAdsBlender to adjust ad spacing based on temporal configuration

Once selected, the blender's blend method is invoked, which delegates to the strategy-specific blend_inner implementation defined in files such as home-mixer/ads/safe_gap_blender.rs or home-mixer/ads/partition_organic_blender.rs.

Stage 3: Core Interleaving Logic

Each blender produces a partial list where ads are strategically positioned among posts. The specific mechanics vary by strategy.

Safe-Gap Blending

In home-mixer/ads/safe_gap_blender.rs, the blend_impl function executes a four-step placement algorithm:

  1. find_safe_gaps – Identifies valid insertion points in the organic post sequence
  2. compute_spacing – Calculates optimal distance between advertisements
  3. assign_ads_to_gaps – Maps specific ads to specific gap indices based on spacing constraints
  4. interleave_and_finalize – Merges posts and ads into a single vector, truncates to RESULT_SIZE, removes trailing ads if they occupy the final slot, and assigns sequential position values
// safe_gap_blender.rs – blend_impl core logic
let safe_gaps = find_safe_gaps(&scored_posts);
let spacing = compute_spacing(&ads);
let placements = assign_ads_to_gaps(&safe_gaps, ads.len(), &spacing, first_ideal);
interleave_and_finalize(scored_posts, ads, &placements, result_size)

The interleave_and_finalize helper, shared between safe-gap and time-gap blenders, constructs the final FeedItem vector by placing ads at their assigned indices and filling remaining slots with organic content.

Partition-Organic Blending

The partition_organic_blender.rs implementation uses custom assembly logic rather than the generic interleaving helper. It creates ad-post triples (post-ad-post sequences) and distributes filler posts between gaps:

// partition_organic_blender.rs – blend_impl excerpt
for (i, (ad, above, below)) in triples.into_iter().enumerate() {
    items.push(FeedItem { item: Some(feed_item::Item::Post(above)), .. });
    items.push(FeedItem { item: Some(feed_item::Item::Ad(ad)), .. });
    items.push(FeedItem { item: Some(feed_item::Item::Post(below)), .. });

    // Insert filler posts between ad slots
    for _ in 0..filler_per_gap { /* push filler posts */ }
}

This approach ensures that ads never appear consecutively without organic content buffers, while maintaining even distribution throughout the feed.

Finalizing the Feed Stream

After the core blending completes, the BlenderSelector performs final assembly operations:

  1. Position Assignment – Each FeedItem receives a sequential position field corresponding to its vector index
  2. UI Element Insertion – Helper functions insert_prompts, insert_who_to_follow, insert_push_to_home, and related methods inject non-content modules at fixed positions (lines 102-176 in blender_selector.rs)
  3. Placeholder Generation – The build_non_selected_placeholders function converts dropped posts and ads into placeholder FeedItem objects, storing them in the non_selected vector for analytics and feedback loops
// Final position assignment in safe_gap_blender.rs (lines 94-96)
for (idx, item) in result.iter_mut().enumerate() {
    item.position = idx as i32;
}

Summary

Frequently Asked Questions

What determines which blending strategy is used in the X Algorithm?

The AdsBlenderType query parameter controls strategy selection. According to home-mixer/selectors/blender_selector.rs (lines 52-68), the selector matches string values like "safe_gap" or "partition_organic_low_risk" to specific blender implementations. If no valid type is specified, the system defaults to the partition-organic blender.

How does the safe-gap blender ensure minimum distance between ads?

The safe-gap strategy computes valid insertion points through find_safe_gaps and calculates spacing via compute_spacing in home-mixer/ads/util.rs. The assign_ads_to_gaps function then places ads only at indices that satisfy these distance constraints, ensuring no two ads appear closer than the configured threshold.

What happens to posts and ads that don't make it into the final feed?

Excluded items are preserved as placeholder FeedItem objects. The build_non_selected_placeholders method (lines 78-92 in blender_selector.rs) converts dropped candidates into tracking entries stored in the non_selected vector, allowing the system to record which content was available but not served.

Where is the interleaving logic implemented for time-based ad spacing?

The time-gap blender in home-mixer/ads/time_gap_blender.rs implements temporal spacing logic. Like the safe-gap blender, it uses the shared interleave_and_finalize helper to merge content, but calculates placement gaps based on time-interval configuration rather than raw index spacing.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →