Backend Development 11 min read

Improving Page Performance with HTTP Streaming: Airbnb’s Early Flush Implementation

Airbnb boosted page performance by implementing HTTP streaming with an early‑flush strategy that sends the head chunk first, allowing browsers to start loading CSS and JavaScript while the server fetches data, cutting First Contentful Paint by roughly 100 ms despite challenges like tag handling, buffering, and latency.

Airbnb Technology Team
Airbnb Technology Team
Airbnb Technology Team
Improving Page Performance with HTTP Streaming: Airbnb’s Early Flush Implementation

In this article we discuss how to use HTTP streaming to deliver Airbnb.com’s byte stream to the browser as quickly as possible.

Streaming (or "flush") means sending response chunks to the client as soon as they are ready, instead of buffering the entire response first. This allows the browser to start processing the page before the whole HTML is received.

Practice of Streaming at Airbnb

Most sites still use a buffering strategy because splitting a page into independent chunks adds work and may not be feasible when the whole page depends on a slow backend query. However, streaming can reduce the network request waterfall caused by sequential resource loading.

By sending the <head> part of the HTML first (Early Flush), we can get the browser to start downloading CSS and JavaScript earlier.

Early Flush example (first chunk):

<html>
  <head>
    <script src=… defer />
    <link rel="stylesheet" href=… />
    <!-- lots of other <meta> and other tags… -->

Remaining content (second chunk):

<!-- <head> tags that depend on data go here -->
  </head>
  <body>
    <!-- Body content here -->
  </body>
</html>

Airbnb’s stack uses an Express‑based Node.js server with React for rendering. To make streaming work they split the monolithic component into three parts:

A component that renders the early‑flush <head> (static resources).

A component that renders the later <head> part that depends on data.

A <body> component.

Each component only renders its own fragment, and the server writes the opening <html><head> tags, streams the early <head> , waits for data, streams the later <head> , writes </head><body> , streams the body, and finally closes the document.

Streaming data block example (third chunk):

<html>
  <head>
    <link rel="preload" as="script" href=… />
    <link rel="stylesheet" href=… />
    <!-- lots of other <meta> ... -->

Body block:

<!-- <head> tags that depend on data go here -->
</head>
<body>
  <!-- Body content here -->
  <script src=… />

Delayed data block (sent after visible content):

<script type="application/json">
  <!-- data -->
</script>
</body>
</html>

Challenges encountered include:

Handling unclosed HTML tags when splitting the response.

Rendering components before all data is available.

Managing HTTP status codes and redirects after early flushing.

Disabling Nginx buffering to allow incremental responses.

Unexpected 200 ms latency caused by Nagle’s algorithm and gzip; resolved by disabling Nagle in HAProxy.

Additional notes:

When using delayed data, the <script> tag is moved to the body and the defer attribute is removed because the body is already fully received.

Preload tags are added in the early‑flush chunk to avoid a new waterfall for the script.

Conclusion

HTTP streaming dramatically improved Airbnb’s page performance. Early Flush reduced First Contentful Paint (FCP) by about 100 ms on tested pages, and streaming data eliminated FCP delays caused by slow backend queries. Despite challenges, integrating streaming into an existing React application proved feasible and robust. The broader front‑end ecosystem is also moving toward streaming with GraphQL’s @defer/@stream and Next.js’s streaming SSR.

performance optimizationreactNode.jsServer-side RenderingEarly FlushHTTP Streaming
Airbnb Technology Team
Written by

Airbnb Technology Team

Official account of the Airbnb Technology Team, sharing Airbnb's tech innovations and real-world implementations, building a world where home is everywhere through technology.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.