Forecasting Engine
Beta Feature
The forecasting engine is currently in Beta status. The algorithm and implementation may need significant revision. Use forecasts as rough estimates rather than guarantees. Predictions may not accurately reflect actual inventory availability.
The ad server includes a forecasting engine that predicts how many ad impressions will be available for a potential campaign, helping advertisers plan budgets and publishers optimize inventory allocation. The system identifies conflicts between line items competing for the same traffic.
Key Features
- Opportunity-based analysis: Uses all ad requests (not just impressions) to show total inventory
- Conflict detection: Identifies competing line items with overlapping targeting
- Traffic patterns: Analyzes 30 days of historical data with day-of-week adjustments
- Targeting support: Geography, device types, registered dimensions, and custom key-values
API Endpoint
POST /forecast
Request a forecast for a potential line item configuration.
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
start_date | string | Yes | Campaign flight start date and time (ISO 8601 format) |
end_date | string | Yes | Campaign flight end date and time (ISO 8601 format) |
budget_type | string | Yes | Pricing model: cpm (cost per 1000 impressions), cpc (cost per click), or flat (fixed price) |
budget | float | Yes | Total budget amount in dollars |
publisher_id | int | Yes | Target publisher ID |
cpm | float | If CPM | Cost per thousand impressions (used for eCPM comparison) |
cpc | float | If CPC | Cost per click (converted to eCPM using estimated CTR) |
priority | int | No | Priority level (1=high, 2=medium, 3=low) |
countries | array | No | ISO country codes for geographic targeting (e.g., ["US", "CA"]) |
device_types | array | No | Device types: mobile, desktop, tablet |
key_values | object | No | Custom targeting key-value pairs |
daily_cap | int | No | Maximum impressions per day (prevents over-delivery) |
pacing | string | No | Delivery pacing strategy: ASAP (deliver as fast as possible) or Even (spread evenly across campaign flight) |
Example Request
{
"start_date": "2024-06-01T00:00:00Z", // Replace with your campaign start date
"end_date": "2024-06-08T00:00:00Z", // Replace with your campaign end date (7 days later)
"budget_type": "cpm",
"budget": 1000.0,
"cpm": 5.0,
"publisher_id": 1 // Example publisher ID - replace with your publisher ID
}
Response Fields
| Field | Type | Description |
|---|---|---|
| Summary Metrics | ||
total_opportunities | int | Total ad requests matching targeting |
available_impressions | int | Unfilled inventory available |
estimated_impressions | int | Projected impressions for this line item |
estimated_clicks | int | Projected clicks (CPM/CPC campaigns) |
estimated_spend | float | Projected spend |
fill_rate | float | Current fill rate for matching traffic |
estimated_ctr | float | Expected click-through rate |
| Arrays | ||
daily_forecast | array | Daily projections with date and metrics |
conflicts | array | Competing line items with overlap info |
warnings | array | Advisory messages about data quality |
Conflict Object Fields
| Field | Type | Description |
|---|---|---|
line_item_id | int | Competing line item ID |
line_item_name | string | Line item name |
priority | int | Priority level |
overlap_percentage | float | Targeting overlap (0.0 to 1.0) |
estimated_impact_impressions | int | Delivery impact |
conflict_type | string | higher_priority, same_priority, or lower_priority |
Data Requirements
ClickHouse Schema
The forecasting engine requires the enhanced events table with key-values:
ALTER TABLE events ADD COLUMN key_values Map(String, String);
Historical Data
- Minimum 7 days of ad request data recommended
- Key-values are captured only from ad_request events
- Impressions and clicks are joined via request_id
Implementation Details
Query Strategy
- Query 30 days of ad_request events with targeting filters
- Join with impression events to calculate fill rates
- Analyze existing line items for targeting overlap
- Apply pacing and budget constraints for projections
Queries use 15-minute time buckets and are limited to 10,000 patterns for performance.
Limitations
- Single publisher forecasts only
- Rule-based predictions (no ML)
- Basic day-of-week traffic adjustments
- No seasonality modeling
- No frequency cap simulation
Error Handling
| Status Code | Description | Common Causes |
|---|---|---|
| 200 | Successful forecast | - |
| 400 | Invalid request | Missing fields, invalid dates, unknown publisher |
| 500 | Server error | Database issues, insufficient data |
Testing
# Generate test data
docker compose exec openadserve go run ./tools/traffic_simulator
# Run unit tests
go test ./internal/forecasting/ -v
# Test API endpoint
curl -X POST http://localhost:8787/forecast \
-H "Content-Type: application/json" \
-d '{
"start_date": "2024-06-01T00:00:00Z",
"end_date": "2024-06-08T00:00:00Z",
"budget_type": "cpm",
"budget": 1000,
"cpm": 5,
"publisher_id": 1
}'
Related Topics
Core Concepts
- Ad Decisioning - The forecasting engine mirrors the same selection algorithm and conflict resolution logic
- Analytics - Historical impression and click data powers traffic pattern analysis
Integration
- API Reference - Complete documentation for the
/forecastendpoint - AdCP Integration - AI-powered inventory discovery using natural language queries
Campaign Setup
- Campaign Management - Use forecasting insights when planning campaign budgets and schedules
- Targeting - Forecasting accounts for all targeting criteria when predicting availability