Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python itertools.tee: a lagging reader retains buffered values

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

itertools.tee creates independent iterators over one source by buffering values consumed ahead by another reader.

Download Python source kit

Operation contract

Two receipt readers share a three-item source. The fast reader consumes two IDs before the slow reader consumes one; the slow reader can still retrieve the first ID because tee retained it. The fixture then drains both. This is not two independent upstream queries or a free clone of a generator.

Failure and ownership boundary

If one reader runs far ahead or never resumes, the buffer can grow with the entire unread stream. tee iterators are not safe for simultaneous use from multiple threads. When full replay is needed and the input is already small and bounded, materializing a list can make the memory cost easier to reason about. Python iterators: exhaustion and repeatable collection ownership, Python itertools: adjacent groups and shared iterator consumption and Python SpooledTemporaryFile: rollover is a storage choice, not an upload limit show other choices.

Working program

python
from itertools import tee

source_reads = []
def receipt_stream():
    for identifier in ("R41", "R42", "R43"):
        source_reads.append(identifier)
        yield identifier

fast, slow = tee(receipt_stream())
print(next(fast), next(fast))
print("upstream:", source_reads)
print("slow:", next(slow))
print("fast rest:", list(fast))
print("slow rest:", list(slow))

Output

Output
R41 R42
upstream: ['R41', 'R42']
slow: R41
fast rest: ['R43']
slow rest: ['R42', 'R43']

Costs and limits

Total upstream reads are O(n), but retained buffer size depends on the maximum reader lag and can reach O(n). The three-item fixture does not measure a long-running service.

Common Mistakes

  • tee can retain a large unread backlog.
  • Two tee readers must not be consumed concurrently from different threads.

Connected lessons

Python iterators: exhaustion and repeatable collection ownership, Python itertools: adjacent groups and shared iterator consumption, Python SpooledTemporaryFile: rollover is a storage choice, not an upload limit.

python
tee-buffer-lifetime
Storage details