How 'Deque' Saved My Python Script from Slowing to a Crawl

in #programming26 days ago

image.png

Sometimes the right tool makes all the difference. I was building a Python script that hit API rate limits a bit too often. Not because I was doing anything wild, but because checking and managing timestamps of previous API calls started to slow things down.

The culprit? A regular Python list.

The fix? A simple but powerful data structure called deque (pronounced “deck”).

If you’re dealing with queues, rate limits, or just need to add/remove items from both ends of a list quickly, this little built-in feature might be exactly what you need.

What is deque?

deque stands for Double-Ended Queue. It lives in Python’s collections module, and you use it like this:

from collections import deque

It works a lot like a list—but it’s built for speed, especially when you’re adding or removing items from either end.

How is it different from a regular list?

Here’s the short version:

OperationList Time Complexitydeque Time Complexity
append() (end)Fast (O(1))Fast (O(1))
pop() (end)Fast (O(1))Fast (O(1))
insert(0, item) (start)Slow (O(n))appendleft() = Fast (O(1))
pop(0) (start)Slow (O(n))popleft() = Fast (O(1))

The difference is massive when you’re working with larger data, especially when you’re removing items from the front. Lists have to shift every other element to close the gap. deque just updates a pointer.

Under the hood: Why is deque faster?

Python lists are dynamic arrays. They’re great at random access (getting item by index), but not so great at adding/removing items at the front. That’s because arrays need to keep elements in order in memory, so any time you insert at the front, everything else has to slide down one spot.

deque, on the other hand, is more like a chain of blocks (technically a doubly-linked list under the hood). Adding or removing from either end is a matter of updating pointers—no shifting required.

Rate Limiting with deque

Here’s what I was dealing with: I needed to track the timestamps of recent API calls—say, only the ones made in the last 60 seconds.

That means:

  • Every time I make a call, I need to add the current time.
  • Before making a call, I need to remove any timestamps older than 60 seconds.

This is a classic sliding window problem.

Why deque works perfectly here:

from collections import deque
from time import time

GEMINI_CALL_TIMESTAMPS = deque()

def can_make_call():
    now = time()
    
    # Remove old timestamps
    while GEMINI_CALL_TIMESTAMPS and now - GEMINI_CALL_TIMESTAMPS[0] > 60:
        GEMINI_CALL_TIMESTAMPS.popleft()  # O(1)
    
    # Check if under limit
    if len(GEMINI_CALL_TIMESTAMPS) < 10:
        GEMINI_CALL_TIMESTAMPS.append(now)
        return True
    else:
        return False

If I’d used a list here and called pop(0) instead of popleft(), the cleanup step would get slower the more timestamps there were—because lists shift everything after the first item. That’s a performance hit you feel when you're doing this frequently.

size limits with maxlen

You can also give your deque a fixed size like this:

history = deque(maxlen=100)

Now, when it’s full and you add a new item, it automatically drops one from the other end. Great for logs, recent history, or metrics.

TL;DR

If you need fast operations at both ends of a sequence, deque is your friend.

It’s especially handy when:

  • You’re implementing a queue or stack.
  • You want a sliding window of data.
  • You need to regularly remove the oldest items from a growing collection.

In my case, switching to deque made my rate limiter clean, fast, and reliable—no more slowdowns from shifting long lists.

It’s a small change, but it made a big difference.

Sort:  

I don't think I've used that one, but it could be useful. I tend to use the standard list, set and dictionary a lot, but they may not be optimal for some cases. You just need to know what the other options are. Python does keep surprising me.

I did not know that one before. Sliding window as a usecase was my first thought, too.
Thank you very much. This is wunderful.
!BBH

Thank you for your witness vote!
Have a !BEER on me!
To Opt-Out of my witness beer program just comment STOP below

Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!

Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).

You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support.