Arrow speed calculator
A 50 lb bow drawn 28 inches can launch a 400-grain arrow at up to 362.38 ft/s, the theoretical ceiling with perfect efficiency. Enter draw weight, draw length and arrow mass, and set an efficiency to match your own bow. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Draw weight lb
- 50
- Draw length in
- 28
- Arrow mass grains
- 400
- Arrow speed fps
- 362.38
- Stored energy ft lb
- 116.666667
- Efficiency
- 1
No chronograph, no range day, no spreadsheet: one call with three inputs gives a defensible estimate you can use to compare setups, tune an arrow build, or sanity-check a purchase before any money changes hands.
Why stored energy is the honest way to estimate speed
Most arrow speed calculator tools on the internet are black boxes built on IBO marketing numbers, which assume a very specific bow, arrow and draw length and then extrapolate with rough rules of thumb. This capability takes a different route that you can audit yourself: a bow is a spring, and a spring stores energy in proportion to how hard and how far you draw it.
Multiplying draw weight in pounds-force by draw length in feet gives an upper bound on the stored energy in foot-pounds, and the optional efficiency factor scales that bound down to what the limbs actually deliver to the arrow. Because every input is explicit, you can reproduce the result by hand, adjust the efficiency to match a chronograph reading from your own bow, and get a personalized constant that makes later estimates far more accurate than any generic chart.
How the calculation works, step by step
The conversion chain is short and fully deterministic. First, draw length in inches is divided by twelve to express it in feet. Second, stored energy is computed as efficiency multiplied by draw weight in pounds-force multiplied by draw length in feet, which yields foot-pounds.
Third, the kinetic-energy relation for archery units is inverted: since one foot-pound of kinetic energy corresponds to speed squared times arrow mass in grains divided by 450240 — a constant that folds together the factor of two, standard gravity and the 7000 grains in a pound — the launch speed in feet per second is the square root of 450240 times the stored energy divided by the arrow mass.
Using the estimate well in practice
Treat the default efficiency of 1.0 as a theoretical ceiling, not a prediction: real compound bows transfer roughly seventy to ninety percent of stored energy to the arrow, and recurves somewhat less, because energy is also lost to limb vibration, string mass and noise.
The practical workflow is to measure one arrow through a chronograph, solve for the efficiency that reproduces that reading, and then reuse that efficiency to forecast the speed of every other arrow weight you are considering — lighter arrows fly faster but carry the same energy, heavier arrows fly slower and hit with more momentum. The same model also exposes trade-offs honestly: doubling draw weight does not double speed, because speed grows with the square root of energy.
That square-root law is why chasing speed through poundage alone yields diminishing returns compared to trimming arrow mass.
What you can do with it
Compare two arrows before buying
Estimate the speed difference between a 350-grain and a 500-grain arrow on the same bow and decide whether the lighter build is worth the loss of momentum.
Calibrate efficiency against a chronograph
Feed one measured speed back into the model to derive your bow's real efficiency, then forecast every other arrow weight with that personalized constant.
Fill a ballistics pipeline
Use the estimated launch speed as the muzzle velocity input for trajectory and drop calculations in a sight-tape or range-estimation tool.
FAQ
Which units does it use?
Draw weight in pounds-force, draw length in inches, arrow mass in grains, and the result in feet per second — the standard units of archery.
How accurate is the estimate?
With the default efficiency of 1.0 it is an upper bound. Calibrate efficiency against one chronograph reading and the estimates for other arrow weights typically land within a few percent.
Does it work for recurve and compound bows?
Yes. The model is bow-agnostic; the difference between designs is absorbed by the efficiency factor you supply.
Is any of my data stored?
No. The inputs are numbers processed in memory; nothing is persisted after the response is returned.
Why doesn't doubling the draw weight double the arrow speed?
Because speed grows with the square root of the stored energy. Doubling the draw weight doubles the energy, but the speed rises by much less than double. Lighter arrows fly faster on the same energy, heavier ones slower with more momentum.
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/phys/arrow-speed \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"draw_weight_lb":50,"draw_length_in":28,"arrow_mass_grains":400}'const res = await fetch("https://api.kit.forhosting.com/phys/arrow-speed", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"draw_weight_lb": 50,
"draw_length_in": 28,
"arrow_mass_grains": 400
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/phys/arrow-speed",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"draw_weight_lb": 50,
"draw_length_in": 28,
"arrow_mass_grains": 400
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/phys/arrow-speed", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"draw_weight_lb":50,"draw_length_in":28,"arrow_mass_grains":400}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"draw_weight_lb":50,"draw_length_in":28,"arrow_mass_grains":400}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/phys/arrow-speed", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"draw_weight_lb": 50,
"draw_length_in": 28,
"arrow_mass_grains": 400
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "phys.arrow_speed",
"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
The arrow speed API estimates how fast an arrow leaves the bow in feet per second, starting from the three numbers every archer knows: the draw weight printed on the limb, the shooter's draw length, and the total mass of the arrow in grains. It applies a stored-energy conversion — the energy the limbs put into the arrow divided by the arrow's mass — and returns the launch speed along with the stored energy behind it.
How the calculation works, step by step
All three inputs must be positive numbers; anything missing, zero, negative or non-numeric is rejected with an invalid_input error and the request is never charged.
Technical questions
What does it cost?
$0.002 per request. It is also free to run in your browser on this page.
What happens if I send a zero or negative value?
The request is rejected with an invalid_input error naming the offending field, and you are not charged.