Fence post calculator
A 100-foot run with posts every 8 feet needs 13 sections, 14 posts and 26 rails at 2 rails per section, because neighbouring sections share a post. Spacing is measured centre to centre. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Total fence run length
- 100
- Spacing
- 8
- Rails per section
- 2
- Sections
- 13
- Posts
- 14
- Rails
- 26
A fence post calculator turns a run length and a centre-to-centre post spacing into the integer counts you need before you order timber or steel.
How fence posts and rails are counted from length and spacing
A straight fence run of positive length is divided into bays whose target width is the post spacing measured centre to centre. The number of sections (bays) is the ceiling of length divided by spacing, so a run that is not an exact multiple of the spacing still gets enough bays to cover the full length. Posts equal sections plus one because every bay has two ends and adjacent bays share a post: a single bay needs two posts, two bays need three posts, and so on.
Length and spacing must use the same length unit—metres with metres, feet with feet—because the calculator never converts units and only needs the dimensionless ratio. Length must also be positive; a zero-length run is not a fence. The response does not add waste boards, gate openings, or corner posts beyond the two ends of this single straight run—model gates and corners as separate calls or adjust counts after the geometric take-off.
Practical tips, limits, and related searches
Measure the clear run along the fence line and choose a spacing that matches your panel product or structural guidance—eight feet and two and a half metres are common targets, but the tool accepts any positive pair of length and spacing in the same unit. If the last bay would be awkwardly short, either shorten the overall run, slightly reduce spacing so length divides more evenly, or accept the ceiling rule and cut the last rail to fit; this calculator always covers the full length with ceil.
Keep dimensions inside the published absolute range so counts cannot overflow into non-finite results the solver must reject. Prefer this capability when you already know the run length and target spacing and only need integer material counts; if your source is a closed perimeter, call once per straight side and sum posts carefully so shared corner posts are not double-counted.
What you can do with it
Backyard run material list
Homeowners enter fence length and desired post spacing to get posts and rails counts before shopping for timber or metal stock.
FAQ
How many posts do I need for a fence?
For one straight run, posts = ceil(length / spacing) + 1. Example: length 100 and spacing 10 → 10 sections and 11 posts.
What if spacing is zero or negative?
Post spacing must be strictly positive; zero or negative spacing cannot define a fence bay.
Does this include gates or corners?
No. It models one straight run. Call once per side of a perimeter and adjust so corner posts are not counted twice; treat gates as openings you subtract or model separately.
Is the fence post calculator free?
The browser tool is free and runs locally.
How many rails per section should I use?
Two is common for ranch-style fences and three for many privacy or picket styles, and two is used when you leave it blank. Rails are sections times rails per section, so 13 sections with 2 rails each give 26.
What if the last section comes out short?
The count always rounds up so the whole run is covered. If the last bay would be awkwardly short, shorten the run, reduce the spacing slightly so the length divides more evenly, or simply cut the last rail to fit.
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/home/fence-posts \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"length":100,"spacing":8}'const res = await fetch("https://api.kit.forhosting.com/home/fence-posts", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"length": 100,
"spacing": 8
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/home/fence-posts",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"length": 100,
"spacing": 8
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/home/fence-posts", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"length":100,"spacing":8}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"length":100,"spacing":8}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/home/fence-posts", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"length": 100,
"spacing": 8
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "home.fence_posts",
"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.
Limits
max_dim | 1000000000000 |
min_dim | 1e-15 |
max_rails_per_section | 100 |
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
Zero or negative spacing is rejected with a clear invalid_input error instead of inventing infinite posts, and non-positive length is rejected the same way.
How fence posts and rails are counted from length and spacing
Rails equal sections times rails_per_section, where rails_per_section is how many horizontal members sit between each consecutive pair of posts—two is common for ranch-style runs and three for many privacy or picket styles; the default is two when you omit the field. Spacing must be strictly positive: zero spacing would imply infinitely many posts, and negative spacing has no physical meaning on a line, so both cases return invalid_input. On success the tool echoes rounded length and spacing, publishes sections, posts, rails, rails_per_section, formula, message, and steps so you can audit the arithmetic by hand or in automated tests.
How to call the API and what comes back
Prefer sending numbers rather than pre-formatted strings when you control the client; when you must send strings, avoid unit suffixes or thousand separators that would fail the finite-number pattern. Send a JSON body with two required fields: length (aliases fence_length, L, len, run, run_length) and spacing (aliases post_spacing, space, gap, S, interval). Optionally send rails_per_section (aliases rails_per_bay, rails_between, rail_count, n_rails); when omitted it defaults to two. Length and spacing must be finite positive numbers within the published absolute range so the ratio and counts remain finite in IEEE double precision on the Worker and in the browser. rails_per_section when provided must be a positive integer up to the published maximum; string forms of whole numbers are accepted when they match a strict finite numeric pattern, but fractional rail counts are rejected. On success the response sets sections to the bay count, posts to sections plus one, rails to sections times rails_per_section, formula to the posts and rails expressions, message to a short English summary, and steps to an ordered substitution log. Failed validation—missing fields, non-finite numbers, zero or negative spacing, non-positive length, invalid rails_per_section, or values outside absolute limits—returns invalid_input and is never charged. Pricing is a flat $0.002 per successful request with unit item and zero marginal unit price.
Practical tips, limits, and related searches
When teaching or writing tests, pair an exact multiple (length one hundred, spacing ten → eleven posts) with a non-exact case that exercises the ceiling, and include a deliberate zero or negative spacing to prove the invalid_input path. This landing targets people searching for a fence post calculator, how many posts for a fence, fence rails from spacing, or posts and rails material list online; it is not a concrete post-hole volume tool, not a lumber board-foot estimator, not a gate hardware picker, and not a multi-segment property survey that places posts at GPS coordinates. Failed tasks that return invalid_input do not consume prepaid balance, which keeps exploratory scripts cheap when you deliberately send zero spacing to verify error handling. Round-trip checks are easy: recompute ceil of length over spacing by hand, add one for posts, multiply sections by rails_per_section for rails, and confirm the published integers match.
Integration use cases
Estimator take-off for property-line fences
Builders feed design length, spacing, and rails per bay into the API and attach posts, rails, and steps to a transparent quote.
Golden fixtures for construction apps
Developers generate known-good exact and ceiling cases plus deliberate zero-spacing rejections for unit tests and CI.
Technical questions
How are rails calculated?
Rails = sections × rails_per_section. sections is ceil(length / spacing). rails_per_section defaults to 2 if you omit it.