Bertrand duopoly equilibrium calculator
Two firms with a marginal cost of 20, facing demand that starts at a price of 100, both end up charging 20 and sell 40 units each with zero profit. Enter demand and the two costs to see prices, quantities and profits. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Demand intercept
- 100
- Demand slope
- 1
- Mc firm1
- 20
- Mc firm2
- 20
- Demand equation
- P=100-1Q
- Price firm1
- 20
- Price firm2
- 20
- Quantity firm1
- 40
The Bertrand model is the workhorse of simultaneous price competition: two firms sell a homogeneous good, post prices at the same moment, and the cheaper seller takes the entire market — they split demand only when the two prices match. With constant marginal cost and no capacity constraint, each firm wants to undercut a rival who is pricing above cost, so the unique Nash outcome drives both prices down to marginal cost. That is the Bertrand paradox: two sellers are enough for the competitive price. This Bertrand duopoly equilibrium calculator takes linear inverse demand P = a − bQ together with each firm's constant marginal cost and returns both posted prices, the quantities each firm sells, total output, and profits. When costs are equal the market splits at p = c with zero economic profit; when they differ the low-cost firm either posts its monopoly price or limit-prices at the rival's cost. Students, tutors, and industrial-organization notebooks get a deterministic key instead of a spreadsheet that mishandles the split-versus-winner branch.
What a homogeneous Bertrand equilibrium means
In the homogeneous-goods Bertrand duopoly, two firms choose prices simultaneously. Buyers treat the products as perfect substitutes, so they purchase only from the cheaper firm. If the posted prices are equal, the standard textbook convention is that the two firms split market demand in half.
Inverse demand is written P = a − bQ, where a is the choke price on the vertical axis and b is a positive slope, so quantity demanded at a posted price P is Q = (a − P) / b whenever P sits below a. Each firm has a constant marginal cost and no binding capacity, so the profit of a firm that wins the market at price p is (p − c) times residual demand.
The strategic logic is undercutting: if the rival posts a price above your cost, you can steal the whole market by posting a slightly lower price and still earn a positive margin. That incentive continues until neither firm can profitably go lower.
When the two costs are equal, the unique Nash equilibrium is both prices equal to that common cost, each firm serving half of residual demand, and both economic profits equal to zero — the famous result that price competition with homogeneous goods drives the market to marginal cost even with only two sellers.
When costs differ, the low-cost firm can still undercut; it either charges its unconstrained monopoly price if that price already sits at or below the rival's cost, or it limit-prices at the high-cost firm's cost and serves the entire market. This calculator implements that closed-form equilibrium, not a numerical best-response iteration and not a Cournot quantity game.
Inputs, closed-form branches, validation, and the response
Both marginal costs must be non-negative, and the choke price must strictly exceed the lower cost so that some units are demanded at cost. On the symmetric branch, when the two costs are equal to c, both firms post p = c, total quantity is (a − c) / b, each firm sells half of that total, and both profits are zero. On the asymmetric branch the low-cost firm's monopoly price is (a + c_L) / 2.
If that monopoly price is at most the rival's cost, the low-cost firm posts the monopoly price, the high-cost firm posts its own cost and sells nothing, and the winner earns the monopoly profit. If the monopoly price is above the rival's cost, the low-cost firm limit-prices at the high-cost firm's cost, takes the entire residual demand at that price, and earns (c_H − c_L) times that quantity. Numbers are rounded to twelve decimal places for stable goldens.
Where a Bertrand duopoly calculator earns its keep
Introductory industrial-organization and intermediate micro courses assign Bertrand drills because the paradox is the first sharp contrast with Cournot: the same two firms, the same linear demand, but prices rather than quantities as the strategic variable, and a completely different equilibrium price. Tutoring platforms and LMS auto-graders need a deterministic oracle that returns the split-at-cost outcome when costs match and the correct winner-takes-all outcome when they do not, instead of a student spreadsheet that always halves quantity.
Policy and strategy notebooks that compare Cournot and Bertrand on the same demand and cost numbers can pin the Bertrand side here and keep Cournot in a separate quantity solver. Pin the rounded prices and the regime string in tests, keep intercepts and costs finite, and you get reproducible Bertrand equilibria for homework, exam generators, and lightweight IO notebooks without standing up a numerical game solver.
What you can do with it
Homework and exam Bertrand checks
Students enter inverse-demand intercept and slope plus both marginal costs and verify that equal costs split the market at p = c with zero profit, matching the textbook paradox.
LMS and tutoring auto-grading
Score homogeneous Bertrand items with a deterministic oracle that rejects a non-positive slope and a choke price at or below cost instead of inventing a quantity.
Asymmetric-cost and limit-pricing notebooks
Compare unconstrained monopoly against limit pricing when one firm is cheaper, and pin winner, prices, and profits in industrial-organization problem banks.
FAQ
How do I find the Bertrand equilibrium of a homogeneous duopoly?
Inverse demand is P = a − bQ. When costs are equal the calculator returns p1 = p2 = c, each firm selling (a − c)/(2b) with zero profit.
Why are prices driven to marginal cost?
With identical products and no capacity limit, either firm can steal the whole market by undercutting any price above cost. The only mutual best response is both posting p = c, which is the Bertrand paradox.
What if the two firms have different marginal costs?
The low-cost firm serves the market at p = min((a + c_L)/2, c_H). If its monopoly price is already at or below the rival's cost it posts that monopoly price; otherwise it limit-prices at the rival's cost. The high-cost firm sells nothing.
How is this different from Cournot or from competitive market clearing?
Cournot firms choose quantities and typically earn positive markups; this page is price competition. Competitive supply-demand clearing is a different search and a different calculator. Use this tool only for the two-firm homogeneous Bertrand-Nash.
What happens when both firms have a marginal cost of 20?
With demand that starts at a price of 100 and falls by 1 per unit, both firms charge 20, each sells 40 units, total output is 80 and both profits are zero, because neither can gain by undercutting further.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/econ/bertrand-duopoly-equilibrium \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"demand_intercept":100,"demand_slope":1,"mc_firm1":20,"mc_firm2":20}'const res = await fetch("https://api.kit.forhosting.com/econ/bertrand-duopoly-equilibrium", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"demand_intercept": 100,
"demand_slope": 1,
"mc_firm1": 20,
"mc_firm2": 20
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/econ/bertrand-duopoly-equilibrium",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"demand_intercept": 100,
"demand_slope": 1,
"mc_firm1": 20,
"mc_firm2": 20
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/econ/bertrand-duopoly-equilibrium", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"demand_intercept":100,"demand_slope":1,"mc_firm1":20,"mc_firm2":20}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"demand_intercept":100,"demand_slope":1,"mc_firm1":20,"mc_firm2":20}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/econ/bertrand-duopoly-equilibrium", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"demand_intercept": 100,
"demand_slope": 1,
"mc_firm1": 20,
"mc_firm2": 20
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "econ.bertrand_duopoly_equilibrium",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Inputs, closed-form branches, validation, and the response
POST a JSON body with four required finite numbers. demand_intercept is the choke price a in P = a − bQ. demand_slope is the positive coefficient b of quantity. mc_firm1 and mc_firm2 are the constant marginal costs of the two firms. Aliases a or intercept, b or slope, c1 or mc1, and c2 or mc2 are accepted so a homework sheet can be pasted without renaming columns. Missing, empty, or non-finite values fail with invalid_input naming the field. demand_slope must be strictly positive — a flat or upward inverse demand is not the linear market this model assumes. Successful parse calls use the published $0.002 base price per item; validation failures are not billed.
Where a Bertrand duopoly calculator earns its keep
Instructors building problem banks want the same closed-form prices, quantities, and profits that students derive on paper for P = 100 − Q with c = 20, or for an asymmetric pair that triggers limit pricing.
Technical questions
What does the Bertrand duopoly equilibrium calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.