Core Concepts
Understanding these fundamental concepts will help you work effectively with OpenAdServe and make sense of ad serving technology.
This page explains the essential building blocks. For a complete reference of all terminology, see the Glossary.
Campaign Hierarchy
OpenAdServe organizes ad serving into a clear hierarchy. Understanding this structure is essential:
Publishers
The top-level entity representing your website or application.
What they define:
- Authentication credentials (API keys)
- Default settings and configurations
- Multi-tenancy boundaries
Example: Your news website is a single publisher
Learn more about multi-tenancy →
Placements
Specific ad slots on your pages where ads can appear.
What they define:
- Ad unit location (header, sidebar, in-content)
- Supported creative sizes (300x250, 728x90, etc.)
- Allowed formats (banner, native, HTML)
Example placements:
- "Homepage Header Banner" (728x90)
- "Article Sidebar" (300x250)
- "In-Feed Native" (native format)
Why it matters: Ad requests specify a placement, and only line items targeting that placement can compete.
Campaigns
Groups of related line items working toward a common goal.
What they organize:
- Multiple line items with shared objectives
- Budget tracking across line items
- Reporting and analytics aggregation
Example: "Q1 2024 Brand Campaign" containing:
- Desktop line item (CPM: $5.00)
- Mobile line item (CPM: $4.00)
- Retargeting line item (CPM: $8.00)
Why campaigns matter: They provide organizational structure and consolidated reporting.
Line Items
The core configuration unit that defines how and when ads serve.
What they specify:
- Budget: CPM, CPC, or no budget (remnant)
- Targeting: Who sees the ad (device, location, custom attributes)
- Pacing: How fast to spend the budget (ASAP, Even, PID)
- Schedule: Start and end dates (flight dates)
- Frequency: How often users see the ad
- Priority: Ranking tier (1-10, where 1 is highest)
Example line item:
{
"name": "Mobile Sports Readers",
"budget_type": "CPM",
"cpm_bid": 6.50,
"priority": 3,
"targeting": {
"device_type": ["mobile"],
"content_category": ["sports"]
},
"pacing_mode": "even",
"frequency_cap": {
"max_impressions": 3,
"time_window": "24h"
}
}
Why line items matter: This is where ad serving decisions happen. Every ad request evaluates line items to find the winner.
Creatives
The actual ad content shown to users.
Supported formats:
- HTML: Custom HTML/CSS/JS for rich interactive ads
- Banner: Image-based ads with automatic responsive sizing
- Native: Structured elements (title, image, description) rendered by publisher
What they contain:
- Ad markup or image URLs
- Click-through URLs with macro expansion
- Optional JavaScript for tracking
Example banner creative:
{
"type": "banner",
"image_url": "https://cdn.example.com/ad.jpg",
"click_url": "https://advertiser.com/landing?campaign={{CAMPAIGN_ID}}",
"alt_text": "Buy Now - Limited Time Offer"
}
Budget Types & Competition
Line items compete for impressions based on their eCPM (effective cost per mille). Understanding how different budget types convert to eCPM is crucial.
CPM (Cost Per Mille)
Pay per 1,000 impressions delivered.
- Bid: The CPM value (e.g., $5.00 CPM)
- eCPM: Same as the bid ($5.00)
- Billing: Charged for every 1,000 impressions
Use case: Brand awareness campaigns prioritizing reach over clicks.
Example: $5.00 CPM bid = $5.00 eCPM = charges $5 per 1,000 impressions
CPC (Cost Per Click)
Pay per click received.
- Bid: The CPC value (e.g., $0.50 per click)
- eCPM:
CPC × Predicted CTR × 1,000 - Billing: Charged only when users click
Use case: Performance campaigns prioritizing user actions over impressions.
Example: $0.50 CPC bid with 2% predicted CTR = $10.00 eCPM
OpenAdServe can optionally use ML-based CTR prediction to estimate click-through rates for CPC campaigns. This allows fair competition with CPM campaigns.
No Budget (Remnant)
Serve for free when no paid campaigns match.
- Bid: No monetary bid
- eCPM: Based on priority (lower priority = lower eCPM)
- Billing: No charge
Use case: House ads, PSAs, backfill for unsold inventory.
Example: Priority 8 remnant ad fills empty slots when no paid campaigns qualify.
eCPM Normalization
eCPM (effective Cost Per Mille) normalizes all budget types to a common metric for fair competition.
How it works:
- CPM campaigns: eCPM = CPM bid
- CPC campaigns: eCPM = CPC bid × Predicted CTR × 1,000
- No budget: eCPM = priority-based value
Competition example:
| Line Item | Budget Type | Bid | CTR | eCPM | Winner? |
|---|---|---|---|---|---|
| Brand Campaign | CPM | $8.00 | N/A | $8.00 | ✅ Winner |
| Performance Ad | CPC | $0.50 | 1% | $5.00 | - |
| House Ad | None | N/A | N/A | $1.00 | - |
Within the same priority tier, highest eCPM wins.
Learn more about ad decisioning →
Targeting
Control which requests match each line item through targeting rules.
Device Targeting
Automatically detected from User-Agent headers.
Available options:
- Device Type: Desktop, mobile, tablet
- Operating System: iOS, Android, Windows, macOS, Linux
- Browser: Chrome, Safari, Firefox, Edge, etc.
Example: Target only mobile iOS users:
{
"device_type": ["mobile"],
"operating_system": ["iOS"]
}
Geographic Targeting
Automatically detected via GeoIP lookup using MaxMind GeoLite2.
Available options:
- Country: Two-letter country codes (US, GB, CA, etc.)
- Region: State/province within countries
Example: Target users in California:
{
"country": ["US"],
"region": ["CA"]
}
GeoIP databases provide ~95% country-level accuracy but are less precise for city-level targeting. Results may vary by user location.
Registered Dimensions
Type-validated custom dimensions with analytics indexing.
Benefits:
- Type Safety: Enum constraints, number ranges, required fields
- Performance: Indexed ClickHouse columns for fast analytics
- Analytics: Automatic aggregation in reports
Example configuration (dimensions.yaml):
dimensions:
- name: content_category
type: enum
values: [sports, news, tech, entertainment]
indexed: true
- name: user_engagement_score
type: number
min: 0
max: 100
indexed: true
Usage in ad request:
{
"ext": {
"kv": {
"content_category": "sports",
"user_engagement_score": 85
}
}
}
Learn more about dimension registration →
Custom Key-Values
Flexible targeting for any custom attributes not registered as dimensions.
Use cases:
- A/B test variants
- Content tags
- User segments
- Experiment groups
Example: Target specific article sections:
{
"ext": {
"kv": {
"section": "technology",
"article_type": "review",
"sponsored": "false"
}
}
}
Flexibility: No pre-configuration required - send any key-value pairs and target them in line items.
Pacing
Distribute impressions evenly over time to avoid spending budgets too quickly.
Why Pacing Matters
Without pacing, high-priority campaigns exhaust budgets immediately, leaving nothing for later traffic:
With pacing: Budget distributes across the entire flight, maximizing reach and preventing early exhaustion.
ASAP Pacing
Serve as fast as possible until budget exhausted.
Behavior:
- No throttling or rate limiting
- Competes at full eCPM immediately
- Budget depletes when traffic arrives
Use case: Time-sensitive campaigns, flash sales, limited inventory opportunities.
Example: Black Friday sale that needs maximum exposure in first few hours.
Even Pacing
Target uniform distribution across the flight.
Behavior:
- Calculates target delivery rate based on flight duration
- Throttles when ahead of schedule
- Catches up when behind schedule
Formula:
Target Rate = Total Budget / Flight Duration (hours)
Current Rate = Budget Spent / Hours Elapsed
If Current Rate > Target Rate → Throttle
If Current Rate < Target Rate → Serve more aggressively
Use case: Standard campaigns wanting consistent delivery throughout the flight.
Example: Month-long campaign with $10,000 budget delivers ~$333/day.
PID Controller Pacing
Advanced algorithm that adapts to traffic patterns.
Behavior:
- Uses Proportional-Integral-Derivative control theory
- Learns from traffic patterns and adjusts dynamically
- Handles variable traffic better than simple even pacing
How it works:
- Proportional: Corrects based on current error
- Integral: Corrects based on accumulated error
- Derivative: Anticipates future error
Use case: Campaigns with unpredictable or variable traffic patterns.
Example: News site with traffic spikes during breaking news events - PID adapts automatically.
Learn more about pacing algorithms →
Frequency Capping
Limit how often individual users see the same ad to prevent overexposure and ad fatigue.
How It Works
Tracking:
- Uses cookies or device IDs to identify users
- Stores impression counts in Redis with TTL
- Checks count before serving each impression
Configuration:
{
"frequency_cap": {
"max_impressions": 3,
"time_window": "24h"
}
}
Example: User sees ad 3 times maximum within any 24-hour period.
Time Windows
Supported intervals:
1h- 1 hour24h- 24 hours (1 day)168h- 168 hours (1 week)- Custom: Any hour value
Behavior:
- Counter increments on each impression
- Redis TTL automatically expires old data
- Fresh window starts after expiration
Privacy Considerations
User identification:
- First-party cookies (set by publisher domain)
- Optional device IDs for mobile apps
- No third-party tracking or cross-domain cookies
Data retention:
- Automatic TTL expiration matches time window
- No long-term storage of user data
- Counts cleared immediately after window expires
Priority System
Line items compete in priority tiers (1-10, where 1 is highest).
How Priority Works
Two-stage ranking:
- First: Group by priority (1 is highest)
- Second: Within priority, rank by eCPM (highest wins)
Example competition:
| Line Item | Priority | eCPM | Winner? |
|---|---|---|---|
| Sponsorship | 1 | $3.00 | ✅ Winner (highest priority) |
| Performance | 3 | $12.00 | - (lower priority, despite higher eCPM) |
| Backfill | 8 | $5.00 | - |
Priority 1 always wins, regardless of eCPM, as long as it passes all filters.
When to Use Different Priorities
Priority 1-2: Guaranteed campaigns
- Sold sponsorships with guaranteed delivery
- Direct deals with rate card pricing
- Must deliver contracts
Priority 3-5: Standard campaigns
- Most CPM and CPC campaigns
- Compete on eCPM within tier
- Balanced performance and revenue
Priority 6-7: Remnant and backfill
- House ads
- Network backfill (e.g., Prebid)
- Lower-value inventory
Priority 8-10: Last resort
- PSAs (Public Service Announcements)
- Empty placeholder ads
- Better than blank space
Rate Limiting
Protect line items from traffic spikes and abuse using token bucket algorithm.
Token Bucket Algorithm
How it works:
Configuration:
{
"rate_limit": {
"qps": 100,
"burst": 200
}
}
- QPS: Queries per second (sustained rate)
- Burst: Maximum bucket capacity (handles short spikes)
Example: 100 QPS limit with 200 burst capacity
- Serves 100 requests/second continuously
- Can handle 200 requests instantly for spikes
- Refills at 100 tokens/second
Why Rate Limiting Matters
Prevents:
- Budget exhaustion from bot traffic
- Unusual traffic spikes depleting budgets
- Single-source traffic dominating delivery
Use cases:
- Protect high-value CPM campaigns
- Limit exposure during traffic anomalies
- Control costs for CPC campaigns
Learn more about rate limiting →
Next Steps
Now that you understand the core concepts:
For Learners:
- Systems Architecture - See how components fit together
- Ad Decisioning - Understand the selection algorithm
- Pacing System - Deep dive into pacing algorithms
For Integrators:
- API Reference - Request/response formats
- Trafficking Guide - Create campaigns and line items
- Integration Guide - SDK and server-to-server setup
For Developers:
- Development Guide - Local setup and testing
- Data Stores - Storage architecture
- Dimension Registration - Custom targeting dimensions