# Marginal advertising budget comparison — Lonta AI, 2026-10-29

Read the article: https://lonta.io/blog/marginal-google-ads-budget/

Use office-worksheet.txt first. Every business input in sample.json and downside.json is invented. The code enumerates supplied discrete options, not estimated auction response curves. It does not forecast your account, establish causal lift, connect to providers or change budgets.

## Run locally

Extract the entire ZIP. With Node.js 20 or later:

    node core.mjs
    node core.mjs downside.json
    node core.mjs your-scenario.json
    node --test core.test.mjs

No dependencies or network requests. Keep real account data private.

## Schema and units

One JSON object:

- mediaBudgetCents: upper bound on added media in integer USD cents. This is a ceiling, not a requirement to spend. Added fees are outside this media ceiling, but subtracted from remaining contribution.
- availableMinutes: nonnegative integer crew minutes genuinely available for extra completed work in the same period, AFTER other commitments, travel, unsuccessful visits and operating reserve. A single common pool is assumed.
- addedFeeCents: nonnegative integer USD cents charged once if a plan spends any added media. The no-increase plan pays no added fee. All options are assumed to face the same fee; varying campaign/level fees require another model.
- campaigns: one to five campaigns, each with unique alphanumeric/underscore/hyphen id (1-40 characters), contributionPerJobCents and one to six levels.
- contributionPerJobCents: same defined contribution basis for every added completed job in this campaign, before acquisition, fixed overhead and tax. Distinguish extra delivery cash from already committed payroll. The program cannot infer accounting treatment.
- levels: each has spendCents, jobs and minutes, all nonnegative integers. jobs means added completed jobs ASSUMED at that level; minutes means crew time RESERVED for that option. Each campaign must include exactly one zero-cost, zero-job, zero-minute level. Spend levels must be unique.

Levels in one campaign are mutually exclusive TOTAL increases above a shared unchanged baseline. The $1000 level replaces the $500 level; it is not another $1000 on top. The code chooses exactly one level per campaign. It does not interpolate. Between campaigns, outcomes and costs are assumed additive and independent; overlap or cannibalization can invalidate that assumption.

All quantities and intermediate totals must remain safe integers. Invalid inputs reject the batch with a nonzero exit.

## Output and objective

All combinations appear in plans, with feasibility against media and minutes. best maximizes contributionCents - spendCents - feeCents among feasible combinations. The no-increase combination is always available. Equal-surplus plans prefer lower media spend, then lower minutes, then deterministic JSON ordering.

This remainder is contribution for other business needs, not company net profit or cash flow. Choosing the maximum here is conditional on the supplied assumptions and options. There may be better real options not supplied.

## Literal sample results

3 choices x 3 campaigns = 27 combinations.
$1000 media ceiling, 600 crew minutes, no added fee: drain +$1000; 5 jobs; 600 minutes; $2000 contribution before acquisition - $1000 media = $1000 remainder.
840 crew minutes: drain +$500 and panel +$500; 4 jobs; 840 minutes; $2400 contribution - $1000 media = $1400 remainder.
600 minutes with $200 fee: base remainder $800.
Downside: same reserved minutes, fewer assumed completions. Best drain +$1000; 3 jobs x $400 - $1000 = $200. These are scenario assumptions, not statistical confidence bounds.

## Files and rights

core.mjs and core.test.mjs: original code/tests, MIT.
sample.json, downside.json, expected-summary.json and office-worksheet.txt: original synthetic fixtures and worksheet, CC BY 4.0.
LICENSE.txt gives the licenses and attribution. The article links platform documentation; third-party documentation is not redistributed.
