ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 92

  1. Blog
  2. /Observability & SRE

deque vs list: Queue FIFO Lab

Hands-on collections.deque vs list queue lab: real FIFO ops/s for append/popleft vs list.pop(0) at several prefill sizes on Linux localhost (eng lab).

Aditya Challa·30 September 2026·3 min read

Lab
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — FIFO cycles/s (p50)
  5. Drain and append baselines
  6. Pitfalls
  7. When to pick what
  8. Reproduce
  9. Closing

Intro — what this post promises

Need a FIFO queue in Python? Folklore says “use collections.deque” because list.pop(0) is O(n). This lab times append + popleft vs append + pop(0) with a prefill of size S, plus drain and append-only baselines, on Linux localhost.

Related links:

  • lru_cache hit vs miss localhost lab
  • struct pack vs to_bytes localhost lab
  • set vs list membership localhost lab
  • sorted vs heapq vs bisect localhost lab
  • copy vs deepcopy localhost lab
  • string concat vs join localhost lab
  • dataclass vs slots vs dict localhost lab
  • logging vs print localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. Affiliates: 0. FIFO cycle = one append + one front pop, keeping length ≈ S.

Verdict up front: at S=0–100 deque is only ~1.2–1.2× list. At S=1 000 already ~2.6×. At S=10 000 ~31× (18.6M vs 605k cycles/s). Draining 50k with pop(0) is ~255k/s vs deque ~31.6M.


Arms

ArmPattern
FIFOprefill S, then M× (append + pop front)
drainprefill N, pop until empty
append-onlygrow from empty (sanity)
list pop() enddrain with pop() — stack, not queue

Lab topology

FIFO S in {0, 100, 1000, 10000, 50000}
M scaled down for large S (still p50 ops/s)
Drain N in {1000, 10000, 50000}
Metric: p50 wall → cycles/s or pops/s

Script: lab-evidence/54-deque-vs-list-queue/results/run_lab.py.


Lead table — FIFO cycles/s (p50)

Prefill Sdequelist pop(0)deque÷list
034,942,18828,243,5931.2×
10034,512,08228,976,0331.2×
1,00032,741,94812,494,5842.6×
10,00018,638,981604,50130.8×
50,0003,049,348119,59625.5×

At S=10k, list pays ~1654 ns/cycle vs deque ~54 ns.


Drain and append baselines

Armops/sns/op
deque drain N=50k31,573,53031.7
list pop(0) drain N=50k255,4873914.1
list pop() end N=50k36,831,95127.2
list append N=100k41,751,38724.0
deque append N=100k36,859,59227.1

list.pop() from the end matches deque drain speed — the bug is front removal, not “lists are slow.”


Pitfalls

  1. Benchmarking empty-queue FIFO only — S≈0 hides the O(n) shift.
  2. Using list as a queue “until it hurts” — at S=1k it already hurts on this box.
  3. Confusing stack (pop()) with queue (pop(0)) — different asymptotics.
  4. Indexing into a deque — O(n) for middle access; use a list if you need random access.

When to pick what

NeedPrefer
FIFO / sliding windowcollections.deque
Stack / LIFOlist + append/pop
Random access + occasional endslist
Append-only buffereither (append is peer)

Reproduce

python3 lab-evidence/54-deque-vs-list-queue/results/run_lab.py

Evidence: /workspace/lab-evidence/54-deque-vs-list-queue/results/.


Closing

list.pop(0) does not stay fine. On this box deque FIFO is ~2.6× at S=1k and ~31× at S=10k. Drain 50k: deque ~32M/s vs list pop(0) ~255k. Use deque for queues; keep list for stacks and random access.

collections.dequelist pop(0)fifo queuepopleftpython queuelocalhost labsredeque

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5. FIFO append+popleft/pop(0). S=0: deque 34.9M vs list 28.2M (~1.24x). S=1000: deque 32.7M vs list 12.5M (~2.6x). S=10000: deque 18.6M vs list 605k (~31x). S=50000: ~25x. Drain N=50k: deque 31.6M vs list pop(0) 255k. Affiliates: 0. Evidence: lab-evidence/54-deque-vs-list-queue/.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 12

    islice vs list Slice Windows: Localhost Lab

    Hands-on itertools.islice vs list slice window lab: real ops/s taking ranges from sequences, measured on Linux localhost in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

  • Plate 07

    heapq.merge vs sorted(chain): Localhost Lab

    Hands-on heapq.merge vs sorted(chain) multi-way merge: real records/s on pre-sorted lists, measured on Linux localhost today in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

  • Plate 88

    mmap Write vs pwrite Region: Localhost Lab

    Hands-on mmap MAP_SHARED write+msync vs pwrite region update: real MB/s with durability labels, measured on Linux localhost in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

On this page

  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — FIFO cycles/s (p50)
  5. Drain and append baselines
  6. Pitfalls
  7. When to pick what
  8. Reproduce
  9. Closing
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove