Skip to main content

queuelib

https://img.shields.io/pypi/v/queuelib.svg https://img.shields.io/pypi/pyversions/queuelib.svg https://github.com/scrapy/queuelib/actions/workflows/tests-ubuntu.yml/badge.svg Coverage report

Queuelib is a Python library that implements object collections which are stored in memory or persisted to disk, provide a simple API, and run fast.

Queuelib provides collections for queues (FIFO), stacks (LIFO), queues sorted by priority and queues that are emptied in a round-robin fashion.

Queuelib supports Python 3.10+ and has no dependencies.

Installation

You can install Queuelib either via the Python Package Index (PyPI) or from source.

To install using pip:

$ pip install queuelib

To install using easy_install:

$ easy_install queuelib

If you have downloaded a source tarball you can install it by running the following (as root):

# python setup.py install

FIFO/LIFO disk queues

Queuelib provides FIFO and LIFO queue implementations.

Here is an example usage of the FIFO queue:

>>> from queuelib import FifoDiskQueue
>>> q = FifoDiskQueue("queuefile")
>>> q.push(b'a')
>>> q.push(b'b')
>>> q.push(b'c')
>>> q.pop()
b'a'
>>> q.close()
>>> q = FifoDiskQueue("queuefile")
>>> q.pop()
b'b'
>>> q.pop()
b'c'
>>> q.pop()
>>>

The LIFO queue is identical (API-wise), but importing LifoDiskQueue instead.

PriorityQueue

A discrete-priority queue implemented by combining multiple FIFO/LIFO queues (one per priority).

First, select the type of queue to be used per priority (FIFO or LIFO):

>>> from queuelib import FifoDiskQueue
>>> qfactory = lambda priority: FifoDiskQueue('queue-dir-%s' % priority)

Then instantiate the Priority Queue with it:

>>> from queuelib import PriorityQueue
>>> pq = PriorityQueue(qfactory)

And use it:

>>> pq.push(b'a', 3)
>>> pq.push(b'b', 1)
>>> pq.push(b'c', 2)
>>> pq.push(b'd', 2)
>>> pq.pop()
b'b'
>>> pq.pop()
b'c'
>>> pq.pop()
b'd'
>>> pq.pop()
b'a'

RoundRobinQueue

Has nearly the same interface and implementation as a Priority Queue except that each element must be pushed with a (mandatory) key. Popping from the queue cycles through the keys “round robin”.

Instantiate the Round Robin Queue similarly to the Priority Queue:

>>> from queuelib import RoundRobinQueue
>>> rr = RoundRobinQueue(qfactory)

And use it:

>>> rr.push(b'a', '1')
>>> rr.push(b'b', '1')
>>> rr.push(b'c', '2')
>>> rr.push(b'd', '2')
>>> rr.pop()
b'a'
>>> rr.pop()
b'c'
>>> rr.pop()
b'b'
>>> rr.pop()
b'd'

Clearing a queue

clear() removes every item from a queue, freeing the disk space that they used, and leaves the queue open and usable:

>>> q.clear()
>>> len(q)
0

PriorityQueue and RoundRobinQueue also close their internal queues, the same way that pop() does when one of them becomes empty.

Disk persistence

FifoDiskQueue and LifoDiskQueue write their items to the path they get on instantiation, so that a queue can be resumed later, even by a different process.

Each class uses that path differently:

  • FifoDiskQueue uses a directory, which it creates, together with any missing parent directory. Items go into chunk files (q00000, q00001, etc.), each holding up to chunksize items, and the queue also keeps an info.json file there for its own bookkeeping.

  • LifoDiskQueue uses a single file, whose parent directory must already exist.

The layout and the contents of those files are an implementation detail that may change in any release. Do not read or write them yourself, and do not expect a queue written by one version of Queuelib to be readable by a different one.

Always close disk queues

While a disk queue is open, its bookkeeping (number of items, read and write positions) only lives in memory, and close() is what writes it to disk. Queuelib never calls fsync() either, and LifoDiskQueue writes items through a buffered file object, so the most recent items may not have reached the disk at all.

Calling close() is hence mandatory:

from contextlib import closing

with closing(FifoDiskQueue("queuedir")) as q:
    q.push(b'a')

If a process ends without calling close(), the queue on disk keeps the bookkeeping that the last close() call wrote, which no longer matches the files. Items pushed since then become unreachable, and using the queue again is unsafe: it may report a wrong length, return items that had already been popped, delete files that still contain items, or raise OSError. Queuelib offers no way to repair or to recover such a queue.

Empty queues delete their files

close() on an empty queue deletes its file, or, in the case of FifoDiskQueue, its chunk files and its info.json file, and also its directory if nothing else remains in it. Using that same path again creates a new, empty queue.

FifoDiskQueue frees disk space one chunk at a time

FifoDiskQueue deletes a chunk file once every item in it has been popped. Until then, popped items keep using disk space, so a queue uses up to chunksize items worth of disk space on top of the items that it holds.

Lower chunksize to lower that overhead, at the cost of more chunk files and more file operations. For example, a queue that holds 400 items of 1 MB each uses about 100 GB of disk space with the default chunksize of 100000, and about 800 MB with a chunksize of 400.

Reopening a FifoDiskQueue keeps its chunk size

FifoDiskQueue stores its chunksize when creating a queue, and reuses the stored value when reopening one, ignoring the chunksize parameter.

Use one queue object per path at a time

Queuelib does not lock the files that it uses. On top of not being thread-safe, a given path must not be used by more than one open queue object at a time, in the same process or not. Such queue objects overwrite each other’s items and bookkeeping; for example, two FifoDiskQueue objects on the same directory return the same items, and their close() calls may raise FileNotFoundError.

Persisting a PriorityQueue or a RoundRobinQueue

PriorityQueue and RoundRobinQueue do not write anything to disk themselves; their persistence comes entirely from the queues that qfactory builds, and it is up to qfactory to map a priority or a key to a valid path.

Their close() method returns the priorities or keys whose underlying queue was not empty. Storing that value is your responsibility, and so is passing it back as startprios or start_domains on the next run:

>>> import json
>>> from queuelib import FifoDiskQueue, PriorityQueue
>>> qfactory = lambda priority: FifoDiskQueue('queue-dir-%s' % priority)
>>> pq = PriorityQueue(qfactory)
>>> pq.push(b'a', 3)
>>> active = pq.close()
>>> with open('active.json', 'w') as f:
...     json.dump(active, f)
...
>>> with open('active.json') as f:
...     startprios = json.load(f)
...
>>> pq = PriorityQueue(qfactory, startprios)
>>> pq.pop()
b'a'

Priorities and keys that you do not pass back are not detected, and the items in their queues stay on disk, unreachable.

Bug tracker

If you have any suggestions, bug reports or annoyances please report them to our issue tracker at: http://github.com/scrapy/queuelib/issues/

Contributing

Development of Queuelib happens at GitHub: http://github.com/scrapy/queuelib

You are highly encouraged to participate in the development. If you don’t like GitHub (for some reason) you’re welcome to send regular patches.

All changes require tests to be merged.

Tests

Tests are located in queuelib/tests directory. They can be run using nosetests with the following command:

nosetests

The output should be something like the following:

$ nosetests
.............................................................................
----------------------------------------------------------------------
Ran 77 tests in 0.145s

OK

License

This software is licensed under the BSD License. See the LICENSE file in the top distribution directory for the full license text.

Versioning

This software follows Semantic Versioning

Release files for queuelib 1.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for queuelib 1.10.0
File Size Uploaded
queuelib-1.10.0.tar.gz 14.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for queuelib 1.10.0
File Interpreter ABI Platform
queuelib-1.10.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.5 kB

Release files / queuelib-1.10.0.tar.gz

Download URL queuelib-1.10.0.tar.gz
Size 14.3 kB
Tags Source
SHA-256 checksum
How to use checksums
063c821c32859ae8bdce2cc9e74156645c074218a464f8262e29a3b8de839737
BLAKE2b-256 checksum
How to use checksums
b3b3d9da691d2729b00b63cc67869aaf96fb9b612bd3ec6acba30f3af2a33d32
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / queuelib-1.10.0-py3-none-any.whl

Download URL queuelib-1.10.0-py3-none-any.whl
Size 16.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
257936b7202d12325c80ad79e254c59e2cd3533704ae6dffb567b1a0b309ae5e
BLAKE2b-256 checksum
How to use checksums
bc78715c431c72ab296e1d4540e9dbbbc78f086bed3cdb04fc68fb32c6232d0b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.10.0 This release

2 release files

1.9.0

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.5.0

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.2

2 release files

1.2.1

1.2.0

1.1.1

1 release file

1.1

1 release file

1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page