Attention Complexity › Attention vs. RNN Complexity

Michael BrenndoerferUpdated May 29, 20259 min read
Language AI HandbookAll chapters
Part 13 of 67Self-Attention
Chapter 95Attention Complexity › Attention vs. RNN Complexity
Reading section 4 of 11 · Attention vs. RNN Complexity · 9 minSection 4 of 11 · 9 min

Book contents

Section 4 of 11 · 9 min read

Attention Complexity › Attention vs. RNN ComplexityOne section · Sections in this chapter4 / 11 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

To appreciate why the quadratic cost matters, let's compare attention to recurrent neural networks. Both architectures process sequences, but their computational patterns differ fundamentally. Understanding this comparison is important for two reasons. First, it contextualizes when attention's quadratic cost is a problem versus when it is irrelevant. Second, it makes precise the trade-off that motivated the transformer architecture: you pay more computation per token in exchange for dramatically shorter information paths.

Before transformers, recurrent networks (LSTMs and GRUs) were the dominant architecture for sequence modeling. These networks processed sequences token by token, maintaining a fixed-size hidden state that summarized everything seen so far. This sequential nature made them efficient in terms of total operations, but it created a critical weakness: information from early in the sequence had to propagate through many time steps to influence late positions. In a 1000-token sequence, information from the first token must survive 999 update steps to reach the last position. Each step involves a learned transformation, and information tends to degrade through this chain, a problem known as the vanishing gradient.

Attention sidesteps this problem entirely by connecting any two positions directly in a single operation. The cost of this directness is the quadratic scaling. Whether this trade-off is worth it depends on the sequence length, the nature of the task, and whether the long-range dependencies you care about are dense enough to justify the overhead.

RNN Complexity Analysis

The recurrent architecture's cost structure is fundamentally different from attention's. Rather than computing all pairwise interactions at once, an RNN processes tokens one at a time, updating a hidden state at each step. This sequential structure has practical consequences for both complexity and parallelizability.

An RNN with hidden dimension dd processes each of nn tokens sequentially. At each timestep tt, the hidden state update follows:

ht=σ(Whht−1+Wxxt+b)h_t = \sigma(W_h h_{t-1} + W_x x_t + b)

where:

  • hth_t: hidden state at timestep tt (dimension dd)
  • WhW_h: hidden-to-hidden weight matrix (shape d×dd \times d)
  • ht−1h_{t-1}: previous hidden state (dimension dd)
  • WxW_x: input-to-hidden weight matrix (shape d×dd \times d, assuming input dimension matches dd)
  • xtx_t: input at timestep tt
  • σ\sigma: activation function (e.g., tanh)

The computational cost per timestep is:

  • Matrix-vector multiplication Whht−1W_h h_{t-1}: O(d2)O(d^2) operations
  • Matrix-vector multiplication WxxtW_x x_t: O(d2)O(d^2) operations
  • Activation function: O(d)O(d) operations

Total per step: O(d2)O(d^2). For nn tokens: O(nd2)O(nd^2).

RNN complexity is linear in sequence length and quadratic in hidden dimension. This is a notable contrast with attention: the RNN pays its quadratic cost in the model dimension, while attention pays its quadratic cost in the sequence length. The choice of architecture is essentially a choice about which resource you can afford to spend quadratically.

Comparative Analysis

Summarizing the complexity of each architecture:

  • Attention: O(n2d)O(n^2 d)
  • RNN: O(nd2)O(nd^2)

where nn is sequence length and dd is the hidden/model dimension.

The key insight is that these two complexities share the same functional form with nn and dd swapped. Attention is quadratic in nn, linear in dd. RNN is linear in nn, quadratic in dd. This symmetry is not coincidental: it reflects the fundamental trade-off between sequential processing (which pays a fixed cost per step but must be sequential) and parallel processing (which can run in parallel but must examine all pairs).

To find when these costs are equal, we set n2d=nd2n^2 d = nd^2 and solve for nn:

n2d=nd2n^2 d = nd^2

Dividing both sides by ndnd (assuming n,d>0n, d > 0):

n=dn = d

This crossover point has a clear interpretation: when sequence length exceeds model dimension (n>dn > d), attention becomes more expensive. When model dimension exceeds sequence length (n<dn < d), RNN becomes more expensive. In practice, modern language models have dimensions of 512 to 4096, meaning that attention is more expensive than RNN for any sequence longer than a few hundred to a few thousand tokens. Since many practical tasks involve sequences longer than that, this crossover is reached regularly in real workloads.

In[12]:
Code
def compare_complexity(n_values, d):
    """Compare attention vs RNN complexity."""
    results = []
    for n in n_values:
        attention = n * n * d  # O(n^2 d)
        rnn = n * d * d  # O(n d^2)
        results.append(
            {
                "n": n,
                "attention": attention,
                "rnn": rnn,
                "ratio": attention / rnn,
            }
        )
    return results


# Compare for typical model dimension
d = 512
n_values = [64, 128, 256, 512, 1024, 2048, 4096]
comparison = compare_complexity(n_values, d)
Out[13]:
Console
Complexity Comparison (d = 512):

 Seq Len (n)       Attention             RNN   Attn/RNN
-------------------------------------------------------
          64       2,097,152      16,777,216       0.12x
         128       8,388,608      33,554,432       0.25x
         256      33,554,432      67,108,864       0.50x
         512     134,217,728     134,217,728       1.00x
        1024     536,870,912     268,435,456       2.00x
        2048   2,147,483,648     536,870,912       4.00x
        4096   8,589,934,592   1,073,741,824       8.00x

Crossover point: n = d = 512

The ratio column reveals the crossover behavior. At n=64n = 64 and n=128n = 128, attention is 0.13x and 0.25x the cost of an RNN, respectively, making attention the more efficient choice. At n=512n = 512 (exactly equal to dd), both architectures have identical cost (1.00x ratio). Beyond this point, attention becomes increasingly expensive: at n=4096n = 4096, attention requires 8x more operations than an equivalent RNN.

Out[14]:
Visualization
Line plot comparing attention O(n^2 d) and RNN O(nd^2) complexity, crossing at the model dimension.
Computational complexity comparison between self-attention and RNN as sequence length varies. The lines cross at n=d (512 in this example), after which attention's quadratic cost dominates.

The crossover behavior has practical implications. For short sequences (a few hundred tokens), attention's overhead is minimal and often smaller than the equivalent RNN. For long documents, books, or conversation histories spanning thousands of tokens, the quadratic cost becomes the dominant bottleneck. This explains the historical dominance of transformers for classification and short generation tasks, alongside early proposals to handle long sequences through hierarchical chunking: run attention on small windows, then run attention again over the chunk summaries. The quadratic cost was "tamed" rather than solved until more principled efficient attention methods arrived.

Path Length vs. Computation Trade-off

Why use attention despite its higher cost at long sequences? The answer lies in path length, a concept that quantifies how "far" information must travel to flow from one part of a sequence to another. In an RNN, information from token ii to token jj must traverse ∣j−i∣|j - i| sequential steps, each involving a learned transformation that can potentially lose or distort information. In attention, any two tokens connect in a single step, with no intermediaries.

Think of it as the difference between a telephone game and a conference call. In the telephone game (RNN), a message passes through a chain of people, each one rephrasing it before passing it on. After 50 iterations, the message may be unrecognizable. In a conference call (attention), everyone hears the original speaker directly, regardless of how far apart they are. The conference call is more expensive to organize for large groups, but it preserves message fidelity perfectly.

In[15]:
Code
# Trade-off analysis: what do we gain for the extra compute?
def analyze_tradeoff(n, d):
    """Analyze the compute/path-length trade-off."""
    # Maximum path length
    rnn_max_path = n - 1  # First to last token
    attention_max_path = 1  # Always direct

    # Average path length (uniform distribution of source/target)
    rnn_avg_path = (n - 1) / 2
    attention_avg_path = 1

    # Compute ratio
    compute_ratio = (n * n * d) / (n * d * d)

    # Path length improvement
    path_improvement = rnn_avg_path / attention_avg_path

    return {
        "compute_ratio": compute_ratio,
        "path_improvement": path_improvement,
        "efficiency": path_improvement / compute_ratio,
    }


tradeoff_results = []
for n in [128, 256, 512, 1024, 2048]:
    result = analyze_tradeoff(n, d=512)
    result["n"] = n
    tradeoff_results.append(result)
Out[16]:
Console
Compute vs Path Length Trade-off (d = 512):

   Seq Len   Compute Ratio    Path Improve   Efficiency
-------------------------------------------------------
       128            0.25x            63.5x      254.000
       256            0.50x           127.5x      255.000
       512            1.00x           255.5x      255.500
      1024            2.00x           511.5x      255.750
      2048            4.00x          1023.5x      255.875

The "Efficiency" column (path improvement divided by compute ratio) quantifies the value proposition of attention. At n=128n = 128, we pay only 0.25x the compute of an RNN while gaining 63x shorter average paths, yielding an efficiency of 252. At n=512n = 512 (the crossover point), we pay 1x compute for 255x path improvement. At n=2048n = 2048, we pay 4x more compute but get 1023x shorter paths. Notice that efficiency remains nearly constant around d/2=256d/2 = 256. This reveals an important insight: as sequence length grows, both the path improvement and the compute penalty scale proportionally with nn. Attention's value proposition stays roughly constant regardless of sequence length. The short path lengths are always worth the extra compute.

This constancy is a powerful argument for attention. One might worry that at very long sequences, the quadratic overhead makes the mechanism unjustifiable. But the analysis shows otherwise: longer sequences also mean proportionally longer average RNN paths, so the benefit of short connections grows in proportion to the cost. The relative advantage of direct connections remains stable even as absolute costs grow. This is why the field did not abandon attention as sequences grew longer; instead, it found ways to make attention cheaper.