---
title: "17.5 The 'static lifetime"
description: "The 'static lifetime is the whole-program lifetime of string literals, and why adding 'static to silence the borrow checker is usually the wrong fix."
url: "https://learnrust.net/chapter-17/the-static-lifetime/"
last_updated: "2026-06-13"
---

# 17.5 The 'static lifetime

One lifetime has a name and you've used it since chapter 5: `'static`, the lifetime of string literals. It means "valid for the entire duration of the program," the longest possible lifetime. This short lesson explains what `'static` is, why string literals have it, and, most importantly, warns against the common beginner trap of adding `'static` to make a borrow-checker error go away. The annotation is almost never the right fix, and knowing why saves you a frustrating detour.

## What 'static means

`'static` is the lifetime that lasts the whole program, from start to finish. A reference with the `'static` lifetime is guaranteed valid forever, because the data it points at lives forever. The clearest example is a string literal, which you've written since lesson [1.1](https://learnrust.net/chapter-1/statements-and-program-structure/):

```rust
fn main() {
    let s: &'static str = "I live for the whole program";
    println!("{s}");
}
```

```
I live for the whole program
```

Every string literal has type `&'static str`. Lesson [5.4](https://learnrust.net/chapter-5/introduction-to-str/) noted that a literal is a `&str`, and lesson [9.7](https://learnrust.net/chapter-9/string-slices/) added that it's specifically `&'static str`; here's why. The text of a string literal is baked directly into the compiled program's binary, so it exists for as long as the program runs. A reference to it can therefore be valid for the entire program, which is exactly what `'static` denotes. You've been creating `'static` references every time you wrote `"hello"`, the type annotation was just elided.

This is also why a function can return a string literal without any lifetime trouble: `fn greeting() -> &'static str { "hello" }` compiles cleanly, because the returned reference points at data that lives forever, so there's no value it could outlive.

> **Key insight**
>
> `'static` is the lifetime of data that lives for the whole program. String literals have it because their bytes are embedded in the binary. It's the one concrete, nameable lifetime you'll write (the `'a` in earlier lessons was a *variable* standing for "some lifetime"; `'static` names a *specific* one, the longest). A `&'static T` is a promise that the reference will be valid no matter how long the program runs.

## The 'static trap

Here's the warning. When you hit a borrow-checker error like "does not live long enough" (lesson [17.2](https://learnrust.net/chapter-17/lifetime-annotations-in-functions/)), the compiler sometimes mentions `'static`, and a tempting "fix" is to add `'static` bounds until the error disappears. This is almost always wrong, and understanding why is the point of the lesson.

Adding `'static` doesn't make data live longer (no annotation does, lesson [17.2](https://learnrust.net/chapter-17/lifetime-annotations-in-functions/)); it *demands* that the data already lives for the whole program. So slapping `'static` on a reference to a local value doesn't satisfy the borrow checker, it changes the error to "this local isn't `'static`," because the local genuinely isn't. You've just told the compiler to require something even stronger, which the local still can't provide. The error moves; the problem doesn't.

```rust
fn main() {
    let name = String::from("Ada");
    let r: &'static str = &name;   // refused: name isn't 'static
    println!("{r}");
}
```

```
error[E0597]: `name` does not live long enough
 --> src/main.rs:3:27
  |
2 |     let name = String::from("Ada");
  |         ---- binding `name` declared here
3 |     let r: &'static str = &name;
  |            ------------   ^^^^^ borrowed value does not live long enough
  |            |
  |            type annotation requires that `name` is borrowed for `'static`
```

The annotation requires `name` to be `'static`, and `name` is a local that's dropped at the end of `main`, so it can't be. The `'static` made things worse, not better.

## What to do instead

When you hit "does not live long enough," the real fixes are about *actual* lifetimes, not annotations:

**Own the data.** The most common fix: instead of borrowing, use an owned `String` or `Vec` (the lesson [10.8](https://learnrust.net/chapter-10/ownership-in-structs/) and [17.3](https://learnrust.net/chapter-17/lifetimes-in-structs/) advice). An owned value carries no lifetime constraint, so the whole class of "doesn't live long enough" errors evaporates. This solves the large majority of cases.

**Restructure so the data outlives the borrow.** Move the owner so it lives long enough, reorder so the borrow ends before the owner is dropped (the "borrows end at last use" idea from chapter 9), or pass ownership in rather than borrowing.

**Use `'static` only when the data genuinely is `'static`**, like a string literal or a true constant (lesson [5.1](https://learnrust.net/chapter-5/constants-and-statics/)). `'static` is a description that fits literals and constants; it's not a tool for extending the life of locals.

> **Best practice**
>
> Treat `'static` as a *description* of data that truly lives forever (literals, constants), never as a *fix* for a borrow error. If the compiler says a value doesn't live long enough, reach for owned data (`String`, `Vec`) or restructure so the value outlives its borrow, don't add `'static`. The presence of `'static` in your own code, outside literal and constant contexts, is usually a smell worth a second look.

## Quiz time

**Question #1**

What does the `'static` lifetime mean, and why do string literals have it?

<details class="solution">
<summary>Show solution</summary>

`'static` means the reference is valid for the entire duration of the program (the longest possible lifetime). String literals have it because their bytes are embedded directly in the compiled binary, so they exist for as long as the program runs, and a reference to them can be valid the whole time. Every `"..."` literal has type `&'static str`.

</details>

**Question #2**

Why doesn't adding `&'static` to a reference to a local variable fix a "does not live long enough" error?

<details class="solution">
<summary>Show solution</summary>

Because `'static` doesn't *extend* a value's life; it *requires* the value to already live for the whole program. A local variable is dropped at the end of its scope, so it isn't `'static`, and demanding `'static` just produces a new error ("this local isn't `'static`"). The annotation asks for something even stronger than before, which the local still can't satisfy.

</details>

**Question #3**

You get "does not live long enough" on a function returning a reference to a `String` it created locally. What are the right fixes?

<details class="solution">
<summary>Show solution</summary>

Return the owned `String` itself instead of a reference (the data the caller is given then lives as long as they keep it), or restructure so the data is owned by the caller and passed in. The fix is to deal with real ownership/lifetimes, not to add `'static`, which would just demand the impossible of a local value. Owning the data is the usual answer (lessons [10.8](https://learnrust.net/chapter-10/ownership-in-structs/), [17.3](https://learnrust.net/chapter-17/lifetimes-in-structs/)).

</details>

That completes lifetimes: what they are, writing them on functions and structs, the elision rules that usually spare you, and `'static`. The summary is next, and then chapter 18 returns to practical ground with the collections you'll use in every real program, `Vec`, `String` as UTF-8, and `HashMap`, where ownership, borrowing, and now lifetimes all show up in working code.

## Sitemap

See the full [sitemap](https://learnrust.net/sitemap.md) for all pages.
