Skip to main content

fastquadtree

Interactive Screenshot

Rust-optimized quadtree with a clean Python API

👉 Check out the Docs: https://elan456.github.io/fastquadtree/

PyPI Python versions Downloads Build No runtime deps

PyO3 maturin Ruff

Docs Wheels Coverage License: MIT


Why use fastquadtree

  • Just pip install: prebuilt wheels for Windows, macOS, and Linux (no Rust or compiler needed)
  • The fastest quadtree Python package (>10x faster than pyqtree)
  • Clean Python API with no external dependencies and modern typing hints
  • Support for inserting bounding boxes or points
  • Fast KNN and range queries
  • Optional object tracking for id ↔ object mapping
  • Mostly drop-in pygame sprite-group integration that adds automatic broadphase culling plus rect queries and k-NN over sprite rects
  • Fast serialization to/from bytes
  • Support for multiple data types (f32, f64, i32, i64) for coordinates
  • 100% test coverage and CI on GitHub Actions
  • Offers a drop-in pyqtree shim that is ~10x faster while keeping the same API

Install

pip install fastquadtree
from fastquadtree import QuadTree # Or any of the other classes mentioned below
from fastquadtree.pyqtree import Index  # Drop-in pyqtree shim (~10x faster while keeping the same API)

Which class should I use?

Class Stores Object tracking Best when
QuadTree Points No Fast point indexing with IDs only.
RectQuadTree Bounding boxes No Fast rectangle overlap queries.
QuadTreeObjects Points Yes Point indexing with attached Python objects.
RectQuadTreeObjects Bounding boxes Yes Rectangle indexing with attached objects.
fastquadtree.pyqtree.Index Bounding boxes Yes pyqtree-compatible API, much faster.
fastquadtree.pygame.Group pygame sprites Yes Mostly drop-in Group with sprite queries.

Quickstart

1. Point indexing (QuadTree)

from fastquadtree import QuadTree

qt = QuadTree((0.0, 0.0, 1000.0, 1000.0), capacity=16)

# Insert points with explicit IDs (or omit id_ for auto IDs)
qt.insert((100.0, 200.0), id_=1)
qt.insert((120.0, 260.0), id_=2)
qt.insert((700.0, 800.0), id_=3)

# Range query returns (id, x, y)
hits = qt.query((0.0, 0.0, 500.0, 500.0))
print(hits)  # [(1, 100.0, 200.0), (2, 120.0, 260.0)]

2. Object tracking (QuadTreeObjects)

from fastquadtree import QuadTreeObjects

qto = QuadTreeObjects((0.0, 0.0, 1000.0, 1000.0), capacity=16)

player = {"name": "player-1", "team": "blue"}
enemy = {"name": "enemy-9", "team": "red"}

qto.insert((100.0, 200.0), obj=player)
qto.insert((130.0, 220.0), obj=enemy)

# Query returns PointItem objects with id_, x, y, geom, and obj
for item in qto.query((0.0, 0.0, 300.0, 300.0)):
    print(item.id_, item.x, item.y, item.obj["name"]) # 0 100.0 200.0 player-1
                                                      # 1 130.0 220.0 enemy-9

# Remove entries by object identity
qto.delete_by_object(player)  # returns 1 (number of items deleted)

See the quickstart guide or the interactive demos for more details.

Benchmarks

fastquadtree outperforms all other quadtree Python packages, including the Rtree spatial index.

Library comparison

Total time Throughput

Summary (PyQtree baseline, sorted by total time)

  • Points: 500,000, Queries: 500
Library Build (s) Query (s) Total (s) Speed vs PyQtree
fastquadtree (np)1 0.052 0.017 0.068 42.52×
fastquadtree2 0.054 0.231 0.285 10.20×
Shapely STRtree3 0.200 0.110 0.309 9.40×
fastquadtree (obj tracking)4 0.263 0.093 0.356 8.17×
nontree-QuadTree 0.826 0.844 1.670 1.74×
Rtree 1.805 0.546 2.351 1.24×
e-pyquadtree 1.530 0.941 2.471 1.18×
quads 1.907 0.759 2.667 1.09×
PyQtree 2.495 0.414 2.909 1.00×

See the benchmark section for details, including configurations, system info, and native vs shim benchmarks.

API

See the full API

QuadTree(bounds, capacity, max_depth=None, dtype="f32")

  • bounds — tuple (min_x, min_y, max_x, max_y) defines the 2D area covered by the quadtree
  • capacity — max number of points kept in a leaf before splitting
  • max_depth — optional depth cap. If omitted, uses the engine default
  • dtype — data type for coordinates, e.g., "f32", "f64", "i32", "i64"

Key Methods

  • insert(xy, id_=None) -> int

  • query(rect) -> list[tuple[int, float, float]]

  • nearest_neighbor(xy) -> tuple[int, float, float] | None

  • delete(id, x, y) -> bool

For object tracking, use QuadTreeObjects instead. See the docs for more methods.

Geometric conventions

  • Rectangles are (min_x, min_y, max_x, max_y).
  • Containment rule is closed on the min edge and open on the max edge (x >= min_x and x < max_x and y >= min_y and y < max_y). This only matters for points exactly on edges.

Performance tips

  • Choose capacity so that leaves keep a small batch of points. Typical values are 8 to 64.
  • If your data is very skewed, set a max_depth to prevent long chains.
  • For fastest local runs, use maturin develop --release.
  • Use QuadTree when you only need spatial indexing. Use QuadTreeObjects when you need to store Python objects with your points.
  • Refer to the Native vs Shim Benchmark for overhead details.

Pygame Ball Pit Demo

Ballpit_Demo_Screenshot

A simple demo of moving objects with collision detection using fastquadtree. You can toggle between fastquadtree, pyqtree, and brute-force mode to see the performance difference. I typically see an FPS of ~70 with fastquadtree, ~25 with pyqtree, and <1 FPS with brute-force on my machine with 1500 balls.

See the runnables guide for setup instructions.

FAQ

Can I delete items from the quadtree? Yes! Use delete(id, x, y) to remove specific items. You must provide both the ID and exact location for precise deletion. This handles cases where multiple items exist at the same location. If you're using QuadTreeObjects, you can also use delete_by_object(obj) for convenient object-based deletion with O(1) lookup. The tree automatically merges nodes when item counts drop below capacity.

Can I store rectangles or circles? Yes, you can store rectangles using the RectQuadTree class. Circles can be approximated with bounding boxes. See the RectQuadTree docs for details.

Do I need NumPy installed? No, NumPy is a fully optional dependency. If you do have NumPy installed, you can use methods such as query_np and insert_many_np for better performance. Note that insert_many raises TypeError on NumPy input—you must use insert_many_np explicitly for NumPy arrays. The Rust core is able to handle NumPy arrays faster than Python lists, so there's a lot of time savings in utilizing the NumPy functions. See the Native vs Shim benchmark for details on how returing NumPy arrays can speed up queries.

# Using Python lists
qt.insert_many([(10, 20), (30, 40), (50, 60)])

# Using NumPy arrays (requires NumPy)
import numpy as np
points = np.array([[10, 20], [30, 40], [50, 60]])
qt.insert_many_np(points)  # Use insert_many_np for NumPy arrays

Does fastquadtree support multiprocessing? Yes, fastquadtree objects can be serialized to bytes using the to_bytes() method and deserialized back using from_bytes(). This allows you to share quadtree data across processes and even cache prebuilt trees to disk. When using QuadTreeObjects or RectQuadTreeObjects, you must pass include_objects=True to to_bytes() to serialize Python objects, and allow_objects=True to from_bytes() when loading. By default, objects are skipped for safety, as deserializing untrusted Python objects can be unsafe. Native decode uses a default preallocation limit of 67,108,864 bytes (64 MiB); if loading needs more than the configured bucket, from_bytes() fails with a ValueError unless you choose a larger allowed bucket or pass disable_preallocation_limit=True for trusted data. See the interactive v2 demo for an example of saving and loading a quadtree, and the QuadTreeObjects API docs for full details on the serialization methods.

Serialization uses the current fastquadtree binary format. Data serialized by bincode-backed fastquadtree releases, including v2.2 and earlier, is not loadable by newer wincode-backed releases.

License

MIT. See LICENSE.

Acknowledgments

  1. Uses query_np for Numpy array return values rather than Python lists. ↩

  2. Uses standard query method returning Python lists. ↩

  3. Uses Shapely STRtree with Numpy array points and returns. ↩

  4. Uses QuadTreeObjects with object association. ↩

Metadata

Release files for fastquadtree 2.4.2

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

Source distribution (sdist)

Source distribution for fastquadtree 2.4.2
File Size Uploaded
fastquadtree-2.4.2.tar.gz 949.9 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for fastquadtree 2.4.2
File
fastquadtree-2.4.2-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
fastquadtree-2.4.2-cp39-abi3-pyemscripten_2026_0_wasm32.whl CPython 3.9 abi3 PyEmscripten 2026.0+ WebAssembly Details
fastquadtree-2.4.2-cp39-abi3-pyemscripten_2025_0_wasm32.whl CPython 3.9 abi3 PyEmscripten 2025.0+ WebAssembly Details
fastquadtree-2.4.2-cp39-abi3-manylinux_2_28_x86_64.whl CPython 3.9 abi3 Linux glibc 2.28+ x86-64 Details
fastquadtree-2.4.2-cp39-abi3-manylinux_2_28_armv7l.whl CPython 3.9 abi3 Linux glibc 2.28+ ARMv7l Details
fastquadtree-2.4.2-cp39-abi3-manylinux_2_28_aarch64.whl CPython 3.9 abi3 Linux glibc 2.28+ ARM64 Details
fastquadtree-2.4.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl CPython 3.9 abi3 macOS 10.12+ x86-64, macOS 10.12+ universal2 (ARM64, x86-64), macOS 11.0+ ARM64 Details

Total release size: 3.9 MB

Release files / fastquadtree-2.4.2.tar.gz

Download URL fastquadtree-2.4.2.tar.gz
Size 949.9 kB
Tags Source
SHA-256 checksum
How to use checksums
d8eff682571e54179ed2b389bfed58e529611bf914945f7fe798e66edeee318e
BLAKE2b-256 checksum
How to use checksums
71fc64bfc68c0b2bcdb4cbd1cfd4a33379855dd8a1d8713cd9d5a7ad3f06aaf9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fastquadtree-2.4.2-cp39-abi3-win_amd64.whl

Download URL fastquadtree-2.4.2-cp39-abi3-win_amd64.whl
Size 318.5 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
f45a72f868ac698ef668b7747e6f876e45347009fc1ae5ea2f09afd054fd4653
BLAKE2b-256 checksum
How to use checksums
0795d79860a954a3aef47bb8861d1091a36ea233344e60aa579d46884172e4ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fastquadtree-2.4.2-cp39-abi3-pyemscripten_2026_0_wasm32.whl

Download URL fastquadtree-2.4.2-cp39-abi3-pyemscripten_2026_0_wasm32.whl
Size 208.6 kB
Tags CPython 3.9 PyEmscripten 2026.0+ WebAssembly abi3
SHA-256 checksum
How to use checksums
af19ad98c5131cafb5f2838a3fdf3ec64250e9e775fce5931b71759c46502959
BLAKE2b-256 checksum
How to use checksums
9278819cca848bdf5690c8acd19246b3455396b7cb00abe4ce0c59459c9b54c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fastquadtree-2.4.2-cp39-abi3-pyemscripten_2025_0_wasm32.whl

Download URL fastquadtree-2.4.2-cp39-abi3-pyemscripten_2025_0_wasm32.whl
Size 208.6 kB
Tags CPython 3.9 PyEmscripten 2025.0+ WebAssembly abi3
SHA-256 checksum
How to use checksums
3ebc6508810c87ede4bafcb91d0d26ad4a198822851e9db2e18b728d9260b59e
BLAKE2b-256 checksum
How to use checksums
65c795f0b0a37c473b1e40976508bf903c846ffe6261faad3601dd6a63eccf8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fastquadtree-2.4.2-cp39-abi3-manylinux_2_28_x86_64.whl

Download URL fastquadtree-2.4.2-cp39-abi3-manylinux_2_28_x86_64.whl
Size 471.6 kB
Tags CPython 3.9 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
b226e3eddd0aee6413275848fa543205ec8adf1c23b05a269e44dd12b9035171
BLAKE2b-256 checksum
How to use checksums
13da65db13bf90e4ecd1dd05a91af4ff199c0024de387c1ad0b9d364304c041c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fastquadtree-2.4.2-cp39-abi3-manylinux_2_28_armv7l.whl

Download URL fastquadtree-2.4.2-cp39-abi3-manylinux_2_28_armv7l.whl
Size 505.2 kB
Tags CPython 3.9 Linux glibc 2.28+ ARMv7l abi3
SHA-256 checksum
How to use checksums
6f4411ed464694e292f984996f75b00440f573dd1bd57debd3da63487a09c9bd
BLAKE2b-256 checksum
How to use checksums
84a8c88b9a0df493ac4c4aa1e08355e248eba8860c5fd051109f873843a806cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fastquadtree-2.4.2-cp39-abi3-manylinux_2_28_aarch64.whl

Download URL fastquadtree-2.4.2-cp39-abi3-manylinux_2_28_aarch64.whl
Size 456.2 kB
Tags CPython 3.9 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
cb0b6e1a096a710aaa7d73e052f035e62c0ae22fbcb0be07bf7ad90ff1674403
BLAKE2b-256 checksum
How to use checksums
2f3165138e6497e2e078c1162a03d10e5f452ab717604080e0535aa2b8c4f841
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fastquadtree-2.4.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL fastquadtree-2.4.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 817.1 kB
Tags CPython 3.9 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
3ff3b013a06e2308a5d97dd5f19d88b7bbe174eefad63204888fa5f2004b7b50
BLAKE2b-256 checksum
How to use checksums
4cb3bb699392d7de853b432e08e6625d29acc92eab9200386f609ebc65b2beb9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

2.4.2 This release

8 release files

2.4.1

7 release files

2.4.0

6 release files

2.3.0

6 release files

2.2.0

6 release files

2.1.1

10 release files

2.1.0

10 release files

2.0.4

10 release files

2.0.2

6 release files

2.0.1

6 release files

2.0.0

6 release files

1.5.2

6 release files

1.5.1

6 release files

1.5.0

6 release files

1.4.3

6 release files

1.4.2

6 release files

1.4.1

6 release files

1.4.0

6 release files

1.3.2

6 release files

1.3.1

6 release files

1.3.0

6 release files

1.2.3

6 release files

1.2.1

6 release files

1.2.0

6 release files

1.1.2

6 release files

1.1.1

6 release files

1.1.0

6 release files

1.0.2

6 release files

1.0.1

6 release files

1.0.0

6 release files

0.9.1

6 release files

0.9.0

6 release files

0.8.1

6 release files

0.8.0

6 release files

0.7.0

6 release files

0.6.1

6 release files

0.6.0

4 release files

0.5.1

4 release files

0.5.0

4 release files

0.4.2

4 release files

0.4.1

4 release files

0.4.0

4 release files

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