top of page

The Michaelis-Menten Enzyme Kinetics Model

At some point in school or university most of us met the Michaelis-Menten model of enzyme kinetics, providing a simplified description of the dependence of the rate of an enzyme-catalysed reaction on substrate concentration. This post explores the assumptions and derivation of the model, its caveats, and how we can fit it to data. We will see why it might not always be an appropriate model and how to test for that.


Reaction equations

The simplest version of the Michaelis-Menten model assumes that a single species of substrate S and enzyme E reversibly form an enzyme-substrate complex ES, then that complex reversibly transforms to a single species of product P and (recovered) enzyme, ready to go again. The recovery of the enzyme means it is a catalyst. It is assumed that the formation of the enzyme-substrate complex is first order with respect to all reagents. Therefore, we have the following set of reaction equations:

And these allow us to write the following set of reaction equations:

In these equations, the quantities E,S,ES and P denote time-dependent concentrations of enzyme, substrate, enzyme-substrate complex and product. A dot is used to indication multiplication of concentrations. This is easier than using the traditional square brackets for concentrations.

Our objective is to express the rate of enzyme-catalysed reaction as a function of observable quantities and (unknown) constant parameters that can be obtained by fitting the model to data. The Michaelis-Menten model achieves this by making the following assumptions:

  1. At the beginning of the reaction, only S and E will be present, and in the time period observed, P will be negligible (initial rate limit)

  2. The total concentration of all reagents combined is constant (conservation of mass)

  3. There will exist a steady-state period, without violating assumption 1, in which the concentration of ES is constant

  4. Conditions are unchanging so that rate coefficients are constant

  5. The substrate concentration is very much higher than enzyme concentration

Assumption 1 means that the rate of reaction is equivalent to the rate of formation of product P. It also means that we can neglect the formation of ES from E+P, so the reaction equations simplify to:

The system of rate equations with the initial rate assumption (assumption 1) simplify to:

We are now looking to find dP/dt under the conditions of the remaining 3 assumptions, namely an initial rate, steady state solution. Therefore need to express ES, the concentration of enzyme-substrate complex (in the initial rate, steady-state regime) in terms of the constants of the system. Now examining the expression for dES/dt, assumption 3 (steady-state) means that its concentration is unchanging in the period of measurement, so its rate of change is zero:

This condition is a bit stronger than necessary. It is sufficient to replace it with the requirement that rate of change of ES is negligible compared to rate of change of P:

We will show in due course that this is more reasonable than it may seem at first. For now, we simply put it to use, firstly by rearranging so that the unknown dES/dt no longer appears:

Or equivalently:

Under assumption 5, the initial rate, steady-state substrate concentration is approximately equal to the total substrate concentration and we can write:

The term KM is the Michaelis constant and will be shown in due course to represent the affinity of an enzyme for its substrate. For now it suffices to say that it is constant since it can be written in terms of rate constants only, which assumption 4 requires to be indeed constant (i.e. no temperate, pressure, pH changes etc).

We are still left with enzyme concentration E as an unknown. Assumption 2 (conservation of mass) can be stated:

Where the T subscript simply means "total". We will take both these totals to be known constants. It means that once substrate is titrated into enzyme, nothing else is added or removed from the system under observation in the course of the experiment. We can eliminate E by rearranging the expression for the Michaelis constant to give:

Rearranging the above for ES gives:

So we now have an expression for ES, the concentration of enzyme-substrate complex, in the initial-rate, steady-state regime, in terms of known constants of the experiment and an model parameter KM. To complete the derivation, we return to our original expression for dP/dt to get:

The "0" subscript has been introduced to make clear that this is an initial-rate, steady-state solution. The Vmax term represents the maximal rate of reaction, which will be shown in due course. This completes the derivation of the basic Michaelis-Menten expression. The initial-rate, steady-state solution is a linearly hyperbolic function of substrate concentration with affinity KM and plateau Vmax. However, the 5 conditions stated must be met, else this solution is not valid.


Basic predictions of the model

It is easy to see what this model predicts for the dependence of rate of reaction (in initial-rate, steady-state regime) as a function of enzyme and substrate concentration and the constants k23 and KM. A code snippet like this will do the job with Python:

import numpy as np
import matplotlib.pyplot as plt

def michaelis_menten(E,S,kcat,Km):
    # S should be numpy array, others constant
    return kcat*E*S/(Km+S)

# molar
E = 1e-6
S = np.linspace(0,2e-3,1001)
kcat = [1000, 2000, 3000, 4000]
Km = 200e-6

cmap =
line_colors = cmap(np.linspace(0.4,0.9,len(kcat)))
for i,k in enumerate(kcat):
    plt.plot(1000*S, 1000*michaelis_menten(E,S,k,Km),
             label="kcat="+str(k)+" /s")
plt.xlabel("Substrate concentration (mM)")
plt.ylabel("dP/dt (mM/s)")
plt.title("Michaelis-Menten dependence on kcat")

Which gives us this plot:

The constant k23 has been renamed kcat, denoting the catalytic constant or turnover number. It can be shown that this is the maximum number of reactions per unit time that the enzyme can catalyse. In the figure above, it is clear that rate of reaction increases with substrate concentration up to some maximum. That maximum is Vmax. An enzyme with twice the turnover number has twice the Vmax if conditions are otherwise unchanged.

A similar plot can be made for a constant Vmax but different values of the Michaelis constant (affinity) KM:

All the curves will reach the same Vmax plateau if a sufficient substrate concentration were available, but a lower Km means that a lower substrate concentration is required to achieve an appreciable rate. An enzyme with a high affinity for substrate has a low Km.


The meaning of the Michaelis constant

The Michaelis constant Km is defined by:

Unit calculus shows that is has units of concentration. It will take a lower value if the concentration of ES if higher at steady-state, so a low Km implies that the ES state is favoured over unbound enzyme and substrate. By contrast, a high Km implies that unbound E and S are favoured over forming the ES complex. We therefore interpret Km as the affinity of an enzyme for its substrate, with low Km meaning high affinity. If the substrate concentration titrated into enzyme happens to be exactly the Km, the the rate of reaction is:

So Km is the substrate concentration at which rate of reaction is half-maximal.

The meaning of turnover number

The turnover number, kcat, is the number of reactions an enzyme can catalyse per second when saturated with substrate. More complex models that the simple one here also have a kcat, but in this case we can identify the rate constant k23 with kcat. In a more complex model (for example, a multi-step reaction), there would still be a kcat but it would refer to a different rate constant. kcat is general, k23 is specific to the simple Michaelis-Menten model. It is easy to see that kcat represents turnover. Firstly, note:

Which is also the definition of Vmax, but shows that kcat must have units of inverse time. Since E+S are in equilibrium with ES, we expect all enzyme to be in the ES state if S is extremely high.


Fitting the model to data

A typical dataset when seeking to apply the Michaelis-Menten model to obtain Km and kcat for a enzyme will ideally contain well-sampled values of substrate concentration, and for each, one or more measurements of initial rate (which we hope will be at steady-state). Equipped with such a dataset, the Michaelis-Menten model can be fitted directly to the (S,dP/dt) data using any non-linear fitting procedure you like. It is possible to transform the data so that a linear fit can be used, but that mangles the uncertainties and was useful in the past when computers couldn't easily manage non-linear fits. Nowadays it's as difficult as putting on a hat. More on why not to bother with linearising data because you're still fitting using an Acorn 3000 later. For this demo, I'll show how to fit the Michaelis-Menten model to data using Python and the fitting packing LMFIT. The latter can be installed with the command

pip install lmfit

And its documentation can be found here. Suppose we have only one assay per substrate concentration. The following code snippet shows how we can fit the model to data:

import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model,Parameters

def michaelis_menten(S,E,Km,kcat):
    return kcat*E*S/(Km+S)

# Create and fit model
# S is the (independent) substrate conc
# dPdt is rate of reaction
mdl = Model(michaelis_menten)
params = Parameters()
params.add("E", value=E, vary=False)
params.add("Km", value=1e-3,min=1e-9, max=1e-3, vary=True)
params.add("kcat", value=1e5, min=0, max=1e9, vary=True)
result =,params=params,S=S)

# predict for well-sampled concentration range
s = np.linspace(0,700e-6,1000)
dPdt_pred = result.eval(S=s)
dPdt_bounds = result.eval_uncertainty(sigma=2,S=s)

That is sufficient to fit the model and calculate 2-sigma prediction bounds using the estimated covariance matrix. Bounds and initial estimates were also supplied. The Levenberg-Marquardt algorithm was used - the default, as no other option was specified. The result looks like this:

The plot was created with this code:

cmap =
colors = cmap(np.linspace(0.4,0.9,10))
plt.xlabel("Substrate concentration (mM)")
plt.ylabel("dP/dt (mM/s)")

The data used were simulated using the Michaelis-Menten model with some noise added. The true (simulation) parameters were the following:

Km = 100e-6 # M
kcat = 1000 # /s
E = 1e-6 # assumed known in fitting

The fitted parameters were:

from lmfit import fit_report

[[Fit Statistics]]
 # fitting method   = leastsq
 # function evals   = 19
 # data points      = 12
 # variables        = 2
    chi-square         = 4.3769e-08
    reduced chi-square = 4.3769e-09
    Akaike info crit   = -229.151018
    Bayesian info crit = -228.181205
    E:     1e-06 (fixed)
    Km:    1.0775e-04 +/- 2.3690e-05 (21.99%) (init = 0.001)
    kcat:  1047.84964 +/- 93.4247195 (8.92%) (init = 100000)
[[Correlations]] (unreported correlations are < 0.100)
    C(Km, kcat) =  0.900

The model has therefore slightly over-estimated Km and kcat, but the true values are within the reasonably narrow uncertainty bounds. The success may be largely due to the thorough data sampling near the true Km, where the gradient of the function is steep. It is also important to have at least 1 measurement significantly in excess of the Km.


The Steady State

Important conditions for the Michaelis-Menten model are initial rate and steady state. So we will look at what that means, and what happens if we make observations outside the valid range but try to apply the model anyway. There are cases where there is no time period where the system can meet both conditions simultaneously. We will explore the consequences. Firstly, how to simulate the time-dependence of all 4 species in the model: E,S,ES,P. This simply requires integrating the set of coupled rate equations. Not so easy analytically, but easily done numerically, for example using the following Python code:

import numpy as np
from scipy.integrate import solve_ivp

# define rate equations for reactions
def rate_equations(t,Y,k12,k21,k23,k32):
 # Y ordered E,S,ES,P
    dy = [0]*4
    dy[0] = -k12*Y[0]*Y[1] + (k21+k23)*Y[2] - k32*Y[0]*Y[3]
    dy[1] = -k12*Y[0]*Y[1] + k21*Y[2]
    dy[2] = k12*Y[0]*Y[1] - (k21+k23)*Y[2] + k32*Y[0]*Y[3]
    dy[3] = k23*Y[2] - k32*Y[0]*Y[3]
 return dy

# molar, seconds
Km = 100e-6
k23 = 100
k32 = 1e6
k21 = 100
k12 = (k21+k23)/Km

t = np.linspace(0,60,1001)
tspan = [t[0], t[-1]]

E0 = 0.1e-6
S0 = 50e-6
y0 = [E0, S0, 0,0] # E,S,ES,P

# integrate rate equations
rates = solve_ivp(lambda t,Y:rate_equations(t,Y,k12,k21,k23,k32),

The solutions, i.e. concentrations as a function of time for E,S,ES,P, are plotted here:

The concentrations of S and P are massively higher than E and ES, as S>>E is a requirement of the model we want to ultimately fit. We can see that the reaction slightly favours the P state as it tends towards equilibrium (a process accelerated by the enzyme with no change to the position of equilibrium). To identify when or if the reaction has a steady-state phase with respect to ES, we need to zoom in a bit:

Since we are only interested really in the initial-rate region, we have zoomed on both axes. The ES concentration is changing very little over most of this time, which is precisely what is meant by steady state. At least, its rate of change is very much less than that of E of P, which is a good condition for a realistic steady state. We can also take a look at the very early part of the reaction during which steady state is established:

So steady state is established quite quickly in this case. This is important, as we can only use measurements in the initial rate phase, so we do not want to lose measurement time waiting for steady state only to invalidate the model by having waited so long the initial rate condition is violated. In this zoomed-in figure, we can see that dP/dt is constant and dES/dt roughly zero from about 0.02 s onwards, but after a few seconds dP/dt will be slowing down.


bottom of page