Desk Clarity

A field guide to everyday digital problems.

Developer tools / Practical guide

Python Deque Maxlen Drops Old Items: Choose a Rolling Window or a Work Queue

A bounded deque silently loses older entries when new items are appended.

By ON Lab2 min readSources checked November 10, 2026 (KST)

A deque with maxlen is a rolling window: appending to a full deque discards an item at the opposite end. Use a bounded queue with a defined full policy when unprocessed work must not be silently replaced.

Check the failure with a small fixture

A bounded deque silently loses older entries when new items are appended.

from collections import deque
from queue import Queue, Full
recent = deque(maxlen=2)
recent.extend(["first", "second", "third"])
assert list(recent) == ["second", "third"]
recent.appendleft("new-left")
assert list(recent) == ["new-left", "second"]
work = Queue(maxsize=2)
work.put_nowait("first")
work.put_nowait("second")
try:
    work.put_nowait("third")
except Full:
    print("caller must choose a full-queue policy")
assert work.get_nowait() == "first"
work.task_done()

What the result means

The deque discards a different end depending on whether you append right or left. That is useful for recent history, but it is a different contract from rejecting or waiting for capacity. The Queue example raises Full without dropping an already queued item, making overload visible to the caller.

Choose the correction for your caller

Choose a deque for the most recent N observations when losing older observations is intentional. Choose a work queue when each accepted item needs accounting, and decide whether full means wait with a timeout, reject, or persist elsewhere. Do not substitute deque(maxlen=N) as a memory cap for a task backlog without a documented loss policy. Also distinguish append from insert: inserting into an already full bounded deque raises IndexError instead of automatically discarding from the other side. To observe a pending discard in a single-owner rolling window, inspect recent[0] before append when len(recent) == recent.maxlen and maxlen is positive. Capture that value before changing the deque; combining the check and append across threads needs shared synchronization. A zero-capacity deque retains nothing.

Limits and the next check

A bounded in-memory queue is not durable storage, and this example does not claim exactly-once processing. queue.Queue targets thread coordination; process and async producers need their respective queue contracts. Capacity limits item count, not the total bytes held by arbitrary payloads.

Related: Compare a related data or execution contract.

The embedded Python example was executed as an isolated local script on November 10, 2026 (KST), using Python 3.11.6. It demonstrates the stated boundary; it is not a test of your application or a promise of compatibility with every Python release.

Sources & further reading