Blog/ Amazon Advertising/ Automated bids

Bids that correct themselves

Automated bids on DAX measures over time frames

A manager edits bids by hand once a day — and still lags the market. We made it so the bid computes itself from a clear rule, and the human only sets the goal.

The target bid per SKU is a DAX measure inside a time frame: take the ACoS target, actual CTR/CR and margin, compute the safe ceiling. A Go service pulls the result every few minutes and pushes thousands of bids through the API.

MA Mikhail Abovyan·founder, ACS ·May 2026 ·10 min
Automated bids ACoS / ROAS time frames DAX Go + API Amazon Ads
Driver's seat Plain language: what hurts, what changes and what you get. The target-bid calculator below is live — drag the ACoS goal. No formulas — switch to "Under the hood" if you want the engineering.
Under the hood The engineering: DAX measures, time frames, the bid-delivery scheme over the API. For analysts and people who like formulas.
bids inside ACoS band 88% was 32% by hand
manual edits / day ~0 was 2–3 hours
market reaction 15 min was "once a day"
SKUs under autobid 3,400+ one run

01 Why manual bidding always lags

Advertising on a marketplace lives by the hour: in the morning the bid is fine, by midday competitors have raised the cost per click, and you either overpay or sink in the ranking. The manager opens the console, scans dozens of campaigns, edits bids by hand — and still reacts half a day late. And there are thousands of SKUs.

The main trouble isn't even speed, it's the logic. "Bump it $0.10 where it's bad" isn't a strategy. It's unclear how much you can pay per click for the ad to still be in the black given the margin of that specific product.

"Not 'raise it where it's bad', but 'pay per click exactly what the product can afford'."

02 The idea: the target bid is a measure, not a button

We flip the task. Instead of "what bid do I set?", you answer one clear question: how much you're willing to spend on ads per $100 of revenue for this product (that's ACoS — advertising cost of sales). Then the math turns the goal into a cost per click.

The logic is simple: if out of 100 clicks three buy on average, and the average order value is known — then it's clear how much revenue one click brings. Multiply by the target ACoS — and you get how much that click is worth paying for. Drag the ACoS goal and watch the target bids recompute:

Target bid by SKU and time frame
target bid = revenue per click × ACoS goal · synthetic data
18%
SKUTime frameCRAOVRev / clickTarget bid

* below ~30 clicks in a frame the measure stays silent — too little data to trust the funnel. Such rows are dimmed.

03 Time frames: the key trick

The same product sells differently in the morning, midday and on weekends. So we don't compute one "average" bid but a separate one for each characteristic stretch of time — a "frame". The system knows this SKU converts better on Sunday evening, and calmly raises the ceiling exactly then.

Frame A
weekday · day
CR 2.8% · bid ↓
Frame B
weekday · evening
CR 3.6% · bid ↑
Frame C
weekend
CR 4.1% · bid ↑↑
Frame D
night
CR 1.2% · bid ↓↓

CR and buyout are computed inside the frame, so the bid adapts to the daily and weekly rhythm of demand instead of being smoothed into an average. The table above already uses these per-frame conversion rates.

04 How bids reach the console

Computing the bid isn't enough — it has to be set in the console, and not one but thousands. A small service does that: every 15 minutes it takes the fresh target bids from the model and carefully sends them to the Amazon Advertising console through its official interface. The human only watches the goal.

Want the engineering? Switch to "Under the hood" at the top right — there's the DAX measure for the per-frame bid, the protection against small-data noise, and the Go delivery service with diff and rate limits.

01 Why manual bidding breaks

Manual bidding breaks on two things: frequency and the unit of decision. A person edits bids "once a day", while the auction shifts over hours. And the decision is made "by eye, per campaign", whereas the economically correct unit is the tuple SKU × placement × time frame, each with its own bid ceiling.

So you don't need "one more export" but a measure that, for each such tuple, computes the maximum allowable bid from the target ACoS and the actual funnel — and recomputes as often as we can deliver the result to the console.

02 The target bid from the funnel

The target bid is derived from the funnel. Expected revenue per click is the conversion to order times the average order value (adjusted for buyout). Multiply by the target ACoS — and you get the cost-per-click ceiling:

Bidtarget = CR × AOV × Buyout × ACoStarget
CR — click→order conversion · AOV — average order value · Buyout — buyout share · ACoS — target cost share

All four factors are measures that already live in the model for reporting. Autobid doesn't add a new source of truth — it reuses the same one as the operating-summary dashboards. So the bid and the report never diverge.

Why it's safe. The bid is a ceiling, not a fixed price. We don't guarantee spend, we cap the maximum at which the unit economics still works. It can't get worse than the target ACoS by construction.

03 Time frames in DAX

A frame is a funnel-aggregation window: e.g. day-of-week × hour-bucket, or rolling 7/14/28 days for smoothing. In DAX it's a measure that respects the current frame context. A simplified skeleton:

// Target bid in the current frame context (SKU × placement × window)
Target Bid =
VAR _cr   = DIVIDE( [Frame orders], [Frame clicks] )
VAR _aov  = DIVIDE( [Frame revenue], [Frame orders] )
VAR _buy  = [Frame buyout share]            // 0..1
VAR _acos = [ACoS Target]                    // set by the product owner
VAR _raw  = _cr * _aov * _buy * _acos
// protection against small-data spikes
VAR _safe = MINX( { _raw, [Bid Ceiling], [Prev bid × 1.5] }, [Value] )
RETURN
    IF( [Frame clicks] >= 30, ROUND( _safe, 2 ), BLANK() )
Small data is the main enemy. If a frame has 4 clicks, a "25%" conversion is noise. So the measure withholds a bid until clicks exceed a threshold, and caps the growth step (×1.5 over the previous). Better to stay silent than burn budget on a random number.

04 How bids reach the console

The model is the source of truth, delivery is a separate layer. The calculation is exported (a table SKU · placement · frame · bid), and a Go service diffs it against the current console state and sends only the changes, in batches, respecting API limits:

DAX modelbid per frame
Exportparquet / API
Go servicediff + rate-limit
Ads APIAmazon Advertising

Go wasn't chosen for fashion: thousands of requests with retries, backoff and strict rate-limit compliance is about concurrency, where Go is strong. Each run is idempotent: it fails mid-way — a re-run finishes the rest without double-setting bids.

05 What it gave

The manager stopped living in the ad console. Instead of two or three hours of manual edits a day, they set an ACoS goal and watch the result. Advertising reacts to the market in 15 minutes, not "when there's time", and stays within the economics of each product.

MetricBefore (manual)After
Bids in the target ACoS band32%88%
Time on bidding2–3 h/day~0
Reaction period~1 day15 min
SKU coveragetop, by hand3,400+ auto
An honest note. Autobids aren't a "magic profit button". They're discipline: advertising stops stepping outside the economics and runs evenly, with no dips or overpaying. Sales growth comes from a good product — the math just stops getting in its way.

Let's compute the target bid on your data

In a free review we'll show what ACoS your SKUs hold right now and how much you overpay per click because of manual bidding. No obligation.

more on the topic  ·  All blog articles →
reading mode