To create ROI-Based Budget Rebalancing rules, it is important to understand each individual component. ROI stands for Return On Investment.
In this page, you learn about each component in the rebalance rule, and how each parameter affects the way the rule runs.
For rebalancing rules, it is recommended to use either a DAILY
or CUSTOM
schedule, as the action should not be frequently occurring.
The evaluation criteria works harmoniously with the rebalance_spec
to determine the lists of objects affected by rebalancing.
For all rebalance types, the list of objects that pass evaluation is the source of budgets. The list of recipients vary depending on the rebalance type specified, but for most of them (for example, EVEN
) the recipients are the objects that did not pass evaluation.
For example, if my EVEN
type rule criteria is cost_per_mobile_app_install
> 2.50
, this means that all ad sets that have a cost per mobile app install greater than 2.50 will be paused, and their budgets moved to all ad sets that have a cost per mobile app install less than or equal to 2.50.
The rebalance_spec
determines exactly how the recipients get their budget. There are five parameters:
Field | Description |
---|---|
| Required. Determines how the budgets are allocated. If the value is not Supported Values: |
| Optional. Specifies the Insights metric used to rank the recipients. This is required if Supported Values: An Insights field, such as |
| Optional. Specifies the number (K) of recipients. The combination of this, Supported Values: A positive integer, such as |
| Optional. Specifies whether or not you allow budgets to be allocated across ad campaigns. If this is not specified or Supported Values: A boolean value, such as |
| Optional. Specifies whether or not recipients should be ranked from high to low of the inverse of their Supported Values: A boolean value, such as |
There are some specific nuances regarding this action:
If the ad sets to be rebalanced contains both Daily and Lifetime budgets, we separate the ad sets into the two buckets. This means that ad sets only move their Daily budgets to other ad sets that have Daily budgets. The same happens with Lifetime budgets.
For ad sets with Lifetime budgets, we take their leftover budget - the difference between their Lifetime budget and Lifetime spend - when determining the amount of budget they can allocate. This ensures that the total budget on the ad campaign level is unchanged.
rebalance_spec
typesFor EVEN
and PROPORTIONAL
types, we pause the matched objects (the donors of the budget to the recipients). When we pause these objects, we do not adjust their budgets in any way, because:
This means that if you re-enable the ad set afterwards, it retains the same budget it had before. This can be seen when interacting with the paused object and fetching its budget data.
For NO_PAUSE_PROPORTIONAL
type, we do not pause the matched objects. We determine how much budget to adjust by looking at all the objects (donors and recipients) together and ranking their performance. This guarantees that budget is only moved from donors to recipients. This setup avoids a situation where rebalancing results in a well-performing ad set donating instead to an underperforming ad set simply due to how much budget it has. Please see the example below for more information.
For MATCHED_ONLY_PROPORTIONAL
type, we only look at the matched objects. Again, we do not pause them. We rank them among themselves and redistribute their budgets based on how they perform against each other. This means that we take the total budget from all the donors and proportionally share that with the same list of donors. Please see the example below for more information.
For types ending in PROPORTIONAL
, we distribute more budgets to ad sets that are performing better based on the target_field
defined. For example, if the metric is reach
and I have two recipient ad sets that have 10 and 20 reach
, we allocate 33.3% and 66.6% of the budget pool to these ad sets, respectively. If the type is EVEN
, they would each get 50%.
is_inverse
flagThe is_inverse
flag is useful for metrics such as cost_per_mobile_app_install
, where a lower metric number means a higher performing ad set. This is reemphasized in the example below, and means that ad sets with a lower such value get a higher portion of the budget allocation.
Here's an example of a rebalance rule that:
We define under-performing as stably having a high cost_per_mobile_app_install
. We proportionally allocate the budget from all under-performing ad sets to the best 10 ad sets in the ad account. This rule runs at 8AM every day, while looking at lifetime data.
curl \ -F 'name=Test Rebalance Rule' \ -F 'schedule_spec={ "schedule_type": "CUSTOM", "schedule": [ { "start_minute": 480 } ] }' \ -F 'evaluation_spec={ "evaluation_type": "SCHEDULE", "filters": [ { "field": "entity_type", "value": "ADSET", "operator": "EQUAL" }, { "field": "time_preset", "value": "LIFETIME", "operator": "EQUAL" }, { "field": "mobile_app_install", "value": 100, "operator": "GREATER_THAN" }, { "field": "cost_per_mobile_app_install", "value": 3.0, "operator": "GREATER_THAN" } ] }' \ -F 'execution_spec={ "execution_type": "REBALANCE_BUDGET", "execution_options": [ { "field": "rebalance_spec", "value": { "type": "INVERSE_PROPORTIONAL", "target_field": "cost_per_mobile_app_install", "target_count": 10, "is_cross_campaign": true }, "operator": "EQUAL" }, ] }' \ -F "access_token=<ACCESS_TOKEN>" \ https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library
Here, the rule:
curl \ -F 'name=Test Rebalance Rule' \ -F 'schedule_spec={ "schedule_type": "DAILY" }' \ -F 'evaluation_spec={ "evaluation_type": "SCHEDULE", "filters": [ { "field": "entity_type", "value": "ADSET", "operator": "EQUAL" }, { "field": "time_preset", "value": "LIFETIME", "operator": "EQUAL" }, { "field": "impressions", "value": 8000, "operator": "GREATER_THAN" }, { "field": "audience_reached_percentage", "value": 70, "operator": "GREATER_THAN" } ] }' \ -F 'execution_spec={ "execution_type": "REBALANCE_BUDGET", "execution_options": [ { "field": "rebalance_spec", "value": { "type": "EVEN" }, "operator": "EQUAL" }, ] }' \ -F "access_token=<ACCESS_TOKEN>" \ https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library
Here's an example leveraging the NO_PAUSE_PROPORTIONAL
type. In this case, the budget is reallocated from ad sets within ad campaigns from those with a low amount of video views. However, in this case ad sets are not paused, and are left with with a proportional amount of budget.
Here's a numeric example of what happens:
1-5
with video_view
of 1-5
, 3000
daily budget each, and the below rule. 6000
budget from ad sets 1
and 2
, and determine proportionally how to distribute that. In this case, each ad set has ratios of 1/15
up to 5/15
. 400
, 800
, 4200
, 4600
, and 5000
respectively. This guarantees that the recipients (ad sets 1
, 2
, and 3
) always increase their budget.curl \ -F 'name=Test Rebalance Rule' \ -F 'schedule_spec={ "schedule_type": "DAILY" }' \ -F 'evaluation_spec={ "evaluation_type": "SCHEDULE", "filters": [ { "field": "entity_type", "value": "ADSET", "operator": "EQUAL" }, { "field": "time_preset", "value": "LIFETIME", "operator": "EQUAL" }, { "field": "video_view", "value": 3, "operator": "LESS_THAN" }, ] }' \ -F 'execution_spec={ "execution_type": "REBALANCE_BUDGET", "execution_options": [ { "field": "rebalance_spec", "value": { "type": "NO_PAUSE_PROPORTIONAL", "target_field": "video_view" }, "operator": "EQUAL" }, ] }' \ -F "access_token=<ACCESS_TOKEN>" \ https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library
Finally, here's an example that leverages MATCHED_ONLY_PROPORTIONAL
. In this case, you don't need to worry about unmatched objects. The focus is on ad sets that satisfy the rule's filters. You can use the same example above, except now there is no need to determine the two lists based on how underperforming ad sets are.
With the same numeric example above, we would end up using all the budgets in the pool (15000
), and distributing it proportionally. As a result, ad sets 1-5
would end up with 1000-5000
budget.
The main downside to this type
is that there is no guarantee that better performing ad sets won't end up losing budget, especially in cases of unbalanced budget values. All else being the same, if ad set 5
had started with 18000
budget, it would end up losing 8000
of its budget.
curl \ -F 'name=Test Rebalance Rule' \ -F 'schedule_spec={ "schedule_type": "DAILY" }' \ -F 'evaluation_spec={ "evaluation_type": "SCHEDULE", "filters": [ { "field": "entity_type", "value": "ADSET", "operator": "EQUAL" }, { "field": "time_preset", "value": "LIFETIME", "operator": "EQUAL" }, ] }' \ -F 'execution_spec={ "execution_type": "REBALANCE_BUDGET", "execution_options": [ { "field": "rebalance_spec", "value": { "type": "MATCHED_ONLY_PROPORTIONAL", "target_field": "video_view" }, "operator": "EQUAL" }, ] }' \ -F "access_token=<ACCESS_TOKEN>" \ https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library