(Space Calc Logo)
Space Calc
Doing the math, so you don't have to.

Multi-Stage Rocket Delta-V Optimizer


When building a rocket, it is advantageous to do staging. Staging is throwing away big, expensive parts of your rocket while the rest continues on. The advantage is that you aren't carrying all that dead weight. For a more-complete explanation, see Wikipedia.

When one has multiple powered stages, the question arises as to how much Δv (a measure of the rocket's ability to push, and a function of the amount of propellant) to allocate to each stage. This turns out to be difficult, and to my knowledge (and effort) there is no way to write out the optimal Δv partitioning in closed-form.

This calculator will attempt to solve it for you anyway.


Enter in the number of stages, the mission Δv, and the lilac boxes below (i.e., the last-stage payload, either ISP or exhaust velocity for each boost stage, and one of mass-ratio/inert-mass-fraction/propellant-fraction for each boost stage). The drop-down selections allow you to change the units.

Number of stages:
(Must be at least two: the unpowered payload and a single boost stage)

Mission Δv:

Some Examples to Try

How Does It Work?


Since the answer cannot be found in closed-form, the calculation is numerical. The code essentially solves for the Δv partition using simulated annealing (sortof like stochastic gradient descent, but worse).

To get high accuracy, this needs to be done carefully. For example, you can't add a small perturbation to one of the fractions and then renormalize the fractions to sum to \(1\), since this loses too much precision. Instead, the perturbation is added to one fraction and subtracted from another. Then, it is renormalized anyway (to deal with numerical issues).

The equations that are solved I derived myself from the rocket equation (the derivation, below, is not difficult). Essentially, we have a system that looks like, for every powered stage \(i\) in an \(n\)-stage rocket:\[ M_i = \left(\sum_{j=i+1}^n M_j\right)\left(\frac{ R_i - 1 }{ 1 - R_i f_i }\right) \]Where:

\(M_i\) is the wet mass of stage \(i\). For the last stage, which is unpowered, this is just your payload's mass.
\(R_i\) is the mass ratio of stage \(i\), calculated as \(\exp\left(\frac{\Delta v_i}{V_i}\right)\).
\(f_i\) is the inert mass fraction (IMF) of stage \(i\).
\(\Delta v_i\) is the Δv for stage \(i\) (the calculator chooses this, using the Δv allocation per-stage).
\(V_i\) is the exhaust velocity of stage \(i\), calculated as \(1 g_0\) times the stage's specific impulse.

The key intuition of each such equation is that it tells how massive stage \(i\) needs to be (\(M_i\)), in order to lift all the stages above it by the given Δv allocation (\(\Delta v_i\)).

The calculator then adjusts the allocation—the \(\Delta v_i\)s—to try to minimize the sum of all the \(M_i\)s (i.e., the total mass of the rocket, which scales with cost and difficulty to build). For a worked example, see below.

The solver itself was based on an earlier Python version I wrote (here), which was originally released with notes on Google+ (here). This version was also released on Google+ (here).

Results should be taken with a grain of salt. This is a very complicated program, mainly due to the UI interaction, and it was made worse by the fact that JavaScript is a terrible language without, for example, RAII, typesafety, or integers. Even the Python version appears to have a problem with the mass ratio output. Bug reports and suggestions are sought.


Let's take the example of the Falcon 9 v.1.1, above, with a \(10\,000\) m/s Δv and a \(22\,800\) kg payload. We might start by allocating 60.0% of that Δv to the first stage (i.e. \(\Delta v_1:=6\,000\) m/s) and 40.0% to the second (i.e. \(\Delta v_2:=4\,000\) m/s):\begin{alignat*}{5} &M_3&&= 22\,800 && && && \\ &M_2&&= \left(\sum_{j=2+1}^3 M_j\right)\left(\frac{R_2-1}{1-R_2 f_2}\right)&&= \left(~~~~~~~~~~~M_3\right)\left(\frac{\exp(\Delta v_2/V_2)-1}{1-\exp(\Delta v_2/V_2) f_2}\right)&&\approx ~~~~~~~~~~~~~~~~~~22\,800~\frac{\exp(4\,000~/~3\,330)-1}{1-\exp(4\,000~/~3\,330)\cdot 0.0404}&&\approx 61\,100\\ &M_1&&= \left(\sum_{j=1+1}^3 M_j\right)\left(\frac{R_1-1}{1-R_1 f_1}\right)&&= \left(M_2+M_3\right)\left(\frac{\exp(\Delta v_1/V_1)-1}{1-\exp(\Delta v_1/V_1) f_1}\right)&&\approx (61\,100+22\,800)~\frac{\exp(6\,000~/~2\,910)-1}{1-\exp(6\,000~/~2\,910)\cdot 0.0552}&&\approx 1\,020\,000\\ \end{alignat*}And the sum is:\[ M_3 + M_2 + M_1 \approx 22\,800 + 61\,100 + 1\,020\,000 \approx 1\,100\,000 \]However, this is not optimal. One now tweaks the Δv allocation to get a better result. Suppose we instead allocate 55.0% of the Δv to the first stage (\(\Delta v_1:=5\,500\) m/s) and 45.0% to the second (\(\Delta v_2:=4\,500\) m/s). When we run the equations through again, we get:\[ M_3 + M_2 + M_1 \approx 22\,800 + 77\,100 + 887\,000 \approx 987\,000 \]Since \(987\,000 < 1\,100\,000\), this Δv allocation is better. We continue in this vein until we discover the optimal allocation (34.7% to the first, 65.3% to the second):\[ M_3 + M_2 + M_1 \approx 22\,800 + 195\,000 + 610\,000 \approx 828\,000. \]

How Does It Work? (Derivation of Formula)

Essentially, want to figure out stage \(i\)'s mass \(M_i\) such that stage \(i\) can lift the mass of the whole rocket stack above it (\(\sum_{j=i+1}^n M_j\)), through the stage's Δv allocation (\(\Delta v_i\)).

Recall the Tsiolkovsky rocket equation:\[ \Delta v_i = V_i \ln\left( \frac{M_{i,0}}{M_{i,1}} \right) \]Where:

\(M_{i,0}\) is the initial (wet) mass of the stage (i.e., \(M_i\), above) plus the whole rocket stack above it.
\(M_{i,1}\) is the final mass of the stage (i.e., the dry mass) plus the whole rocket stack above it.

We simply substitute in the inert mass fraction and wet masses:\[ \Delta v_i = V_i \ln\left( \frac{ ~~~M_i + \left(\sum_{j=i+1}^n M_j\right) }{ f_i M_i + \left(\sum_{j=i+1}^n M_j\right) } \right) \]. . . and solve for \(M_i\):\begin{align*} R_i &= \frac{ ~~~M_i + \left(\sum_{j=i+1}^n M_j\right) }{ f_i M_i + \left(\sum_{j=i+1}^n M_j\right) }\\ R_i f_i M_i + R_i \left(\sum_{j=i+1}^n M_j\right) &= M_i + \left(\sum_{j=i+1}^n M_j\right)\\ \left(R_i f_i - 1\right) M_i &= \left(1-R_i\right) \left(\sum_{j=i+1}^n M_j\right)\\ M_i &= \left(\sum_{j=i+1}^n M_j\right)\left(\frac{ R_i - 1 }{ 1 - R_i f_i }\right) \end{align*}