PHP ob_flush() Function: Everything You Need to Know
As a PHP developer, you may need to flush the output buffer to send data to the client immediately rather than waiting for the buffer to fill up. The ob_flush()
By default PHP holds your output in a buffer and sends it to the client all at once. Sometimes you want to push what you have so far to the browser without ending the buffer — for example, to stream a long report row by row or show progress during a slow task. The ob_flush() function does exactly that: it sends the contents of the active output buffer onward and then empties it, while keeping buffering active so you can keep collecting output. This chapter explains how ob_flush() fits into PHP's output-buffering chain, when to reach for it, and the gotchas that trip people up.
What ob_flush() Does
ob_flush() sends the contents of the topmost output buffer to the next level — the next buffer in the stack, or PHP's internal write layer if this is the only buffer. After flushing, that buffer is emptied but stays open, so subsequent echos are captured again.
Signature: ob_flush(): void
Returns: nothing (void); emits a warning if no buffer is active
PHP: 4.0+ (return type became void in PHP 8.0)Two ideas are easy to confuse:
ob_flush()moves data out of the PHP buffer but does not guarantee it reaches the browser. There may be another buffer above it, plus PHP's own write buffer and the web server's buffer.flush()pushes PHP's write buffers toward the client. To actually get bytes on the wire you typically call both, in order:ob_flush()thenflush().
It must be paired with ob_start(). Calling ob_flush() when no buffer is active raises a notice/warning and does nothing.
Syntax
ob_flush();It takes no arguments and returns no value.
Basic Example
Enable buffering, write something, then flush it out:
<?php
ob_start(); // 1. Enable output buffering
echo "This will be buffered";
ob_flush(); // 2. Flush PHP buffer to the next level
flush(); // 3. Push it toward the clientOutput:
This will be bufferedob_start() opens a buffer, the echo is captured into it, ob_flush() releases that text, and flush() nudges it toward the browser. Crucially, the buffer is still open after this — you could echo and flush again.
Streaming Output Progressively
The most common real use of ob_flush() is sending output in chunks so the user sees results as they are produced, instead of waiting for the whole script to finish:
<?php
ob_start();
for ($i = 1; $i <= 5; $i++) {
echo "Processing item $i\n";
ob_flush(); // hand this line to the next level
flush(); // and on toward the browser
// sleep(1); // (a real task would do work here)
}Output:
Processing item 1
Processing item 2
Processing item 3
Processing item 4
Processing item 5On a live server with the sleep(1) uncommented, each line would appear one second apart rather than all at the end.
ob_flush() vs. ob_end_flush() vs. ob_get_clean()
Picking the wrong "flush" function is the usual source of bugs. They differ in two ways: whether the buffer stays open, and where the contents go.
| Function | Sends contents onward? | Keeps buffer open? |
|---|---|---|
ob_flush() | Yes | Yes — keep buffering |
ob_end_flush() | Yes | No — closes the buffer |
ob_get_clean() | No — returns them as a string | No — closes the buffer |
Use ob_flush() when you want to emit progress but continue buffering. Use ob_end_flush() once you are completely done. Use ob_get_clean() when you want to capture the buffer into a variable rather than send it.
Common Gotchas
- Server buffering can still hold output back. Apache, Nginx (FastCGI buffering), gzip compression, and proxies may keep your flushed bytes until they have "enough".
ob_flush()+flush()only control PHP's side. zlib.output_compressionbreaks streaming. When gzip output compression is on, intermediate flushes are usually buffered for compression, so chunks won't trickle out. Turn it off for streaming endpoints.- No buffer = warning. Calling
ob_flush()without a matchingob_start()triggers a warning. Check the active level withob_get_level()if you are unsure. - It empties the buffer. After
ob_flush()the buffer is cleared, so you cannot read its previous contents afterward. - Force immediate flushing globally.
ob_implicit_flush(true)makes every output statement flush automatically, removing the need to callob_flush()after eachecho.
Conclusion
ob_flush() sends the current output buffer onward while keeping buffering enabled, making it the right tool for streaming progress or large responses incrementally. Remember the chain: ob_start() opens the buffer, ob_flush() releases its contents to the next level, and flush() pushes them toward the client — and that server-side buffering or gzip compression can still delay delivery regardless of what your PHP code does.