Logistic growth calculator
See where a bounded population will stand: 50 individuals growing at 0.4 per year toward a carrying capacity of 1000 reach about three quarters of that ceiling after 10 years. You also get the headroom left and the growth at that moment. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Initial size
- 50
- Growth rate
- 0.4
- Carrying capacity
- 1,000
- Elapsed time
- 10
- Population
- 741.8413371607
- Fraction of capacity
- 0.7418413372
- Remaining capacity
- 258.1586628393
- Growth
- 76.6051070561
Logistic growth is the standard bounded-population model in ecology, wildlife management, and introductory mathematical biology: a census rises almost exponentially while it remains small relative to its environment, then decelerates as it approaches a finite carrying capacity. This population logistic growth calculator evaluates the closed-form Verhulst solution for N at time t from four finite numbers — the initial size N-zero, the intrinsic growth rate r, the carrying capacity K, and the elapsed time t, with r and t sharing one unit. You receive the predicted population, the fraction of carrying capacity occupied, the remaining headroom to K, and the instantaneous growth rate r times N times one minus N over K at that instant. The model is classic single-species logistic; it does not add an Allee threshold, harvest, age structure, or stochastic extinction, and it is not an unconstrained doubling law.
What logistic (Verhulst) growth means
The logistic, or Verhulst, equation is the simplest model in which per-capita growth declines linearly as density approaches a carrying capacity. In differential form, dN over dt equals r times N times one minus N over K. When N is much smaller than K the factor one minus N over K is nearly one, so the trajectory looks exponential with rate r.
As N approaches K that factor shrinks, net growth falls, and the population levels off. If the starting census already sits above K — a pulse of immigrants, a stocking overshoot, or a census taken after a temporary boom — growth is negative and the trajectory relaxes back down toward K. The closed form used here is N of t equals N-zero times K, divided by N-zero plus K minus N-zero times e to the minus r t.
Time zero returns the starting size. A zero growth rate also leaves the census unchanged. A negative r is mathematically legal and drives the population toward zero rather than toward K, which is useful when you want a decaying logistic rather than a rising one.
The inflection of the rising S-curve sits at K over two: that is where instantaneous growth is largest for r greater than zero and N-zero between zero and K. Search intent for this landing is logistic growth calculator, population logistic growth, carrying-capacity Verhulst N of t, and bounded population from N-zero, r, K, and t.
Use it when you already know those four numbers and want the closed-form census, not a fitted curve, not an unconstrained doubling N equals N-zero times two to the t over g, and not an Allee cubic that only reports the sign of growth at one instant.
Field workflows, limits, and related search intent
Teaching labs fix a small N-zero under a large K so students see the early near-exponential rise, then raise N-zero above K so they see the same formula produce a decline instead of a crash to zero. Wildlife and fisheries notes use the ceiling to ask whether a stock will theoretically sit near K after a stated interval, remembering that harvest, seasonality, and Allee effects are out of scope.
Method developers compare the closed-form logistic against plate counts or census points to see when a culture or a herd left the unbounded exponential sketch. Limits: this tool does not invert a later census to solve for r or t, does not fit K from a time series, does not apply a critical Allee threshold, and does not convert optical density to individuals. Search intent includes logistic growth calculator, population logistic growth calculator, carrying capacity Verhulst, bounded population N of t, and logistic versus exponential growth.
What you can do with it
Classroom sigmoid and carrying-capacity homework
Let students submit N0, r, K, and t and verify the closed-form census, the fraction of K occupied, and the sign of instantaneous growth against textbook Verhulst problems.
Wildlife and fisheries planning horizons
Project a stock or wildlife census toward a published carrying capacity after a stated interval so a memo can quote a deterministic N(t) before anyone opens a simulator.
Checking when a culture left unbounded exponential growth
Compare an observed count against the logistic N(t) and against unconstrained doubling to see how far a flask or a herd has felt the ceiling K.
FAQ
What happens if the initial size is already above carrying capacity?
When r is positive the trajectory declines toward K.
How is this different from exponential bacterial growth?
Exponential doubling N = N0 × 2^(t/g) has no ceiling. Logistic growth slows as N approaches K and can decline when N0 > K.
Where does a logistic population grow fastest?
At half the carrying capacity. With a positive rate and a start between zero and the ceiling, the S-curve has its inflection at K divided by two, where growth is largest before it slows toward the limit.
Do the growth rate and the time need the same unit?
Yes. The rate is per unit of time, so a rate per year goes with time in years and a rate per day with days. The calculator never converts calendars, so mixed units give a wrong curve.
What does a negative growth rate do in the logistic model?
It pulls the population toward zero instead of toward the carrying capacity. That is useful when you want a declining logistic curve, such as a population under pressure, rather than one rising to its ceiling.
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/bio/population-logistic-growth \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"initial_size":50,"growth_rate":0.4,"carrying_capacity":1000,"elapsed_time":10}'const res = await fetch("https://api.kit.forhosting.com/bio/population-logistic-growth", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"initial_size": 50,
"growth_rate": 0.4,
"carrying_capacity": 1000,
"elapsed_time": 10
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/bio/population-logistic-growth",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"initial_size": 50,
"growth_rate": 0.4,
"carrying_capacity": 1000,
"elapsed_time": 10
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/bio/population-logistic-growth", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"initial_size":50,"growth_rate":0.4,"carrying_capacity":1000,"elapsed_time":10}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"initial_size":50,"growth_rate":0.4,"carrying_capacity":1000,"elapsed_time":10}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/bio/population-logistic-growth", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"initial_size": 50,
"growth_rate": 0.4,
"carrying_capacity": 1000,
"elapsed_time": 10
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "bio.population_logistic_growth",
"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
Invalid inputs fail with invalid_input and are not billed.
Input contract, response fields, and validation
The growth rate is one over time, so r and t must share a unit — per year with years, per day with days — and the calculator never converts calendars. A start above K with positive r returns a population that has declined toward K, a fraction above one, negative remaining headroom, and negative growth. Zero elapsed time is legal and returns the starting census with growth evaluated at t equals zero — a useful notebook check that the calculator is not inventing change. POST a JSON body with four required finite numbers: initial_size as a positive starting census (aliases n0, N0, initial, initial_population, n_zero, population_initial), growth_rate as a finite intrinsic rate r (aliases r, rate, intrinsic_rate), carrying_capacity as a positive K in the same unit as the census (aliases k, K, capacity, carrying), and elapsed_time as a non-negative interval (aliases t, time, duration). Example: initial_size fifty, growth_rate zero point four, carrying_capacity one thousand, elapsed_time ten returns a population on the rising limb of the sigmoid, a fraction of capacity below one, positive remaining headroom, and positive instantaneous growth. On success the response echoes the four inputs with stable twelve-decimal rounding, plus population as the primary N of t, fraction_of_capacity as N over K, remaining_capacity as K minus N, growth as r N times one minus N over K at that instant, formula restating the closed form, and a short English message. Missing fields, non-finite strings, boolean types, non-positive initial_size, non-positive carrying_capacity, and negative elapsed_time fail with invalid_input naming the field and are not billed. Successful work is priced at a flat $0.002 with unit item.
Field workflows, limits, and related search intent
Typical workflow: take a published or measured N-zero, an intrinsic rate in reciprocal time, and a carrying capacity from habitat models or a tank volume, set elapsed_time to the planning horizon, and log population next to the protocol. Failed validation does not consume prepaid balance. Round-trip checks are straightforward: recompute N-zero times K over N-zero plus K minus N-zero times e to the minus r t and confirm equality with population within published rounding, then confirm that a missing initial_size flips the response from success to invalid_input with a clear field message. Each successful API call is billed at $0.002.
Technical questions
How do I calculate population size under logistic growth?
Send positive initial_size (N0), finite growth_rate (r), positive carrying_capacity (K), and non-negative elapsed_time (t) in matching units. The API returns population = (N0·K) / (N0 + (K−N0)·exp(−r·t)).
Do growth_rate and elapsed_time need matching units?
Yes. Use per-year with years or per-day with days. The calculator does not convert units; the product r·t must be dimensionless.
What does the population logistic growth calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.