Equilibrium Unemployment#

Introduction#

The labor market is among the most studied institutions in economics, yet some of its most basic features resist explanation by the standard competitive model. In a frictionless Walrasian market, prices adjust instantaneously to equate supply and demand, leaving no room for unemployment as an equilibrium phenomenon — anyone willing to work at the prevailing wage finds a job immediately, and any firm willing to pay that wage finds a worker. Yet unemployment is persistent, pervasive, and highly variable over the business cycle. Job vacancies coexist with unemployment even in tight labor markets. Workers and firms spend substantial time and resources searching for one another. And wages appear to be determined by something more complex than a Walrasian auctioneer.

These facts call for a richer framework. This lecture develops the search and matching model of the labor market, the dominant paradigm in modern labor economics and macroeconomics for studying unemployment, wage determination, and labor market dynamics. The framework was developed primarily by Diamond, Mortensen, and Pissarides — awarded the Nobel Prize in 2010 — and it remains the workhorse model for both theoretical and empirical work on labor markets.

The model is organized around three central questions:

  1. How are aggregate labor market outcomes — unemployment, job vacancies, and employment — determined as equilibrium phenomena?

  2. How are wages determined?

  3. What role does the labor market play in explaining business cycles and growth?

Departures from the Neoclassical Paradigm#

To address these questions, the search and matching framework departs from the neoclassical model in several ways.

Trading frictions. In reality, matching a worker to a job is a costly, time-consuming process. Workers must search for openings, apply, and interview; firms must advertise, screen applicants, and train new hires. These activities consume real resources and take time, meaning that the labor market does not clear instantaneously. Frictions arise from heterogeneity — workers differ in skills, preferences, and location; jobs differ in requirements, compensation, and location — as well as from informational imperfections - workers do not know which firms have suitable vacancies, and firms do not know which workers have suitable skills.

Flow dynamics. Rather than thinking of the labor market as a static equilibrium, the search and matching framework emphasizes the continuous flows between labor market states. At any moment, some workers are losing jobs and entering unemployment; others are finding jobs and leaving unemployment. Unemployment in steady state is not the absence of matching activity but the outcome of a balance between these flows — a point that has profound implications for how we think about policy and business cycles.

Unemployment as an equilibrium outcome. In the search and matching model, unemployment is not a disequilibrium phenomenon to be explained away, but a feature of the equilibrium itself. The time required to match workers and firms means that some workers are always between jobs, and some jobs always go unfilled. The model predicts not just the existence of unemployment but its level, its comovement with vacancies over the cycle, and its response to shocks and policy interventions.

Bargained wages. The neoclassical model treats wages as prices determined by competitive market forces. In the search and matching model, a match between a specific worker and a specific firm generates a bilateral surplus — the value created by their meeting exceeds what either party could obtain elsewhere — and the wage is the outcome of a negotiation over how to divide that surplus. This bilateral nature of wage determination, and its dependence on outside options and bargaining power, generates predictions about wages and their cyclical behavior that differ sharply from the competitive benchmark.

Roadmap#

The chapter proceeds as follows. We first specify the environment: the matching technology that governs how unemployed workers and vacant jobs find one another, and the job destruction process that governs flows back into unemployment. We then derive the steady-state unemployment rate as an equilibrium outcome of these flows. With the matching environment in place, we develop the job creation decision of firms and the wage determination process, culminating in a full characterization of the steady-state equilibrium. We close with a series of comparative statics that illustrate how the equilibrium responds to changes in productivity, unemployment benefits, interest rates, separation rates, and matching efficiency.

The Matching Function#

Trading Frictions and the Matching Technology#

The foundation of the search and matching model is a reduced-form description of the process by which unemployed workers and vacant jobs find one another. Rather than modeling the specific sources of friction — heterogeneity in worker skills and job requirements, geographic dispersion, informational asymmetries — the framework captures their aggregate implications through a single object: the matching function.

Let \(\mathcal{U}\) denote the number of unemployed workers actively searching for jobs and \(\mathcal{V}\) the number of vacant jobs actively seeking workers. The flow of new matches formed per unit time is:

\[\mathcal{M} = m(\mathcal{U}, \mathcal{V})\]

The matching function \(m\) plays the same role in the labor market that a production function plays in goods markets: it summarizes a complex underlying process — the decentralized, uncoordinated search activity of workers and firms — in a tractable aggregate relationship. Just as a production function does not describe how a firm organizes its workers, the matching function does not describe how any particular worker finds any particular job. It simply relates aggregate inputs (searchers and vacancies) to aggregate output (matches).

We impose three assumptions on the function \(m\):

  • Monotonicity: \(m\) is strictly increasing in both arguments — more searchers and more vacancies each produce more matches.

  • Concavity: the marginal contribution of an additional searcher or vacancy is decreasing reflecting congestion in labor markets.

  • Constant returns to scale: A proportional increase in the stock of vacancies and unemployed results in the same increase in total matches: \(m(\lambda\mathcal{U}, \lambda\mathcal{V}) = \lambda m(\mathcal{U}, \mathcal{V})\) for all \(\lambda > 0\).

The constant returns assumption is both empirically supported and theoretically convenient. It implies that match rates depend only on the ratio of vacancies to unemployment, not on their levels separately — a property we exploit. We normalize the size of the labor force to one, so that \(\mathcal{U} + \mathcal{E} = 1\) where \(\mathcal{E} = 1 - \mathcal{U}\) is the employment rate.

The most widely used parametric specification is the Cobb-Douglas matching function:

\[m(\mathcal{U}, \mathcal{V}) = A\mathcal{U}^{1-\beta}\mathcal{V}^{\beta}\]

where \(A > 0\) is matching efficiency and \(\beta \in (0,1)\) is the elasticity of matches with respect to vacancies. This specification satisfies all three assumptions above and is consistent with a large body of empirical evidence.

Job-Finding and Vacancy-Filling Rates#

A central variable in the model is labor market tightness, defined as the ratio of vacancies to unemployment:

\[\theta \equiv \frac{\mathcal{V}}{\mathcal{U}}\]

Market tightness is an index of conditions in the labor market from the perspective of firms: a high value of \(\theta\) means many vacancies relative to searchers, making it difficult for firms to fill positions and easy for workers to find jobs. A low value of \(\theta\) means it is difficult for workers to find jobs, but easy for firms to fill positions. As we will see, \(\theta\) is the key endogenous variable summarizing labor market conditions in equilibrium.

The constant returns assumption allows us to express the rates at which workers find jobs and firms fill vacancies entirely in terms of market tightness \(\theta\).

The vacancy-filling rate is the rate at which a vacant job is matched to a worker:

\[q(\theta) \equiv \frac{m(\mathcal{U}, \mathcal{V})}{\mathcal{V}} = m\!\left(\frac{\mathcal{U}}{\mathcal{V}}, 1\right) = m(1/\theta, 1)\]

where the second equality uses constant returns to scale. During a small interval of time \(dt\), a vacant job is filled with probability \(q(\theta)\,dt\), so the expected duration of a vacancy is \(1/q(\theta)\). Since more vacancies relative to workers makes it harder for any individual firm to attract a worker, \(q'(\theta) \leq 0\), so that the vacancy-filling rate is decreasing in market tightness.

The job-finding rate is the rate at which an unemployed worker is matched to a firm:

\[f(\theta) \equiv \frac{m(\mathcal{U}, \mathcal{V})}{\mathcal{U}} = m\!\left(1, \frac{\mathcal{V}}{\mathcal{U}}\right) = \theta q(\theta)\]

During a small interval of time \(dt\), an unemployed worker finds a job with probability \(f(\theta)\,dt\), so the expected duration of unemployment is \(1/f(\theta)\). Since a tighter market means more vacancies competing for each worker, \(f'(\theta) \geq 0\), so that the job-finding rate is increasing in market tightness.

The relationship \(f(\theta) = \theta q(\theta)\) is worth examining. It says that the job-finding rate and vacancy-filling rate are linked through tightness: a market that is good for workers (high \(f\)) is necessarily difficult for firms (low \(q\)), and vice versa. This tension is at the heart of the model’s predictions about how shocks propagate through the labor market.

For the Cobb-Douglas specification, these rates take the functional forms:

\[q(\theta) = A\theta^{-(1-\beta)}, \qquad f(\theta) = A\theta^{\beta}\]

confirming that \(q\) is decreasing and \(f\) is increasing in \(\theta\), with elasticities \(-(1-\beta)\) and \(\beta\) respectively.

Congestion Externalities#

The matching function embeds a set of externalities that are absent from competitive markets and that have important implications for efficiency.

When an additional worker enters the pool of job-seekers, the probability that any existing vacancy is filled rises, which benefits firms. But the entry of an additional searcher also reduces the job-finding probability of every other worker — each searcher now competes with more rivals for the same pool of vacancies. This worker congestion externality means that the private return to search exceeds the social return: individual workers do not internalize the negative effect their search imposes on other workers.

The symmetric argument applies on the firm side. When an additional firm posts a vacancy, the job-finding probability for workers rises, which benefits searchers. But the entry of an additional vacancy reduces the vacancy-filling probability for every other firm. This firm congestion externality means that the private return to posting a vacancy exceeds the social return.

Formally, an increase in \(\theta\) — more vacancies relative to searchers — raises \(f(\theta)\) and reduces \(q(\theta)\). The externalities run in opposite directions for workers and firms, and whether the market equilibrium is socially efficient depends on whether these externalities are balanced. This is the content of the Hosios condition, which we will encounter when we discuss the welfare properties of the equilibrium.

Before proceeding, it is useful to build intuition for the behavior of \(q(\theta)\) and \(f(\theta)\) by plotting them under the Cobb-Douglas specification. The key parameters are matching efficiency \(A\) and the vacancy elasticity \(\beta\). We fix \(A = 1\) for simplicity — changes in \(A\) shift both curves proportionally without affecting their slopes — and vary \(\beta\) to illustrate its role in governing the relative sensitivity of the two rates to market tightness.

Several features of the figure are worth noting. First, the two rates respond to tightness in opposite directions: as \(\theta\) rises, firms find it progressively harder to fill vacancies while workers find it progressively easier to find jobs — the congestion externalities working in opposite directions discussed above. Second, at \(\theta = 1\) (equal numbers of vacancies and searchers), both rates equal \(A\) regardless of \(\beta\), since \(q(1) = f(1) = A\). Third, \(\beta\) governs the curvature of both schedules: a higher \(\beta\) makes \(q(\theta)\) flatter and \(f(\theta)\) steeper, meaning that the job-finding rate is more sensitive to tightness while the vacancy-filling rate is less so. This has direct implications for the elasticity of unemployment duration with respect to labor market conditions — a quantity of central importance when calibrating the model to data.

Hide code cell source

import numpy as np
import matplotlib.pyplot as plt

# ──────────────────────────────────────────────
# Parameters
# ──────────────────────────────────────────────
A     = 1.0
betas = [0.3, 0.5, 0.7]
# Start very close to zero to capture:
#   - the asymptote of q(θ) → ∞ as θ → 0
#   - f(θ) → 0 as θ → 0  (all curves pass through origin)
theta = np.linspace(1e-4, 5, 1000)

def vacancy_filling(theta, A, beta):
    return A * theta ** (-(1 - beta))

def job_finding(theta, A, beta):
    return A * theta ** beta

# ──────────────────────────────────────────────
# Plot
# ──────────────────────────────────────────────
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
colors = ["#2c7bb6", "#d7191c", "#1a9641"]

for beta, color in zip(betas, colors):
    q = vacancy_filling(theta, A, beta)
    f = job_finding(theta, A, beta)
    label = rf"$\beta = {beta}$"
    axes[0].plot(theta, q, color=color, lw=2, label=label)
    axes[1].plot(theta, f, color=color, lw=2, label=label)

# ── q(θ) panel ──
# Cap the y-axis: the asymptote sends q → ∞ near θ = 0, which would
# compress the rest of the figure.  We cap at 4 and rely on the
# near-vertical left edge of each curve to convey the asymptote.
axes[0].set_ylim(0, 4)
axes[0].set_xlim(0, theta[-1])
axes[0].set_title(r"Vacancy-Filling Rate $q(\theta) = A\theta^{-(1-\beta)}$",
                  fontsize=12)
axes[0].set_xlabel(r"Market Tightness $\theta$", fontsize=11)
axes[0].set_ylabel(r"$q(\theta)$", fontsize=11)
axes[0].legend(fontsize=11)
axes[0].axvline(1, color="gray", lw=0.8, linestyle="--", alpha=0.6)
axes[0].text(1.05, 3.7, r"$\theta = 1$: $q = A$", fontsize=9, color="gray")

# ── f(θ) panel ──
# All curves should visibly pass through (0, 0) with the fine grid.
axes[1].set_ylim(0, None)
axes[1].set_xlim(0, theta[-1])
axes[1].set_title(r"Job-Finding Rate $f(\theta) = A\theta^{\beta}$",
                  fontsize=12)
axes[1].set_xlabel(r"Market Tightness $\theta$", fontsize=11)
axes[1].set_ylabel(r"$f(\theta)$", fontsize=11)
axes[1].legend(fontsize=11)
axes[1].axvline(1, color="gray", lw=0.8, linestyle="--", alpha=0.6)
axes[1].text(1.05, axes[1].get_ylim()[1] * 0.05,
             r"$\theta = 1$: $f = A$", fontsize=9, color="gray")

fig.suptitle(
    r"Matching Rates under the Cobb-Douglas Matching Function ($A = 1$)",
    fontsize=13, y=1.02)
plt.tight_layout()
plt.show()
_images/0f947f1768b9069e1cdac1656ecba567e4819c4e979c6a0bdafbc4bba106db25.png

Job Destruction#

To complete the description of labor market flows, we need to model the process by which employed workers return to unemployment and filled jobs become vacant. In the baseline model, we treat job destruction as exogenous - employed workers lose their jobs at a constant Poisson rate \(s > 0\), independent of productivity, wages, or any other endogenous variable. During a small interval of time \(dt\), an employed worker loses their job with probability \(s\,dt\), so the expected duration of an employment spell is \(1/s\).

The separation rate \(s\) is a reduced-form parameter that captures a range of underlying shocks — idiosyncratic productivity shocks, demand shocks, worker-specific shocks — without distinguishing between them. This simplification is analytically convenient and serves as the appropriate starting point. In a later lecture, we endogenize job destruction by allowing idiosyncratic productivity shocks to arrive stochastically, with sufficiently adverse draws triggering separation. The exogenous destruction model emerges as a special case.

The full flow structure of the labor market can now be summarized. Workers transition from unemployment to employment at rate \(f(\theta)\), and from employment to unemployment at rate \(s\). The dynamics of the unemployment rate are governed by these two rates, which we analyze in the next section.

Equilibrium Unemployment and the Beveridge Curve#

The Steady-State Unemployment Rate#

With the matching technology in place, we can now derive the equilibrium unemployment rate as an outcome of the flows into and out of unemployment. At any moment, employed workers lose their jobs at rate \(s\) and enter unemployment; unemployed workers find jobs at rate \(f(\theta)\) and leave unemployment. The net rate of change of unemployment is therefore:

\[\dot{\mathcal{U}} = \underbrace{s(1 - \mathcal{U})}_{\text{inflow}} - \underbrace{f(\theta)\mathcal{U}}_{\text{outflow}}\]

A steady state requires that these flows balance — the unemployment rate is neither rising nor falling, so \(\dot{\mathcal{U}} = 0\):

\[s(1 - \mathcal{U}) = f(\theta)\mathcal{U}\]

Solving for \(\mathcal{U}\) yields the steady-state unemployment rate:

\[\mathcal{U}^* = \frac{s}{s + f(\theta)}\]

This expression is intuitive. Unemployment is higher when the separation rate \(s\) is large — workers lose jobs quickly — and lower when the job-finding rate \(f(\theta)\) is large — workers find jobs quickly. Crucially, \(\mathcal{U}^*\) depends on \(\theta\) only through \(f(\theta)\) so that market tightness affects unemployment entirely through its effect on the speed at which unemployed workers are matched to vacancies.

Two limiting cases clarify the logic. As \(s \to 0\), job destruction vanishes and \(\mathcal{U}^* \to 0\). Without separations, the unemployment pool drains completely. As \(f(\theta) \to 0\), matching becomes impossible and \(\mathcal{U}^* \to 1\). Without matches, everyone eventually loses their job and no one finds a new one. The steady-state rate lies strictly between these extremes for any positive finite values of \(s\) and \(f(\theta)\).

A useful metaphor for the dynamics of unemployment is a bathtub. Imagine the unemployment rate as the water level in a bathtub:

  • Workers who lose their jobs are the inflow — water entering through the tap, raising the water level.

  • Workers who find jobs are the outflow — water draining through the plug, lowering the water level.

  • The steady-state unemployment rate is the equilibrium water level at which inflows and outflows exactly balance.

When the economy is disturbed — say, by a recession that raises \(s\) — the tap opens wider and the water level rises above its steady-state value. The higher water level itself accelerates the outflow (more unemployed workers means more matches at a given \(\theta\)), so the system is self-correcting and converges back to a new steady state.

This metaphor also clarifies the temporal pattern of unemployment during a recession, which is well illustrated by the figure below. Job losses — as measured by initial unemployment claims — tend to peak early in a recession: the tap opens suddenly. Unemployment itself peaks later, as the bathtub fills. The average duration of unemployment peaks later still, as the pool of unemployed is increasingly composed of workers who have been searching for a long time without success.

The temporal pattern of labor market variables during a recession illustrates the bathtub logic: initial claims (inflows) peak first, aggregate unemployment peaks second, and average unemployment duration peaks last.

In the figure below, we plot the unemployment dynamics following one-time shock to the separation rate. The left panel shows the dynamic path of the unemployment rate following each shock, with dashed horizontal lines marking the new steady states. Two features are worth noting. First, convergence is monotone — there is no overshooting — because the law of motion \(\dot{\mathcal{U}} = s(1-\mathcal{U}) - f(\theta)\mathcal{U}\) is linear in \(\mathcal{U}\) for fixed \(\theta\), so the system behaves like a stable first-order linear ODE. Second, the speed of convergence is governed by \(s + f(\theta)\). Faster churning — high \(s\) and high \(f(\theta)\) — means the pool of unemployed workers turns over more rapidly, so the system reaches its new steady state more quickly.

The right panel shows the phase diagram. The crossing point of each curve with the horizontal axis is the steady-state unemployment rate, and the negative slope everywhere confirms global stability: above the steady state, \(\dot{\mathcal{U}} < 0\) and unemployment falls; below it, \(\dot{\mathcal{U}} > 0\) and unemployment rises.

Hide code cell source

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp

# ──────────────────────────────────────────────
# Baseline parameters
# ──────────────────────────────────────────────
A      = 1.0
beta   = 0.5
theta  = 1.0
s_base = 0.03
f_theta = A * theta**beta    # job-finding rate (fixed)

# Start at baseline steady state
U0 = s_base / (s_base + f_theta)

def dU_dt(t, U, s, f):
    return s * (1 - U) - f * U

scenarios = {
    "Baseline"                       : s_base,
    r"Higher separation ($s$ +50%)"  : s_base * 1.5,
    r"Lower separation ($s$ $-$50%)" : s_base * 0.5,
}

colors = ["#888888", "#d7191c", "#2c7bb6"]

# ──────────────────────────────────────────────
# (1) Shorten time window to focus on transition
#     Convergence rate = s + f(θ); half-life ≈ ln2 / (s + f)
#     With s=0.03 and f=1.0, half-life ≈ 0.67 months → 95% in ~3 months
#     Use 18 months to show the full transition without excess flatness
# ──────────────────────────────────────────────
t_span = (0, 18)
t_eval = np.linspace(*t_span, 500)

# ──────────────────────────────────────────────
# (2) Phase diagram: restrict x-axis to a tight
#     window around the steady states so the
#     zero-crossings are well separated and visible
# ──────────────────────────────────────────────
ss_vals = {label: s / (s + f_theta)
           for label, s in scenarios.items()}
U_min_plot = min(ss_vals.values()) * 0.3   # 30% below lowest SS
U_max_plot = max(ss_vals.values()) * 1.8   # 80% above highest SS
U_phase = np.linspace(U_min_plot, U_max_plot, 300)

fig, axes = plt.subplots(1, 2, figsize=(13, 5))

for (label, s), color in zip(scenarios.items(), colors):
    # ── Time path ──
    sol = solve_ivp(dU_dt, t_span, [U0], args=(s, f_theta),
                    t_eval=t_eval, method="RK45")
    U_path = sol.y[0]
    U_ss   = s / (s + f_theta)

    axes[0].plot(t_eval, U_path * 100, color=color, lw=2, label=label)
    axes[0].axhline(U_ss * 100, color=color, lw=1,
                    linestyle="--", alpha=0.7)

    # ── Phase diagram (zoomed) ──
    dU = dU_dt(0, U_phase, s, f_theta)
    axes[1].plot(U_phase * 100, dU * 100, color=color, lw=2, label=label)
    # Mark zero-crossing
    axes[1].axvline(U_ss * 100, color=color, lw=1,
                    linestyle="--", alpha=0.5)
    axes[1].scatter([U_ss * 100], [0], color=color, zorder=5, s=50)

axes[1].axhline(0, color="black", lw=0.8)

# ── Stability arrows on phase diagram ──
# Show that dU/dt > 0 left of each SS and < 0 right of it
for (label, s), color in zip(scenarios.items(), colors):
    U_ss = s / (s + f_theta)

# ── Formatting ──
axes[0].set_title("Unemployment Rate over Time", fontsize=13)
axes[0].set_xlabel("Months", fontsize=12)
axes[0].set_ylabel("Unemployment Rate (%)", fontsize=12)
axes[0].legend(fontsize=10)
axes[0].set_xlim(0, t_span[1])
axes[0].set_ylim(0, None)

# Annotate half-life on time-path panel
hl = np.log(2) / (s_base + f_theta)
axes[0].axvline(hl, color="gray", lw=0.8, ls=":", alpha=0.7)
axes[0].text(hl + 0.2, 0.5,
             rf"Half-life $\approx {hl:.2f}$ months",
             fontsize=8, color="gray")

axes[1].set_title(r"Phase Diagram: $\dot{\mathcal{U}}$ vs $\mathcal{U}$", fontsize=12)
axes[1].set_xlabel("Unemployment Rate (%)", fontsize=12)
axes[1].set_ylabel(r"$\dot{\mathcal{U}}$", fontsize=12)
axes[1].legend(fontsize=10)
axes[1].set_xlim(U_min_plot * 100, U_max_plot * 100)

fig.suptitle("Dynamics of Unemployment", fontsize=13, y=1.02)
plt.tight_layout()
plt.show()
_images/131143f1576615333cece2f43593c117ece1dcb9061ab9aa26a8bda6ed3e36a0.png

The Half-Life of Unemployment Convergence

The speed at which unemployment converges to its steady state can be characterized analytically. The law of motion \(\dot{\mathcal{U}} = s(1 - \mathcal{U}) - f(\theta)\mathcal{U}\) is a linear first-order ODE in \(\mathcal{U}\). Rearranging:

\[\dot{\mathcal{U}} = s - [s + f(\theta)]\mathcal{U}\]

This has the form \(\dot{y} = a - by\) with \(b = s + f(\theta) > 0\), whose solution is:

\[\mathcal{U}(t) = \mathcal{U}^* + (\mathcal{U}_0 - \mathcal{U}^*)e^{-[s + f(\theta)]t}\]

where \(\mathcal{U}^* = s/(s + f(\theta))\) is the steady state and \(\mathcal{U}_0\) is the initial unemployment rate. The gap between the current unemployment rate and its steady state decays exponentially at rate \(s + f(\theta)\).

The half-life is the time required for the gap \(|\mathcal{U}(t) - \mathcal{U}^*|\) to shrink by half. Setting \(e^{-[s+f(\theta)]t_{1/2}} = 1/2\) and solving:

\[t_{1/2} = \frac{\ln 2}{s + f(\theta)}\]

With the baseline parameters \(s = 0.03\) and \(f(\theta) = A\theta^\beta = 1.0\), the half-life is:

\[t_{1/2} = \frac{\ln 2}{0.03 + 1.0} \approx 0.67 \text{ months}\]

Interpretation. The half-life of less than one month means that unemployment converges to its new steady state very rapidly following a shock. This has two important implications:

  • For empirical work: the steady-state approximation \(\mathcal{U}^* = s/(s+f(\theta))\) is a good description of observed unemployment at monthly or quarterly frequencies, since the economy spends little time away from steady state. This justifies much of the comparative statics analysis in this chapter.

  • For business cycle analysis: the rapid convergence also means that persistent unemployment fluctuations over the business cycle cannot be explained by slow convergence to a fixed steady state. Instead, they must reflect persistent changes in the underlying parameters — shifts in \(s\), \(f(\theta)\), or both — which is precisely what empirical work of documents.

The convergence rate \(s + f(\theta)\) is itself informative. It equals the total churning rate of the labor market — the sum of the rate at which workers lose jobs and the rate at which they find them. A labor market with high churning (high \(s\) and high \(f\)) converges quickly because the pool of unemployed workers turns over rapidly, replacing the current stock with a new draw from the steady-state distribution. A market with low churning (low \(s\) and low \(f\), as in many European labor markets) converges slowly — unemployment dynamics are more persistent and the steady-state approximation is less accurate at short horizons.

Finally, note that the half-life depends on \(\theta\) through \(f(\theta) = A\theta^\beta\): tighter markets have faster job-finding rates and therefore shorter half-lives. This means that the speed of convergence is itself an endogenous outcome of the model — recessions, which reduce \(\theta\) and lower \(f(\theta)\), not only raise the steady-state unemployment rate but also slow the rate at which the economy returns to it.

The Beveridge Curve#

The steady-state unemployment rate \(\mathcal{U}^* = s/(s + f(\theta))\) implies an equilibrium relationship between unemployment and vacancies that is one of the most studied empirical regularities in labor economics. To see it, note that \(f(\theta) = \theta q(\theta)\) and that vacancies are \(\mathcal{V} = \theta\mathcal{U}\). Substituting into the steady-state condition and holding \(s\) and the matching technology fixed, we obtain a locus of \((\mathcal{U}, \mathcal{V})\) pairs consistent with steady state which is called the Beveridge curve:

\[\mathcal{V} = \mathcal{U}\cdot f^{-1}\!\left(\frac{s(1-\mathcal{U})}{\mathcal{U}}\right)\]

More directly, for the Cobb-Douglas specification, the Beveridge curve takes the explicit form :

\[\mathcal{V} = \left[\frac{s(1-\mathcal{U})}{A\mathcal{U}^{1-\beta}}\right]^{1/\beta}\]

The Beveridge curve traces all steady-state combinations of vacancies and unemployment for given \(s\) and \(A\). It is downward-sloping since a higher vacancy rate, holding the matching technology and separation rate fixed, implies a higher job-finding rate and therefore lower steady-state unemployment.

The theoretical Beveridge curve: the locus of steady-state $(u, v)$ pairs consistent with balanced flows into and out of unemployment. The curve is downward-sloping and convex. Movements along the curve reflect changes in market tightness $\theta$; shifts of the curve reflect changes in the separation rate $s$ or matching efficiency $A$.

Two types of labor market changes have distinct geometric interpretations in the \((\mathcal{U}, \mathcal{V})\) plane:

  • Movements along the curve reflect changes in market tightness \(\theta\). A boom raises \(\theta\) — more vacancies relative to searchers — moving the economy up and to the left along the curve toward lower unemployment and higher vacancies. A recession moves the economy down and to the right.

  • Shifts of the curve reflect changes in structural parameters. An increase in the separation rate \(s\) or a decrease in matching efficiency \(A\) shifts the curve outward — for any given vacancy rate, steady-state unemployment is higher. This outward shift is the signature of a deterioration in labor market structure, as distinct from a cyclical downturn.

The empirical Beveridge curve for the United States. Cyclical fluctuations trace out movements along a stable curve; structural shifts — most visibly following the 2008 financial crisis and the COVID-19 pandemic — are reflected in outward movements of the curve itself.

An Empirical Digression: Ahn and Crane on the Dynamic Beveridge Curve#

The theoretical Beveridge curve derived above assumes a steady-state economy in which the separation rate \(s\), matching efficiency \(A\), and tightness \(\theta\) are all constant. In practice, the economy is never in steady state, these parameters vary over time, and identifying the structural curve from data requires carefully disentangling cyclical movements along the curve from structural shifts of the curve. A recent paper by Ahn and Crane — Dynamic Beveridge Curve Accounting — develops a systematic framework for doing so. We walk through their approach here, as it provides a clean bridge between the theory and its empirical implementation.

The Dynamic Framework#

Ahn and Crane adopt a discrete-time version of our model. The flow of new hires in month \(t\) is given by a Cobb-Douglas matching function:

\[\mathcal{M}_t = A_t \mathcal{U}_t^{1-\beta}\mathcal{V}_t^{\beta}\]

where \(A_t\) is allowed to vary over time, capturing shifts in matching efficiency. The implied job-finding probability is:

\[f_t = \frac{\mathcal{M}_t}{\mathcal{U}_t} = A_t\theta_t^{\beta}\]

The discrete-time law of motion for unemployment is:

\[\mathcal{U}_{t+1} - \mathcal{U}_t = s_t(1 - \mathcal{U}_t) - f_t\mathcal{U}_t\]

Substituting the job-finding rate and solving for vacancies yields an expression for the dynamic Beveridge curve — the vacancy rate consistent with observed unemployment dynamics at each point in time:

\[\mathcal{V}_t = \left[\frac{s_t(1-\mathcal{U}_t) - \Delta\mathcal{U}_{t+1}} {A_t\mathcal{U}_t^{1-\beta}}\right]^{1/\beta}\]

where \(\Delta\mathcal{U}_{t+1} = \mathcal{U}_{t+1} - \mathcal{U}_t\). The key difference from the steady-state curve is the presence of \(\Delta\mathcal{U}_{t+1}\): when unemployment is rising, the economy lies to the right of its steady-state curve; when unemployment is falling, it lies to the left. The steady-state Beveridge curve is the special case \(\Delta\mathcal{U}_{t+1} = 0\).

Measurement#

The empirical implementation requires data and parameter choices for \(A_t\), \(s_t\), and \(\beta\). Ahn and Crane proceed as follows:

Data. Unemployment and vacancy rates are obtained from the Current Population Survey and the Job Openings and Labor Turnover Survey (JOLTS) respectively.

Job-finding probability. Rather than inferring \(f_t\) from the matching function, Ahn and Crane measure it directly from the short-term unemployment data:

\[f_t = 1 - \frac{\text{Unemployed for more than one month}_{t+1}}{\text{Unemployed}_t}\]

This measures the fraction of unemployed workers in month \(t\) who are no longer short-term unemployed in month \(t+1\) — a direct proxy for the monthly job-finding rate.

Separation rate. Given \(f_t\) and the observed unemployment series, \(s_t\) is chosen to satisfy the law of motion for unemployment exactly in each period.

Estimated monthly job-finding and separation probabilities for the United States. Both series are highly cyclical, with the job-finding rate falling sharply and the separation rate rising sharply during recessions.

Matching function estimation. It remains to estimate \(A\) and \(\beta\). Taking logs of the job-finding rate expression gives a linear regression:

\[\ln f_t = \ln A + \beta\ln\theta_t + \varepsilon_t\]

which can be estimated by OLS using the observed series on \(f_t\) and \(\theta_t = \mathcal{V}_t/\mathcal{U}_t\).

OLS estimation of the log-linear matching function. The positive slope confirms that the job-finding rate is increasing in market tightness, consistent with the theoretical prediction $f(\theta) = A\theta^\beta$.
Robustness checks on the matching function estimates. The estimated elasticity $\beta$ is stable across specifications and sample periods.

Findings#

With \(A_t\), \(s_t\), and \(\beta\) in hand, Ahn and Crane decompose movements in the Beveridge curve into contributions from three sources: changes in matching efficiency \(A_t\), changes in the separation rate \(s_t\), and out-of-steady-state dynamics captured by \(\Delta\mathcal{U}_{t+1}\). Their main findings are:

  • Matching efficiency declined substantially during and after the 2008 financial crisis, accounting for much of the outward shift in the Beveridge curve observed in that period — consistent with the interpretation that structural mismatch increased.

  • Separation rate fluctuations are the primary driver of cyclical movements in unemployment at business cycle frequencies, with the job-finding rate playing a secondary but significant role.

  • Out-of-steady-state dynamics are quantitatively important at high frequencies: the economy is rarely in steady state, and treating it as such can substantially distort estimates of structural parameters.

These findings underscore the value of the dynamic framework relative to the static Beveridge curve. The same observed \((\mathcal{U}, \mathcal{V})\) combination can reflect very different underlying structural conditions depending on whether the economy is converging to or diverging from steady state. With this empirical grounding established, we return to the theoretical model.

Job Creation#

The Firm’s Problem#

We now turn to the supply side of the labor market - the decision of firms to create jobs and the conditions under which they find it profitable to do so. A firm can be in one of two states: it either has a filled job and is producing, or it has a vacant job and is searching for a worker. We model the firm’s problem using the asset pricing framework that is standard in the search and matching literature — treating the value of a job in each state as the price of an asset that pays a flow return and is subject to stochastic transitions between states.

We maintain the following assumptions throughout:

  • Firms are small and employ at most one worker.

  • Hours of work are fixed and normalized to one.

  • A filled job produces output \(x\) per unit time, sold in a competitive market at price one, so \(x\) is both output and revenue.

  • Posting a vacancy requires a flow cost \(\gamma > 0\) per unit time — advertising, screening, and other recruiting expenditures.

  • There is free entry: any firm may open a vacancy at any time at cost \(\gamma\).

Bellman Equations for the Firm#

Let \(J_\pi\) denote the present discounted value of expected profits from a filled job, and \(J_v\) the present discounted value of expected profits from a vacant job. In steady state, both values are constant — there are no capital gains or losses from expected changes in valuation.

Filled job. A filled job generates flow profit \(x - w\) per unit time, where \(w\) is the wage. It is destroyed at Poisson rate \(s\), at which point the firm transitions to the vacancy state. The steady-state Bellman equation is:

\[rJ_\pi = x - w + s(J_v - J_\pi) \tag{1}\]

The left-hand side is the flow return required by an investor holding an asset worth \(J_\pi\) — the opportunity cost of capital. The right-hand side is the flow payoff: current profit \(x - w\) plus the expected capital loss \(s(J_v - J_\pi)\) from job destruction, which occurs at rate \(s\) and causes the firm’s value to drop from \(J_\pi\) to \(J_v\).

Vacant job. A vacancy generates flow profit \(-\gamma\) per unit time — the recruiting cost. It transitions to a filled job at Poisson rate \(q(\theta)\), at which point the firm’s value rises from \(J_v\) to \(J_\pi\). The steady-state Bellman equation is:

\[rJ_v = -\gamma + q(\theta)(J_\pi - J_v) \tag{2}\]

Derivation of the Bellman Equation

We derive equation (1). Consider a filled job as an asset. Over a small interval \(dt\), it pays flow income \((x - w)dt\) and is destroyed with probability \(s\,dt\). The value of the asset at time \(t\) satisfies:

\[J_\pi(t) = \frac{1}{1 + r\,dt}\left\{(x - w)dt + s\,dt\cdot J_v(t+dt) + (1 - s\,dt)\cdot J_\pi(t+dt)\right\}\]

Multiplying both sides by \((1 + r\,dt)\) and rearranging:

\[r J_\pi(t)\,dt = (x-w)dt + s\,dt\left(J_v(t+dt) - J_\pi(t+dt)\right) + J_\pi(t+dt) - J_\pi(t)\]

Dividing by \(dt\) and taking \(dt \to 0\):

\[rJ_\pi(t) = x - w + s(J_v(t) - J_\pi(t)) + \dot{J}_\pi(t)\]

In steady state \(\dot{J}_\pi = 0\), which delivers equation (1). An identical argument applied to a vacant job delivers equation (2).

Free Entry and the Job Creation Condition#

Free entry into the labor market implies that, in equilibrium, the expected value of opening a vacancy must equal zero. If \(J_v > 0\), firms would find it profitable to open additional vacancies, driving up \(\theta\) until \(J_v\) is pushed back to zero; if \(J_v < 0\), firms would close vacancies, reducing \(\theta\) until \(J_v\) recovers to zero. The free entry condition is therefore:

\[J_v = 0 \tag{3}\]

Substituting \(J_v = 0\) into equation (2) and solving for \(J_\pi\):

\[J_\pi = \frac{\gamma}{q(\theta)} \tag{4}\]

This expression has a natural interpretation: the value of a filled job equals the expected recruiting cost. The right-hand side is the flow cost \(\gamma\) divided by the rate at which vacancies are filled \(q(\theta)\), which equals the expected total cost of filling a vacancy — the flow cost paid during the expected duration \(1/q(\theta)\) of the recruiting process. In equilibrium, firms create vacancies up to the point where the value of a filled job exactly covers these expected hiring costs.

Substituting \(J_v = 0\) into the Bellman equation for a filled job (equation 1) and solving for \(J_\pi\):

\[J_\pi = \frac{x - w}{r + s} \tag{5}\]

The value of a filled job is the present discounted value of the flow profit \(x - w\), discounted at rate \(r + s\) — the sum of the time discount rate and the job destruction rate, since the filled job faces two reasons to be terminated: time preference and separation shocks.

Equating equations (4) and (5) delivers the job creation condition:

\[\frac{x - w}{r + s} = \frac{\gamma}{q(\theta)} \tag{6}\]

The left-hand side is the value of a filled job — the present discounted profit from employing a worker. The right-hand side is the expected cost of recruiting a worker. In equilibrium, firms post vacancies until these two are equalized. For a given wage \(w\), equation (6) determines a unique equilibrium level of market tightness \(\theta^*\).

Why the Job Creation Condition Is an Equilibrium Condition

It is worth pausing to understand why equation (6) pins down a unique equilibrium \(\theta^*\) and why the system is stable. Substituting equation (5) into equation (2) gives the value of a vacancy for any level of market tightness — in and out of equilibrium:

\[rJ_v(\theta) = \frac{q(\theta)}{r + s + q(\theta)}(x - w) - \frac{r + s}{r + s + q(\theta)}\gamma\]

The term \(q(\theta)/(r + s + q(\theta))\) varies monotonically from 0 to 1 as \(\theta\) varies from \(\infty\) to 0, so the value of a vacancy is strictly decreasing in \(\theta\). The two boundary cases clarify the economics:

- As $\theta \to 0$: vacancies are filled instantly ($q(\theta) \to \infty$), so a firm hiring a worker begins earning  profits $x - w$ immediately and in perpetuity. The value of a vacancy approaches $(x-w)/r > 0$ — the present value of a  permanent profit stream.
- As $\theta \to \infty$: vacancies are never filled ($q(\theta) \to 0$), so a firm   perpetually incurs recruiting costs without ever producing. The value of a vacancy approaches $-\gamma/r < 0$.

Since \(J_v(\theta)\) is continuous and strictly decreasing, crossing from positive to negative as \(\theta\) rises from 0 to \(\infty\), there exists a unique \(\theta^*\) at which \(J_v(\theta^*) = 0\). The equilibrium is stable: if \(\theta > \theta^*\) then \(J_v < 0\) and firms close vacancies, reducing \(\theta\) back toward \(\theta^*\); if \(\theta < \theta^*\) then \(J_v > 0\) and firms open new vacancies, raising \(\theta\) back toward \(\theta^*\).

Equilibrium with an Exogenous Wage#

Before introducing endogenous wage determination in the next section, it is instructive to characterize the equilibrium taking the wage \(w\) as given. In this case, the model consists of two equations in two unknowns:

  • The job creation condition (6) determines equilibrium market tightness \(\theta^*\) for a given wage.

  • The Beveridge curve \(\mathcal{U}^* = s/(s + f(\theta^*))\) then determines equilibrium unemployment for the resulting \(\theta^*\).

Equilibrium with an exogenous wage. The job creation condition determines market tightness $\theta^*$ (left panel); the Beveridge curve maps $\theta^*$ into equilibrium unemployment $\mathcal{U}^*$ (right panel). A higher wage shifts the job creation condition inward, reducing $\theta^*$ and raising $\mathcal{U}^*$.

The comparative statics are straightforward. A higher wage \(w\) reduces the profit from a filled job \((x - w)/(r + s)\), so firms post fewer vacancies, \(\theta\) falls, the job-finding rate \(f(\theta)\) falls, and equilibrium unemployment rises. A higher productivity \(x\) has the opposite effect. These observations motivate the need for an endogenous wage: to close the model, we need a theory of how \(w\) is determined — and in particular, how it responds to changes in \(x\), \(\theta\), and labor market conditions more broadly. This is the subject of the next section.

A Numerical Illustration of the Job Creation Condition#

The job creation condition (6) defines an implicit relationship between the wage \(w\) and market tightness \(\theta\): for each wage, there is at most one value of \(\theta\) consistent with firm optimization and free entry. The following code plots this relationship for several parameter configurations, illustrating how changes in productivity, recruiting costs, and the discount rate shift the equilibrium.

Hide code cell source

import numpy as np
import matplotlib.pyplot as plt

# ──────────────────────────────────────────────
# Parameters
# Calibrated so that recruiting costs (r+s)*gamma/q(theta)
# are a meaningful fraction of output x, producing visible
# slope in the JC locus across the theta grid.
#
# Key change from previous version: gamma raised to 0.8*x
# and s raised to 0.10 (monthly ~1%, plausible annual rate)
# so the term (r+s)*gamma/q(theta) varies substantially
# with theta and produces a clearly downward-sloping locus.
# ──────────────────────────────────────────────
A      = 1.0     # matching efficiency
beta   = 0.5     # vacancy elasticity
r      = 0.012   # monthly discount rate (~15% annual, impatient firms)
s      = 0.10    # monthly separation rate (job lasts ~10 months on avg)
x_base = 1.0     # baseline productivity
gamma_base = 0.8 # baseline vacancy cost (80% of one unit of output)

theta = np.linspace(0.05, 4, 500)

# JC locus: w = x - (r+s)*gamma / q(theta)
#           q(theta) = A * theta^{-(1-beta)}
def w_jc(theta, x, r, s, gamma, A, beta):
    q = A * theta ** (-(1 - beta))
    return x - (r + s) * gamma / q

# ──────────────────────────────────────────────
# Plot: three panels varying x, gamma, r
# ──────────────────────────────────────────────
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
colors = ["#2c7bb6", "#888888", "#d7191c"]

# ── Panel 1: vary productivity x ──
x_vals  = [0.7, 1.0, 1.3]
for x, color in zip(x_vals, colors):
    w = w_jc(theta, x, r, s, gamma_base, A, beta)
    axes[0].plot(theta, w, color=color, lw=2, label=rf"$x = {x}$")

# Reference line at w = z (floor below which no match forms)
axes[0].axhline(0.4, color="gray", lw=1, ls=":", alpha=0.8)
axes[0].text(3.5, 0.42, r"$w = z$", fontsize=9, color="gray")
axes[0].set_title("Varying Productivity $x$", fontsize=12)

# ── Panel 2: vary vacancy cost gamma ──
gamma_vals = [0.4, 0.8, 1.2]
for g, color in zip(gamma_vals, colors):
    w = w_jc(theta, x_base, r, s, g, A, beta)
    axes[1].plot(theta, w, color=color, lw=2, label=rf"$\gamma = {g}$")

axes[1].axhline(0.4, color="gray", lw=1, ls=":", alpha=0.8)
axes[1].text(3.5, 0.42, r"$w = z$", fontsize=9, color="gray")
axes[1].set_title(r"Varying Vacancy Cost $\gamma$", fontsize=12)

# ── Panel 3: vary discount rate r ──
r_vals  = [0.004, 0.012, 0.024]
r_labels = ["0.004", "0.012", "0.024"]
for rv, rl, color in zip(r_vals, r_labels, colors):
    w = w_jc(theta, x_base, rv, s, gamma_base, A, beta)
    axes[2].plot(theta, w, color=color, lw=2, label=rf"$r = {rl}$")

axes[2].axhline(0.4, color="gray", lw=1, ls=":", alpha=0.8)
axes[2].text(3.5, 0.42, r"$w = z$", fontsize=9, color="gray")
axes[2].set_title("Varying Discount Rate $r$", fontsize=12)

# ── Shared formatting ──
for ax in axes:
    ax.set_xlabel(r"Market Tightness $\theta$", fontsize=11)
    ax.set_ylabel(r"Maximum wage consistent with JC", fontsize=10)
    ax.set_xlim(theta[0], theta[-1])
    ax.legend(fontsize=10)
    # Let y-axis scale to the data so the slope is visible
    ax.autoscale(axis="y")
    ax.margins(y=0.1)

    # Annotate the slope at theta=1 to make the relationship explicit
    theta_annot = 1.0
    idx = np.argmin(np.abs(theta - theta_annot))



fig.suptitle(
    "Job Creation Condition\n",
    fontsize=13, y=1.04)
plt.tight_layout()
plt.show()
_images/09cbf086c08394417b52f46018c980440545552382e95b55ff41b505ad24b02a.png

Each panel plots the wage \(w\) that satisfies the job creation condition for a given level of market tightness \(\theta\) — equivalently, the maximum wage firms are willing to pay for each value of \(\theta\). The relationship is downward-sloping: higher tightness means vacancies take longer to fill, raising expected recruiting costs and leaving less room for wages. Three comparative statics are immediately visible:

  • Higher productivity \(x\) shifts the entire locus upward: at every \(\theta\), firms can afford to pay a higher wage while still covering their recruiting costs.

  • Higher vacancy costs \(\gamma\) shift the locus downward: recruiting is more expensive, so firms can afford to pay less.

  • Higher discount rate \(r\) shifts the locus downward: firms discount future profits more heavily, reducing the value of a filled job and therefore the wage they are willing to pay.

When we add the wage determination equation in the next section, equilibrium will be at the intersection of this downward-sloping job creation locus and the upward-sloping wage rule — a system whose geometry will make the comparative statics of the full model transparent.

Wage Determination#

Workers and Their Outside Option#

To close the model, we need a theory of wage determination. The neoclassical approach — wages equate labor supply and demand — is unavailable here: the matching frictions that generate unemployment also mean that there is no market clearing price for labor. Instead, when a worker and a firm meet, they find themselves in a bilateral relationship. The filled job generates a surplus — the total value created by their match exceeds what either party could obtain by searching for an alternative — and the wage is the outcome of a negotiation over how to divide that surplus.

Before analyzing the negotiation, we need to characterize the worker’s side of the market. We assume:

  • All workers are either employed or unemployed — no one is out of the labor force.

  • All workers have the same productivity \(x\) when employed.

  • An employed worker earns wage \(w\) per unit time.

  • An unemployed worker receives flow income \(z\) per unit time, which captures all non-employment income: unemployment insurance benefits, the value of home production, and the utility of leisure. We treat \(z\) as a parameter for now.

Bellman Equations for Workers#

Let \(W_n\) denote the present discounted value of expected income to an employed worker, and \(W_u\) the present discounted value of expected income to an unemployed worker. The steady-state Bellman equations are:

\[rW_n = w + s(W_u - W_n) \tag{7}\]
\[rW_u = z + f(\theta)(W_n - W_u) \tag{8}\]

Equation (7) says that the flow return to employment equals the wage \(w\) plus the expected capital loss \(s(W_u - W_n)\) from job destruction, which occurs at rate \(s\) and reduces the worker’s value from \(W_n\) to \(W_u\). Equation (8) says that the flow return to unemployment equals non-employment income \(z\) plus the expected capital gain \(f(\theta)(W_n - W_u)\) from finding a job, which occurs at rate \(f(\theta)\) and raises the worker’s value from \(W_u\) to \(W_n\).

Two observations follow immediately. First, the quantity \(rW_u\) — the flow value of being unemployed — is the worker’s reservation wage: the minimum compensation required to accept a job. A wage offer \(w < rW_u\) leaves the worker worse off than remaining unemployed, and will be rejected. Second, a worker prefers employment to unemployment if and only if \(W_n \geq W_u\), which requires \(w \geq z\): the wage must at least compensate for the foregone non-employment income. We assume \(w > z\) throughout,so that employment is always preferred to unemployment and no worker voluntarily quits.

The Bilateral Surplus#

A match between a worker and a firm generates value that exceeds the sum of what each party could obtain by remaining unmatched. The bilateral surplus of a match is:

\[S \equiv (W_n - W_u) + (J_\pi - J_v)\]

The first term is the worker’s gain from being employed rather than unemployed; the second is the firm’s gain from having a filled job rather than a vacancy. The wage determines how this surplus is divided: a higher wage transfers surplus from the firm to the worker, and vice versa.

For a match to be formed and sustained, the surplus must be strictly positive — both parties must prefer the match to their outside options. Under the free entry condition \(J_v = 0\), the surplus simplifies to \(S = (W_n - W_u) + J_\pi\). Since all workers and firms are identical in this model, the same wage \(w\) applies to all matches, and the surplus is the same across all filled jobs.

Nash Bargaining#

The standard approach to wage determination in the search and matching literature is Nash bargaining, in which the wage maximizes the weighted geometric mean of the worker’s and firm’s surpluses:

\[w = \arg\max_{w}\; (W_n - W_u)^\alpha (J_\pi - J_v)^{1-\alpha} \tag{9}\]

where \(\alpha \in (0,1)\) is the bargaining power of the worker. The parameter \(\alpha\) captures the relative strength of the worker’s negotiating position: \(\alpha\) close to one means workers capture most of the surplus; \(\alpha\) close to zero means firms do.

The threat points in this bargaining problem are \(W_u\) for the worker and \(J_v\) for the firm. If negotiations break down, the worker returns to unemployment and the firm returns to posting a vacancy. The Nash solution therefore captures the idea that the wage is determined by each party’s outside option — what they could obtain in the absence of an agreement.

Derivation of the Surplus-Sharing Rule#

Taking the first-order condition of the Nash product with respect to \(w\):

\[\frac{\alpha}{W_n - W_u}\frac{\partial W_n}{\partial w} + \frac{1-\alpha}{J_\pi - J_v}\frac{\partial J_\pi}{\partial w} = 0\]

From the Bellman equations, raising \(w\) by one unit raises \(W_n\) by \(1/(r+s)\) and reduces \(J_\pi\) by \(1/(r+s)\), so \(\partial W_n/\partial w = -\partial J_\pi/\partial w = 1/(r+s)\). Substituting:

\[\frac{\alpha}{W_n - W_u} = \frac{1-\alpha}{J_\pi - J_v}\]

Rearranging yields the surplus-sharing rule:

\[(1-\alpha)(W_n - W_u) = \alpha(J_\pi - J_v) \tag{10}\]

Equivalently, using \(J_v = 0\) under free entry:

\[W_n - W_u = \alpha(J_\pi + W_n - W_u), \qquad J_\pi = (1-\alpha)(J_\pi + W_n - W_u)\]

The worker receives fraction \(\alpha\) of the total surplus; the firm receives fraction \(1 - \alpha\). This splitting rule is independent of the specific values of outside options — it depends only on the bargaining power parameter \(\alpha\).

The Wage Equation#

To obtain an explicit expression for the wage, we substitute the Bellman equations and the free entry condition into the surplus-sharing rule.

From the Bellman equation for an employed worker (7), solving for \(W_n\):

\[W_n = \frac{w + sW_u}{r + s}\]

Substituting into \((W_n - W_u)\) and simplifying:

\[W_n - W_u = \frac{w - rW_u}{r + s}\]

From the surplus-sharing rule (10) with \(J_v = 0\):

\[(1-\alpha)\frac{w - rW_u}{r+s} = \alpha J_\pi = \frac{\alpha\gamma}{q(\theta)}\]

where the last equality uses the free entry condition (4). Solving for \(w\):

\[w = rW_u + \frac{\alpha(r+s)\gamma}{(1-\alpha)q(\theta)}\]

This says the wage equals the worker’s reservation wage \(rW_u\) plus a share of the match surplus. To find \(rW_u\) explicitly, substitute the Bellman equation for an unemployed worker (8) using the surplus-sharing rule to express \(f(\theta)(W_n - W_u)\) in terms of \(J_\pi\):

\[rW_u = z + f(\theta)(W_n - W_u) = z + \frac{\alpha}{1-\alpha}\gamma\theta\]

where we used \(f(\theta) = \theta q(\theta)\) and the expression for \((W_n - W_u)\) derived above. Substituting back:

\[\boxed{w = \alpha(x + \gamma\theta) + (1-\alpha)z} \tag{11}\]

This is the wage rule of the model. It admits a clean economic interpretation. The term \(\alpha(x + \gamma\theta)\) is the worker’s share of the joint surplus from production: the firm produces \(x\), and the worker is also compensated for the hiring cost \(\gamma\theta\) that the firm saves by agreeing to the match rather than continuing to search. The term \((1-\alpha)z\) is the firm’s contribution to the wage floor: even if the worker had no bargaining power, the wage would have to compensate them for foregone non-employment income \(z\).

Four properties of the wage rule are worth emphasizing:

  • Productivity: the wage is increasing in \(x\). Workers capture fraction \(\alpha\) of any increase in productivity — the remainder accrues to the firm as higher profit.- Market tightness: the wage is increasing in \(\theta\). A tighter labor market strengthens workers’ bargaining position — their outside option (finding another job quickly) improves — so they can negotiate a higher wage. This gives the wage rule an upward slope in \((\theta, w)\) space.

  • Non-employment income: the wage is increasing in \(z\). A higher outside option for workers raises the reservation wage and therefore the negotiated wage.

  • Bargaining power: a higher \(\alpha\) raises the wage, as workers capture a larger share of the surplus.

The wage rule (11): an upward-sloping relationship between the negotiated wage $w$ and market tightness $\theta$. A tighter labor market improves workers' outside options and raises the bargained wage. The intercept $(1-\alpha)z + \alpha x$ is the wage at $\theta = 0$; the slope is $\alpha\gamma$.

Labor Market Equilibrium#

We now have all the ingredients to characterize the full steady-state equilibrium. An equilibrium is a triple \((\mathcal{U}^*, \theta^*, w^*)\) satisfying three conditions simultaneously:

\[\mathcal{U}^* = \frac{s}{s + f(\theta^*)} \tag{BC}\]
\[\frac{x - w^*}{r + s} = \frac{\gamma}{q(\theta^*)} \tag{JC}\]
\[w^* = \alpha(x + \gamma\theta^*) + (1-\alpha)z \tag{WR}\]

The equilibrium is determined sequentially. The job creation condition (JC) and the wage rule (WR) jointly determine \((\theta^*, w^*)\) as the intersection of a downward-sloping and an upward-sloping locus in \((\theta, w)\) space. Given \(\theta^*\), the Beveridge curve (BC) determines \(\mathcal{U}^*\).

Substituting the wage rule into the job creation condition yields an implicit equation for equilibrium market tightness alone:

\[\frac{\gamma}{q(\theta^*)} = \frac{(1-\alpha)(x - z) - \alpha\gamma\theta^*}{r + s} \tag{12}\]

The left-hand side is increasing in \(\theta^*\) (since \(q'(\theta) \leq 0\)); the ight-hand side is decreasing in \(\theta^*\). Existence and uniqueness of \(\theta^*\) ollow provided \((1-\alpha)(x-z) > 0\), which requires \(x > z\) — production must be ore valuable than non-employment, a condition we maintain throughout.

Full steady-state equilibrium. The job creation condition (JC) is downward-sloping in $(\theta, w)$ space; the wage rule (WR) is upward-sloping. Their intersection pins down $(\theta^*, w^*)$. The Beveridge curve (BC) then determines $\mathcal{U}^*$ given $\theta^*$.

A Numerical Illustration#

The following code solves the full equilibrium numerically and plots the JC and WR curves.

Hide code cell source

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import brentq

# ──────────────────────────────────────────────
# Parameters
# ──────────────────────────────────────────────
A      = 1.0
beta   = 0.5
r      = 0.012
s      = 0.10
gamma  = 0.8
x      = 1.0
z      = 0.4
alpha  = 0.5

def q(theta): return A * theta ** (-(1 - beta))
def f(theta): return A * theta ** beta

# ──────────────────────────────────────────────
# JC locus: theta as a function of w
#   theta = [A*(x-w) / (gamma*(r+s))]^{1/(1-beta)}
# ──────────────────────────────────────────────
def theta_from_jc(w, x, r, s, gamma, A, beta):
    val = np.where(np.asarray(x - w) > 0, x - w, np.nan)
    return (A * val / (gamma * (r + s))) ** (1 / (1 - beta))

# ──────────────────────────────────────────────
# WR locus: theta as a function of w
#   theta = (w - alpha*x - (1-alpha)*z) / (alpha*gamma)
# ──────────────────────────────────────────────
def theta_from_wr(w, x, z, alpha, gamma):
    val = np.where(
        np.asarray(w - alpha * x - (1 - alpha) * z) > 0,
        w - alpha * x - (1 - alpha) * z, np.nan)
    return val / (alpha * gamma)

# ──────────────────────────────────────────────
# Beveridge curve: theta as a function of U
#   At steady state: s(1-U) = f(theta)*U = A*theta^beta * U
#   => theta = [s(1-U) / (A*U)]^{1/beta}
# ──────────────────────────────────────────────
def theta_from_bc(U, s, A, beta):
    return (s * (1 - U) / (A * U)) ** (1 / beta)

# ──────────────────────────────────────────────
# Solve equilibrium
# ──────────────────────────────────────────────
w_min_wr = alpha * x + (1 - alpha) * z

def equilibrium_condition(w):
    return (theta_from_jc(w, x, r, s, gamma, A, beta) -
            theta_from_wr(w, x, z, alpha, gamma))

w_star     = brentq(equilibrium_condition, w_min_wr + 0.001, x - 0.001)
theta_star = float(theta_from_wr(w_star, x, z, alpha, gamma))
U_star     = s / (s + f(theta_star))

print(f"Equilibrium wage:              w* = {w_star:.3f}")
print(f"Equilibrium market tightness:  θ* = {theta_star:.3f}")
print(f"Equilibrium unemployment rate: U* = {U_star:.3f}")

# ──────────────────────────────────────────────
# Grids
# ──────────────────────────────────────────────
w_grid = np.linspace(w_min_wr + 0.001, x - 0.001, 500)
U_grid = np.linspace(0.001, 0.60, 500)

theta_jc = theta_from_jc(w_grid, x, r, s, gamma, A, beta)
theta_wr = theta_from_wr(w_grid, x, z, alpha, gamma)
theta_bc = theta_from_bc(U_grid, s, A, beta)

# ──────────────────────────────────────────────
# Determine shared theta axis limits across both panels
# ──────────────────────────────────────────────
theta_max = max(np.nanmax(theta_jc), np.nanmax(theta_bc[U_grid > 0.02]))
theta_max = min(theta_max, theta_star * 3.5)   # cap for readability
theta_min = 0.0

# ──────────────────────────────────────────────
# Plot
# ──────────────────────────────────────────────
fig, axes = plt.subplots(1, 2, figsize=(13, 5), sharey=True)

# ── Panel 1: JC–WR diagram ──
# theta on vertical axis, w on horizontal axis
axes[0].plot(w_grid, theta_jc, color="#2c7bb6", lw=2.5,
             label="Job Creation (JC)")
axes[0].plot(w_grid, theta_wr, color="#d7191c", lw=2.5,
             label="Wage Rule (WR)")


# Project theta* horizontally across to Beveridge curve panel
axes[0].axhline(theta_star, color="gray", lw=1, ls="--", alpha=0.7)
axes[0].axvline(w_star,     color="gray", lw=1, ls="--", alpha=0.7)



axes[0].set_xlabel("Wage $w$", fontsize=12)
axes[0].set_ylabel(r"Market Tightness $\theta$", fontsize=12)
axes[0].set_title("Job Creation and Wage",
                  fontsize=12)
axes[0].legend(fontsize=11, loc="upper right")
axes[0].set_xlim(w_min_wr, x)
axes[0].set_ylim(theta_min, theta_max)

# ── Panel 2: Beveridge curve with theta on vertical axis ──
# theta on vertical axis, U on horizontal axis
# The equilibrium theta* carries directly across from panel 1
axes[1].plot(U_grid * 100, theta_bc, color="#1a9641", lw=2.5,
             label="Beveridge Curve (BC)")

# Project theta* across from panel 1 to read off U*
axes[1].axhline(theta_star, color="gray", lw=1, ls="--", alpha=0.7)
axes[1].axvline(U_star * 100, color="gray", lw=1, ls="--", alpha=0.7)


axes[1].set_xlabel(r"Unemployment Rate $\mathcal{U}$ (%)", fontsize=12)
axes[1].set_ylabel(r"Market Tightness $\theta$", fontsize=12)
axes[1].set_title(r"Beveridge Curve",
                  fontsize=12)
axes[1].legend(fontsize=11)
axes[1].set_xlim(0, 50)

fig.suptitle("Steady-State Equilibrium", fontsize=13, y=1.02)
plt.tight_layout()
plt.show()
Equilibrium wage:              w* = 0.932
Equilibrium market tightness:  θ* = 0.579
Equilibrium unemployment rate: U* = 0.116
_images/55712a04ebf518821e72d6567a0396546ef4d9276734cc21a6a03b92c5edf8f4.png

The two panels share a common \(\theta\) axis so the equilibrium logic reads as a two-step procedure directly from the figure:

  1. Step 1 (left panel): the intersection of JC and WR determines the equilibrium pair \((w^*, \theta^*)\). The dashed horizontal line projects \(\theta^*\) across to the right panel.

  2. Step 2 (right panel): given \(\theta^*\), the Beveridge curve determines \(\mathcal{U}^*\) as the unemployment rate consistent with steady-state flow balance at that level of tightness. The equilibrium lies at the intersection of the horizontal projection from Step 1 with the Beveridge curve.

The Beveridge curve is downward-sloping in \((\mathcal{U}, \theta)\) space — higher tightness corresponds to lower steady-state unemployment — and the slope becomes steeper as \(\mathcal{U} \to 0\). Movements along the curve correspond to cyclical fluctuations: booms move the economy up and to the left (higher \(\theta\), lower \(\mathcal{U}\)); recessions move it down and to the right. Shifts of the curve — outward for higher \(s\) or lower \(A\) — change the unemployment rate associated with any given \(\theta\), and are the signature of structural rather than cyclical deterioration.

Comparative Statics#

Overview#

The steady-state equilibrium is characterized by three conditions — the job creation condition (JC), the wage rule (WR), and the Beveridge curve (BC) — in three unknowns \((\theta^*, w^*, \mathcal{U}^*)\). Having established the geometry of the equilibrium, we now analyze how it responds to changes in the model’s six parameters: productivity \(x\), non-employment income \(z\), the discount rate \(r\), the separation rate \(s\), matching efficiency \(A\), and vacancy posting costs \(\gamma\).

The analysis follows a uniform method throughout. Any parameter change affects the equilibrium through one or both of two channels:

  • A shift in the JC locus — reflecting a change in the value of a filled job or the cost of recruiting.

  • A shift in the WR locus — reflecting a change in the worker’s outside option or bargaining position.

The new equilibrium \((\theta^*, w^*)\) is found at the intersection of the shifted loci. Given \(\theta^*\), the Beveridge curve then determines \(\mathcal{U}^*\). We also note whether the Beveridge curve itself shifts — which occurs whenever \(s\) or \(A\) changes — since this affects the unemployment-vacancy relationship independently of tightness.

Productivity: \(x \uparrow\)#

A rise in productivity \(x\) shifts the JC locus upward — at any given \(\theta\), a filled job is now more valuable so firms are willing to pay a higher wage — and shifts the WR locus upward — workers capture fraction \(\alpha\) of the productivity gain during bargaining. Since the JC locus shifts up by more than the WR locus (the full increase \(\Delta x\) accrues to JC, while only \(\alpha\Delta x < \Delta x\) accrues to WR), the equilibrium shifts to higher \(\theta^*\) and higher \(w^*\).

An increase in productivity $x$ shifts both loci upward, with the JC shift dominating. Equilibrium tightness and wages both rise; unemployment falls.

The economic mechanism runs as follows. Higher productivity raises the value of a filled job, so firms post more vacancies. Because workers capture only fraction \(\alpha < 1\) of the productivity gain in wages, the net profit from a filled job rises and firms find it worthwhile to recruit more aggressively. Higher vacancy posting increases \(\theta\), which raises the job-finding rate \(f(\theta)\) and reduces steady-state unemployment. Higher wages follow from the improved labor market conditions: a tighter market strengthens workers’ bargaining position, reinforcing the direct productivity effect on wages.

Since the Beveridge curve is unaffected by \(x\) (neither \(s\) nor \(A\) changes), the fall in unemployment reflects a movement along the existing curve toward higher \(\theta\).

Non-Employment Income: \(z \uparrow\)#

A rise in non-employment income \(z\) shifts only the WR locus upward — workers’ outside option improves, so they negotiate higher wages at every \(\theta\) — leaving the JC locus unchanged. The intersection shifts to lower \(\theta^*\) and higher \(w^*\).

An increase in non-employment income $z$ shifts the WR locus upward, leaving JC unchanged. Wages rise, tightness falls, and unemployment increases. A higher worker bargaining power $\alpha$ produces qualitatively identical results.

Higher non-employment income raises workers’ reservation wage, forcing firms to pay more. Higher wages erode the value of a filled job, reducing firms’ incentive to post vacancies. Fewer vacancies reduce tightness \(\theta\), which lowers the job-finding rate and raises steady-state unemployment. The result is a movement up and to the right along the Beveridge curve.

Note that this result has direct implications for the design of unemployment insurance. The model predicts that more generous unemployment benefits — a higher \(z\) — raise wages and reduce vacancy creation, leading to higher equilibrium unemployment. This is the standard moral hazard channel in search models: better outside options reduce workers’ urgency to accept job offers and raise firms’ wage costs, both of which contribute to higher unemployment. The model deliberately abstracts from the search effort margin — unemployed workers are assumed to search with equal intensity regardless of \(z\) — so this result reflects only the wage-bargaining channel, not any disincentive effect on search effort. Incorporating variable search effort would strengthen the result.

An increase in worker bargaining power \(\alpha\) produces qualitatively identical effects: it raises the WR locus without affecting JC, leading to higher wages, lower tightness, and higher unemployment.

Discount Rate: \(r \uparrow\)#

A rise in the discount rate \(r\) shifts only the JC locus downward — future profits are discounted more heavily, reducing the value of a filled job and lowering the maximum wage firms are willing to pay at any \(\theta\) — leaving the WR locus unchanged. The intersection shifts to lower \(\theta^*\) and lower \(w^*\).

An increase in the discount rate $r$ shifts the JC locus downward, leaving WR unchanged. Wages and tightness both fall; unemployment rises.

Higher discounting makes firms less willing to bear the upfront recruiting cost \(\gamma\) in exchange for a future profit stream. Vacancy creation falls, tightness declines, and unemployment rises. Wages fall because the deterioration in labor market conditions weakens workers’ bargaining position — a tighter outside option translates directly into a lower negotiated wage.

An important special case is \(r = 0\): with no discounting, workers are indifferent between being employed and unemployed in a present-value sense — both states yield the same lifetime income as long as they eventually find a job. As \(r\) rises above zero, the present cost of unemployment grows, workers become more eager to accept jobs, and their bargaining position weakens — which is why wages fall. This channel is sometimes called the patience effect: less patient workers accept lower wages to avoid the cost of continued unemployment.

Separation Rate: \(s \uparrow\)#

A rise in the separation rate \(s\) shifts only the JC locus downward — a higher destruction rate reduces the expected duration of a match and therefore the value of a filled job — while leaving the WR locus unchanged. The intersection shifts to lower \(\theta^*\) and lower \(w^*\).

An increase in the separation rate $s$ shifts the JC locus downward, leaving WR unchanged. Wages and tightness fall; unemployment rises. The Beveridge curve also shifts outward, making the effect on vacancies ambiguous.

The mechanism is symmetric to the discount rate case: a higher \(s\) reduces the present discounted value of a match to the firm, depressing vacancy creation. The effect on unemployment operates through two channels that reinforce each other. First, the fall in \(\theta\) reduces the job-finding rate, raising unemployment for a given Beveridge curve. Second, the higher separation rate shifts the Beveridge curve itself outward — at any given \(\theta\), more workers are losing jobs per unit time, requiring a higher vacancy rate to maintain the same steady-state unemployment rate. The net effect on vacancies is therefore ambiguous: the decline in \(\theta\) reduces vacancies, but the outward shift of the Beveridge curve raises them. Unemployment, however, unambiguously rises through both channels.

Matching Efficiency: \(A \downarrow\)#

A decrease in matching efficiency \(A\) — reflecting greater mismatch between workers and jobs, whether due to skill mismatches, geographic barriers, or informational frictions — shifts both the JC locus downward and the WR locus downward. The reduction in \(A\) means that for any given \(\theta\), vacancies take longer to fill (\(q(\theta)\) falls) and workers take longer to find jobs (\(f(\theta)\) falls). The former raises expected recruiting costs and shifts JC down; the latter weakens workers’ outside options and shifts WR down. Both effects push toward lower \(w^*\), and the net effect on \(\theta^*\) depends on the relative magnitudes of the two shifts.

A decrease in matching efficiency $A$ shifts both loci downward. Wages fall unambiguously; market tightness and unemployment depend on the relative magnitudes of the shifts. The Beveridge curve shifts outward, raising unemployment for any given $\theta$.

In practice, the standard result is that lower matching efficiency reduces \(\theta\) and raises unemployment — the outward shift of the Beveridge curve dominates, so that for any given vacancy-creation rate, unemployment is higher. This is the structural interpretation of the Beveridge curve shifts documented empirically by Ahn and Crane: periods in which the curve shifts outward are interpreted as episodes of increased mismatch, rather than cyclical downturns that move the economy along a fixed curve.

Vacancy Posting Costs: \(\gamma \uparrow\)#

A rise in vacancy posting costs \(\gamma\) shifts the JC locus downward — higher recruiting costs reduce the net value of a filled job — and shifts the WR locus upward — workers are compensated for the higher hiring costs saved by the match, since the term \(\gamma\theta\) enters the wage rule directly. The two shifts work in opposite directions on wages, making the effect on \(w^*\) ambiguous. Both shifts reduce \(\theta^*\), so market tightness falls unambiguously and unemployment rises.

An increase in vacancy posting costs $\gamma$ shifts JC downward and WR upward. Market tightness falls unambiguously and unemployment rises; the effect on wages is ambiguous depending on which shift dominates.

The intuition is as follows. Higher vacancy costs reduce firms’ incentive to recruit, directly lowering \(\theta\). At the same time, the wage rule reflects the fact that workers are implicitly compensated for the hiring costs they save the firm — when \(\gamma\theta\) is high, workers can negotiate a higher wage because the firm’s alternative (continued search at cost \(\gamma\)) is more expensive. These two forces work in opposite directions on wages: whether wages rise or fall depends on whether the direct effect of lower \(\theta\) on workers’ bargaining position dominates the indirect effect of higher \(\gamma\) on the wage rule intercept.

Numerical Comparative Statics#

The following code computes the full equilibrium numerically for each parameter variation, plots the shifted JC and WR loci, and tabulates the equilibrium responses of \(\theta^*\), \(w^*\), and \(\mathcal{U}^*\).

Hide code cell source

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import brentq

# ──────────────────────────────────────────────
# Baseline parameters
# ──────────────────────────────────────────────
A      = 1.0
beta   = 0.5
r      = 0.012
s      = 0.10
gamma  = 0.8
x      = 1.0
z      = 0.4
alpha  = 0.5

def q(theta): return A * theta ** (-(1 - beta))
def f(theta): return A * theta ** beta

def theta_from_jc(w, x, r, s, gamma, A, beta):
    val = np.where(np.asarray(x - w) > 0, x - w, np.nan)
    return (A * val / (gamma * (r + s))) ** (1 / (1 - beta))

def theta_from_wr(w, x, z, alpha, gamma):
    val = np.where(
        np.asarray(w - alpha * x - (1 - alpha) * z) > 0,
        w - alpha * x - (1 - alpha) * z, np.nan)
    return val / (alpha * gamma)

def solve_equilibrium(x, r, s, gamma, z, alpha, A, beta):
    w_min = alpha * x + (1 - alpha) * z
    w_max = x
    def condition(w):
        t_jc = theta_from_jc(w, x, r, s, gamma, A, beta)
        t_wr = theta_from_wr(w, x, z, alpha, gamma)
        if np.isnan(t_jc) or np.isnan(t_wr):
            return np.nan
        return t_jc - t_wr
    try:
        w_star     = brentq(condition, w_min + 1e-6, w_max - 1e-6)
        theta_star = float(theta_from_wr(w_star, x, z, alpha, gamma))
        U_star     = s / (s + f(theta_star))
        return w_star, theta_star, U_star
    except ValueError:
        return None, None, None

# ──────────────────────────────────────────────
# Experiments
# ──────────────────────────────────────────────
experiments = [
    ("x", r"Productivity $x$", [
        (0.7,  "#2c7bb6", "--", "$x = 0.7$"),
        (1.0,  "#888888", "-",  "$x = 1.0$ (baseline)"),
        (1.3,  "#d7191c", "--", "$x = 1.3$"),
    ]),
    ("z", r"Non-employment Income $z$", [
        (0.2,  "#2c7bb6", "--", "$z = 0.2$"),
        (0.4,  "#888888", "-",  "$z = 0.4$ (baseline)"),
        (0.6,  "#d7191c", "--", "$z = 0.6$"),
    ]),
    ("r", r"Discount Rate $r$", [
        (0.004, "#2c7bb6", "--", "$r = 0.004$"),
        (0.012, "#888888", "-",  "$r = 0.012$ (baseline)"),
        (0.024, "#d7191c", "--", "$r = 0.024$"),
    ]),
    ("s", r"Separation Rate $s$", [
        (0.05,  "#2c7bb6", "--", "$s = 0.05$"),
        (0.10,  "#888888", "-",  "$s = 0.10$ (baseline)"),
        (0.15,  "#d7191c", "--", "$s = 0.15$"),
    ]),
    ("A", r"Matching Efficiency $A$", [
        (1.2,  "#2c7bb6", "--", "$A = 1.2$"),
        (1.0,  "#888888", "-",  "$A = 1.0$ (baseline)"),
        (0.8,  "#d7191c", "--", "$A = 0.8$"),
    ]),
    ("gamma", r"Vacancy Cost $\gamma$", [
        (0.4,  "#2c7bb6", "--", r"$\gamma = 0.4$"),
        (0.8,  "#888888", "-",  r"$\gamma = 0.8$ (baseline)"),
        (1.2,  "#d7191c", "--", r"$\gamma = 1.2$"),
    ]),
]

# ──────────────────────────────────────────────
# Plot
# ──────────────────────────────────────────────
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
axes = axes.flatten()

w_base, theta_base, U_base = solve_equilibrium(
    x, r, s, gamma, z, alpha, A, beta)

for idx, (param, title, variants) in enumerate(experiments):
    ax = axes[idx]

    # ── Compute panel-level axis limits ──
    # x-axis: use the widest domain across all variants
    # so that every curve is plotted on the same wage grid
    all_x_vals   = [x]    # always include baseline x
    all_z_vals   = [z]
    all_alpha    = [alpha]
    all_theta_eq = []

    for val, color, ls, label in variants:
        p = dict(x=x, r=r, s=s, gamma=gamma,
                 z=z, alpha=alpha, A=A, beta=beta)
        p[param] = val
        all_x_vals.append(p['x'])
        all_z_vals.append(p['z'])
        all_alpha.append(p['alpha'])
        w_s, t_s, _ = solve_equilibrium(
            p['x'], p['r'], p['s'], p['gamma'],
            p['z'], p['alpha'], p['A'], p['beta'])
        if t_s is not None:
            all_theta_eq.append(t_s)

    # Panel x-axis spans from the lowest WR intercept to the
    # highest x across all variants — every curve is defined
    # somewhere on this range
    w_lo_panel = min(a * xv + (1 - a) * zv
                     for xv, zv, a in
                     zip(all_x_vals, all_z_vals, all_alpha)) - 0.01
    w_hi_panel = max(all_x_vals) + 0.01

    # Common wage grid covering the full panel domain
    w_grid = np.linspace(w_lo_panel, w_hi_panel, 1000)

    for val, color, ls, label in variants:
        p = dict(x=x, r=r, s=s, gamma=gamma,
                 z=z, alpha=alpha, A=A, beta=beta)
        p[param] = val

        # Mask wages outside the valid domain for this variant:
        #   JC requires w < p['x']
        #   WR requires w > alpha*p['x'] + (1-alpha)*p['z']
        w_min_v = p['alpha'] * p['x'] + (1 - p['alpha']) * p['z']

        t_jc = theta_from_jc(w_grid, p['x'], p['r'], p['s'],
                              p['gamma'], p['A'], p['beta'])
        t_wr = theta_from_wr(w_grid, p['x'], p['z'],
                              p['alpha'], p['gamma'])

        # Explicitly set values outside each curve's valid domain to nan
        # so matplotlib naturally terminates the line at the right point
        # without producing a cliff or a gap in the wrong place
        t_jc = np.where(
            (w_grid < p['x']) & (w_grid > w_min_v), t_jc, np.nan)
        t_wr = np.where(
            w_grid > w_min_v, t_wr, np.nan)

        ax.plot(w_grid, t_jc, color=color, lw=2, ls=ls)
        ax.plot(w_grid, t_wr, color=color, lw=2, ls=ls, alpha=0.5)

        # Termination marker at w = p['x'] for JC curve
        # so students can see where the curve ends and why
        t_jc_end = float(theta_from_jc(
            p['x'] - 1e-4, p['x'], p['r'], p['s'],
            p['gamma'], p['A'], p['beta']))
        ax.scatter([p['x']], [t_jc_end], color=color,
                   zorder=5, s=30, marker="|", linewidths=1.5)

        # Equilibrium marker
        w_s, t_s, _ = solve_equilibrium(
            p['x'], p['r'], p['s'], p['gamma'],
            p['z'], p['alpha'], p['A'], p['beta'])
        if w_s is not None:
            ax.scatter([w_s], [t_s], color=color,
                       zorder=6, s=60, marker="o")

    # Baseline equilibrium star
    ax.scatter([w_base], [theta_base], color="black",
               zorder=7, s=100, marker="*")

    # Axis limits
    theta_lo = max(0, min(all_theta_eq) * 0.5)
    theta_hi = max(all_theta_eq) * 1.6
    ax.set_xlim(w_lo_panel, w_hi_panel)
    ax.set_ylim(theta_lo, theta_hi)

# Legend: parameter variants only, no style explanation entries
    handles = []
    for val, color, ls, label in variants:
        handles.append(
            plt.Line2D([0], [0], color=color, lw=2,
                       ls=ls, label=label))
    ax.legend(handles=handles, fontsize=8, loc="upper right")

    ax.set_xlabel("Wage $w$", fontsize=11)
    ax.set_ylabel(r"Market Tightness $\theta$", fontsize=11)
    ax.set_title(title, fontsize=12)

fig.text(0.5, -0.01,
         "Solid lines = baseline; dashed lines = alternative values.  "
         "Darker shade = JC locus; lighter shade = WR locus.  "
         "Vertical tick = upper bound of JC curve ($w = x$).  "
         "Circles = shifted equilibria; star = baseline equilibrium.",
         ha="center", fontsize=9, color="gray")

fig.suptitle("Comparative Statics: Job-Creation and Wage Diagram",
             fontsize=14, y=1.02)
plt.tight_layout()
plt.show()

# ──────────────────────────────────────────────
# Summary table
# ──────────────────────────────────────────────
print(f"\n{'Experiment':<30} {'Value':>8} {'w*':>8} "
      f"{'θ*':>8} {'U* (%)':>10}")
print("-" * 68)
for param, title, variants in experiments:
    for val, color, ls, label in variants:
        p = dict(x=x, r=r, s=s, gamma=gamma,
                 z=z, alpha=alpha, A=A, beta=beta)
        p[param] = val
        w_s, t_s, U_s = solve_equilibrium(
            p['x'], p['r'], p['s'], p['gamma'],
            p['z'], p['alpha'], p['A'], p['beta'])
        base_marker = " ◄" if ls == "-" else ""
        if w_s is not None:
            print(f"{title:<30} {val:>8.3f} {w_s:>8.3f} "
                  f"{t_s:>8.3f} {U_s*100:>9.2f}%{base_marker}")
    print()
_images/498cacc98ae4e732518c825faf5831ea2afea2a246e5ca3ac23339a877d521f8.png
Experiment                        Value       w*       θ*     U* (%)
--------------------------------------------------------------------
Productivity $x$                  0.700    0.654    0.261     16.38%
Productivity $x$                  1.000    0.932    0.579     11.61% ◄
Productivity $x$                  1.300    1.214    0.911      9.48%

Non-employment Income $z$         0.200    0.920    0.800     10.06%
Non-employment Income $z$         0.400    0.932    0.579     11.61% ◄
Non-employment Income $z$         0.600    0.946    0.365     14.21%

Discount Rate $r$                 0.004    0.936    0.590     11.52%
Discount Rate $r$                 0.012    0.932    0.579     11.61% ◄
Discount Rate $r$                 0.024    0.926    0.564     11.75%

Separation Rate $s$               0.050    0.960    0.650      5.84%
Separation Rate $s$               0.100    0.932    0.579     11.61% ◄
Separation Rate $s$               0.150    0.907    0.517     17.26%

Matching Efficiency $A$           1.200    0.942    0.605     11.39%
Matching Efficiency $A$           1.000    0.932    0.579     11.61% ◄
Matching Efficiency $A$           0.800    0.917    0.544     11.94%

Vacancy Cost $\gamma$             0.400    0.950    1.250      8.21%
Vacancy Cost $\gamma$             0.800    0.932    0.579     11.61% ◄
Vacancy Cost $\gamma$             1.200    0.919    0.365     14.21%

The figure presents all six comparative statics simultaneously. In each panel, the baseline equilibrium is marked with a star; shifted equilibria are marked with circles. Solid lines are JC loci; dashed lines are WR loci. The printed table quantifies the equilibrium responses, allowing the qualitative predictions derived above to be verified numerically.

The results are summarized in the table below:

Parameter

Direction

\(\theta^*\)

\(w^*\)

\(\mathcal{U}^*\)

Productivity \(x\)

\(\uparrow\)

\(\uparrow\)

\(\uparrow\)

\(\downarrow\)

Non-employment income \(z\)

\(\uparrow\)

\(\downarrow\)

\(\uparrow\)

\(\uparrow\)

Discount rate \(r\)

\(\uparrow\)

\(\downarrow\)

\(\downarrow\)

\(\uparrow\)

Separation rate \(s\)

\(\uparrow\)

\(\downarrow\)

\(\downarrow\)

\(\uparrow\)

Matching efficiency \(A\)

\(\downarrow\)

\(\downarrow\)

\(\downarrow\)

\(\uparrow\)

Vacancy cost \(\gamma\)

\(\uparrow\)

\(\downarrow\)

ambiguous

\(\uparrow\)

Three patterns stand out. First, all shocks that reduce vacancy creation — whether through lower productivity, higher outside options, heavier discounting, faster destruction, reduced matching efficiency, or higher posting costs — raise unemployment. The labor market is fragile in the sense that unemployment responds to a wide range of disturbances. Second, wages and unemployment tend to move in opposite directions for supply-side shocks (\(x\), \(A\)) but in the same direction for demand-side shocks (\(z\), \(r\), \(s\)): when workers become more expensive (higher \(w\)), firms create fewer vacancies, raising \(\mathcal{U}\). Third, the effect of vacancy posting costs on wages is genuinely ambiguous — the only case in the table without a determinate sign — because higher costs shift both loci in opposite directions, with the net effect depending on parameters.

Conclusion#

This chapter has developed the search and matching model of the labor market from its foundations to a fully dynamic framework with endogenous job destruction. The main contributions of each section are as follows.

The matching function provides a tractable reduced-form description of the process by which workers and firms find each other, embedding congestion externalities that are absent from competitive models. The key variables — market tightness \(\theta\), the vacancy-filling rate \(q(\theta)\), and the job-finding rate \(f(\theta)\) — summarize labor market conditions from the perspectives of firms and workers respectively.

Equilibrium unemployment arises from the balance of flows into and out of unemployment. The steady-state rate \(\mathcal{U}^* = s/(s + f(\theta))\) is determined by the separation rate and the job-finding rate, and the Beveridge curve traces the locus of steady-state \((\mathcal{U}, \mathcal{V})\) pairs. The empirical work of Ahn and Crane shows how this theoretical curve can be taken to data, decomposing Beveridge curve shifts into contributions from matching efficiency, separation rates, and out-of-steady-state dynamics.

Job creation is governed by a free entry condition that equates the value of a filled job to the expected cost of recruiting. The resulting job creation condition defines a downward-sloping relationship between wages and market tightness: higher wages reduce vacancy creation and tighten the labor market less.

Wage determination via Nash bargaining delivers a wage rule that is increasing in both productivity and market tightness, generating an upward-sloping relationship between wages and tightness. The equilibrium wage and tightness are jointly determined at the intersection of the job creation and wage rule loci.

The comparative statics analysis shows that the model delivers sharp and intuitive predictions across a range of parameter changes: productivity improvements raise wages and reduce unemployment; higher non-employment income or bargaining power raises wages but also raises unemployment; and reductions in matching efficiency shift the Beveridge curve outward, a result with direct empirical relevance for interpreting structural changes in the labor market.

The framework developed here is the foundation for a large and active literature. Immediate extensions include heterogeneous workers and firms, directed search, on-the-job search, and the incorporation of the model into a dynamic general equilibrium framework to study business cycle fluctuations. Each of these extensions preserves the core insight of the search and matching approach: that labor market outcomes are the equilibrium result of decentralized matching activity subject to frictions, and that understanding unemployment requires understanding the flows that generate and dissolve employment relationships.