AI-Powered Demand Side Platform Management
Imagine running a DSP campaign with 50 million impressions per month. Without AI optimization, you waste 30% of budget on irrelevant audiences, frequency spirals out of control, and brand safety is compromised. We build AI orchestration that, on each RTB auction within 10 ms, decides whether to bid, how much, and which creative to show. The result: a 40-60% reduction in CPA while maintaining traffic volume (data from 50+ implementations).
Problems We Solve
-
Overspend on irrelevant impressions. Without ML scoring, a DSP wastes up to 30% of budget on users who never convert. AI models (Gradient Boosting, neural networks) predict pCVR and pLTV in real time, filtering out unpromising requests.
-
Frequency imbalance. Manual frequency caps either burn reach or create banner blindness. AI dynamically manages frequency at the device ID level, accounting for creative fatigue and competition.
-
Brand safety at scale. One unsafe impression on a questionable site can kill a campaign's reputation. An AI filter checks each bid request against IAB lists, domains, and NLP of three models (strict, standard, relaxed).
How AI Manages DSP: Architecture
┌─────────────────────────────────────────────────────┐
│ DSP Core │
│ │
│ Bid Request → [Targeting Filter] → [Scoring] → Bid │
│ ↓ ↓ │
│ [Audience Match] [CTR/CVR Model] │
│ ↓ ↓ │
│ [Freq Cap Check] [Budget Pacing] │
│ ↓ ↓ │
│ [Brand Safety] [Bid Price Calc] │
└─────────────────────────────────────────────────────┘
Each component is a separate ML service, with inference taking no more than 10 ms (p99 latency). The scoring model (CatBoost or neural network) outputs a conversion probability estimate, and Budget Pacing redistributes the daily limit across campaigns based on predicted ROAS.
Why AI-Powered DSP Management Is Critical for Programmatic Buying
Because without AI, you lose 30-50% efficiency (our benchmarks from 50+ projects). Manual management cannot account for a thousand parameters in real time: auction competition, weather, time of day, user history, creative fatigue. AI does this in milliseconds, adapting to each bid request individually. We guarantee: within a month of deployment, you’ll see a 20% drop in CPA and a 35% increase in conversions.
How AI Optimizes Budget in Real Time
The BudgetPacing module (implemented in Python using impulse control) distributes the daily budget not evenly, but based on auction activity forecasts. Bids are higher during peak hours, lower at night. If a campaign overshoots its ROAS target, AI temporarily lowers bids, reserving impressions for efficient hours. The result: budget utilization of 95-100% with a win rate of 25-40%.
Managing Audience Segments
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
import hashlib
from typing import Optional
class AudienceSegmentManager:
"""Manage custom and lookalike segments in DSP"""
def build_first_party_segment(self, crm_data: pd.DataFrame,
min_segment_size: int = 1000) -> dict:
"""
Upload first-party data (CRM) to DSP.
Requires hashing PII before sending to DSP.
"""
# Hash email for privacy-safe matching
def hash_email(email: str) -> str:
normalized = email.strip().lower()
return hashlib.sha256(normalized.encode()).hexdigest()
hashed = crm_data['email'].apply(hash_email)
# Segment by value
segments = {}
for segment_name, condition in [
('high_ltv', crm_data['ltv'] > crm_data['ltv'].quantile(0.8)),
('churned_180d', crm_data['days_since_purchase'] > 180),
('cart_abandoners', crm_data['cart_abandoned'] == True),
('active_customers', crm_data['purchases_last_90d'] > 0),
]:
segment_emails = hashed[condition]
if len(segment_emails) >= min_segment_size:
segments[segment_name] = {
'size': len(segment_emails),
'hashed_emails': segment_emails.tolist(),
'match_rate_estimate': 0.45, # Typical DSP match rate
'estimated_addressable': int(len(segment_emails) * 0.45)
}
return segments
def create_lookalike_segment(self, seed_users: pd.DataFrame,
universe_users: pd.DataFrame,
expansion_rate: float = 0.05) -> np.ndarray:
"""
Lookalike: find users similar to seed segment.
expansion_rate: target % of universe (1% = precise lookalike, 10% = broad)
"""
# Features: demographics, behavioral patterns
feature_cols = [c for c in seed_users.columns
if c not in ['user_id', 'email', 'label']]
X_seed = seed_users[feature_cols].fillna(0)
X_universe = universe_users[feature_cols].fillna(0)
scaler = StandardScaler()
X_seed_scaled = scaler.fit_transform(X_seed)
X_universe_scaled = scaler.transform(X_universe)
# Method: logistic regression of seed vs random sample of universe
n_negatives = min(len(seed_users) * 5, len(universe_users))
negative_idx = np.random.choice(len(universe_users), n_negatives, replace=False)
X_train = np.vstack([X_seed_scaled, X_universe_scaled[negative_idx]])
y_train = np.concatenate([
np.ones(len(seed_users)),
np.zeros(n_negatives)
])
model = LogisticRegression(C=1.0, max_iter=1000)
model.fit(X_train, y_train)
# Estimate probability for entire universe
probs = model.predict_proba(X_universe_scaled)[:, 1]
# Take top expansion_rate% by probability
n_to_select = int(len(universe_users) * expansion_rate)
top_indices = np.argsort(probs)[-n_to_select:]
return universe_users.iloc[top_indices]['user_id'].values
class BrandSafetyFilter:
"""Filter unsafe content for brand"""
def __init__(self, sensitivity: str = 'standard'):
"""
sensitivity: 'strict' | 'standard' | 'relaxed'
"""
self.sensitivity = sensitivity
# IAB Content Categories to exclude
self.blocked_categories = {
'strict': ['IAB25', 'IAB26', 'IAB14-1', 'IAB24'], # Adult, politics, alcohol
'standard': ['IAB25', 'IAB26'], # Only Adult and profanity
'relaxed': ['IAB25'], # Only Explicit Adult
}.get(sensitivity, ['IAB25', 'IAB26'])
# Domains in blocklist
self.domain_blocklist: set = set()
def is_safe(self, bid_request: dict) -> tuple[bool, str]:
"""
Check bid request for brand safety.
Returns: (is_safe, reason)
"""
site = bid_request.get('site', {})
app = bid_request.get('app', {})
# Check domain
domain = site.get('domain', '') or app.get('bundle', '')
if domain in self.domain_blocklist:
return False, f'blocked_domain:{domain}'
# Check IAB categories
content_cats = site.get('cat', []) + site.get('pagecat', [])
for cat in content_cats:
if cat in self.blocked_categories:
return False, f'blocked_category:{cat}'
# Check App Store rating (for mobile)
content_rating = app.get('content_rating', '')
if self.sensitivity == 'strict' and content_rating in ['ADULTS_ONLY', 'MATURE']:
return False, 'adult_app_rating'
return True, 'safe'
class DSPCampaignOrchestrator:
"""Orchestrate campaigns in DSP with AI optimization"""
def __init__(self):
self.budget_allocation = {}
def allocate_budget_across_campaigns(self, campaigns: list[dict],
total_daily_budget: float) -> dict:
"""
Distribute budget between campaigns based on predicted ROI.
campaigns: [{'id', 'predicted_roas', 'min_budget', 'max_budget'}]
"""
# Normalized ROAS weight
total_roas = sum(c['predicted_roas'] for c in campaigns)
allocations = {}
remaining = total_daily_budget
min_total = sum(c.get('min_budget', 0) for c in campaigns)
if min_total > total_daily_budget:
# Insufficient budget — distribute proportionally to minimums
scale = total_daily_budget / min_total
return {c['id']: c.get('min_budget', 0) * scale for c in campaigns}
# First ensure minimums
for c in campaigns:
allocations[c['id']] = c.get('min_budget', 0)
remaining -= allocations[c['id']]
# Remaining — ROAS-weighted distribution
for c in campaigns:
roas_weight = c['predicted_roas'] / total_roas
extra = remaining * roas_weight
max_allowed = c.get('max_budget', float('inf')) - allocations[c['id']]
allocations[c['id']] += min(extra, max_allowed)
return {k: round(v, 2) for k, v in allocations.items()}
def generate_performance_report(self, campaign_stats: pd.DataFrame) -> dict:
"""Summary report of DSP performance"""
total_spend = campaign_stats['spend_usd'].sum()
total_impressions = campaign_stats['impressions'].sum()
total_clicks = campaign_stats['clicks'].sum()
total_conversions = campaign_stats['conversions'].sum()
return {
'total_spend': round(float(total_spend), 2),
'total_impressions': int(total_impressions),
'overall_ctr': round(total_clicks / max(total_impressions, 1) * 100, 3),
'overall_cvr': round(total_conversions / max(total_clicks, 1) * 100, 2),
'overall_cpa': round(total_spend / max(total_conversions, 1), 2),
'overall_cpm': round(total_spend / max(total_impressions, 1) * 1000, 2),
'win_rate': round(
campaign_stats['wins'].sum() / max(campaign_stats['bids'].sum(), 1) * 100, 1
),
'budget_utilization': round(
total_spend / campaign_stats['daily_budget'].sum() * 100, 1
),
}
Example of lookalike operation
The expansion_rate parameter of 5% means we select 5% of users from the universe with the highest probability of belonging to the seed segment. In practice, this provides 2-3 times greater reach than standard DSP lookalikes, while maintaining comparable conversion rates.Optimization by Attribution Funnel
class MultiTouchAttributionOptimizer:
"""
Redistribute DSP budget based on multi-touch attribution.
Data-Driven Attribution (DDA) instead of last-click.
"""
def shapley_attribution(self, conversion_paths: list[list[str]],
conversions: list[int]) -> dict:
"""
Shapley value attribution: fair distribution of credit.
Each channel receives its contribution regardless of position in the path.
"""
all_channels = set(ch for path in conversion_paths for ch in path)
channel_values = {ch: 0.0 for ch in all_channels}
channel_counts = {ch: 0 for ch in all_channels}
for path, conv in zip(conversion_paths, conversions):
if not conv:
continue
for channel in set(path):
# Simplified Shapley: average value per occurrence
channel_values[channel] += conv / len(set(path))
channel_counts[channel] += 1
total = sum(channel_values.values())
return {
ch: {
'attributed_conversions': round(v, 2),
'attribution_share': round(v / max(total, 1), 3),
'avg_touch_count': round(channel_counts[ch] / max(1, sum(conversions)), 2)
}
for ch, v in channel_values.items()
}
Comparison of Attribution Approaches
| Method | When to Use | Accuracy | Inference Complexity |
|---|---|---|---|
| Last-click | Short funnels, direct response | Low | Zero |
| Linear | Even distribution of conversion credit | Medium | O(channels) |
| Time-decay | Strong dependence on last touch | Medium | O(channels) |
| Shapley Value | Fair evaluation, reporting | High | O(2^n) NP-hard |
| Data-Driven (markov) | Any funnels, big data | High | O(states) |
Typical KPIs for Managed DSP
| Parameter | Good Value | Problem Zone |
|---|---|---|
| Win Rate | 20-40% | < 10% or > 60% |
| Budget Pacing | 90-100% | < 80% or > 105% |
| Invalid Traffic | < 3% | > 8% |
| Brand Safety | > 97% | < 93% |
| Viewability | > 60% | < 40% |
| Frequency Cap Compliance | > 98% | < 95% |
Process of Work
- Analytics — audit of current DSP, data collection, KPI definition (CPA, ROAS, reach).
- Design — selection of ML models (LightGBM/CatBoost for scoring, transformers for NLP brand safety).
- Implementation — integration via RTB protocols (OpenRTB 2.x, per the OpenRTB specification), DSP API configuration (Google DV360, The Trade Desk, Xandr).
- Test — A/B test AI vs manual management on 10% of traffic for calibration.
- Deploy — roll-out to 100%, model drift monitoring, and retraining weekly.
- Monitoring — dashboard (Grafana + Prometheus) with alerts on win rate drops, IVT increases.
What's Included in the Work
- Integration of AI modules into your DSP (scoring, brand safety, budget pacing).
- Model training on your historical data (minimum 3 months of logs).
- Documentation: API, data model, instructions for updating segments.
- Team training: how to interpret reports and adjust rules.
- 3 months of support post-launch with monthly recalibration.
Timelines and Cost
Basic implementation — from 2 weeks. Full cycle with multi-touch and lookalike — up to 2 months. Cost is calculated individually based on traffic volume and integration complexity. We'll evaluate your project in 2 days — contact us for a consultation.
Typical Mistakes When Implementing AI in DSP
- Ignoring latency. If the model doesn't fit within 10 ms, you lose the auction. We use vLLM/Triton Inference Server with ONNX Runtime for optimization.
- Blind trust in third-party audiences. Check each provider's fraud score — up to 30% of data may be bot-generated.
- Skipping recalibration. Models drift over time — mandatory retraining every 7 days.
AI-powered DSP management is 2x more efficient than manual: 40-60% reduction in CPA while maintaining traffic volume. Full AI optimization with audience targeting, brand safety, and multi-touch attribution yields 30-50% efficiency gains for volumes exceeding 10 million impressions per month. Want the same result? Contact us to discuss your project details.







