Install & Compatibility
Where this runs
tested against v? · pip install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
build_error
glibcpy 3.10–3.95 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
AnnoyIndex
✓ from annoy import AnnoyIndex
This example demonstrates how to initialize an Annoy index, add items (vectors), build the index for efficient search, save it to disk, load it back (memory-mapped), and then perform nearest neighbor queries using an item ID or a new vector. The `AnnoyIndex` constructor takes the vector dimension `f` and the distance `metric` (e.g., 'euclidean', 'angular'). The `build` method specifies the number of trees (`n_trees`) and jobs (`n_jobs`).
import os
from annoy import AnnoyIndex
import random
f = 40 # Length of item vector that will be indexed
t = AnnoyIndex(f, 'euclidean') # or 'angular', 'manhattan', 'hamming', 'dot'
# Add items to the index
for i in range(1000):
v = [random.gauss(0, 1) for _ in range(f)]
t.add_item(i, v)
# Build the index with n_trees trees. n_jobs=-1 uses all CPU cores.
t.build(10, n_jobs=-1)
# Save and load the index
index_path = 'test.ann'
t.save(index_path)
u = AnnoyIndex(f, 'euclidean')
u.load(index_path) # super fast, will just mmap the file
# Query for nearest neighbors
query_item_id = 0
k = 10 # Number of neighbors to retrieve
nearest_neighbors = u.get_nns_by_item(query_item_id, k)
print(f"Nearest neighbors for item {query_item_id}: {nearest_neighbors}")
query_vector = [random.gauss(0, 1) for _ in range(f)]
nearest_neighbors_by_vector = u.get_nns_by_vector(query_vector, k)
print(f"Nearest neighbors for a random vector: {nearest_neighbors_by_vector}")
# Clean up the created index file
if os.path.exists(index_path):
os.remove(index_path)
Debug
Known issues
gotchaOnce the `build()` method is called on an `AnnoyIndex` instance, no more items can be added to that index. Annoy is designed for static, read-only indexes after creation. If you need a mutable index, consider rebuilding or using an alternative library.fixPlan your data ingestion to add all items before calling `.build()`. If your dataset changes, you must rebuild the entire index.
affects: All versions
gotchaItem IDs must be non-negative integers. Annoy allocates memory for `max(id)+1` items, assuming dense integer IDs from 0 to N-1. Using sparse or very large IDs can lead to excessive memory allocation or unexpected behavior.fixMap your arbitrary item identifiers to a dense range of non-negative integers (e.g., 0, 1, ..., N-1) before adding them to Annoy.
affects: All versions
gotchaThe `n_trees` parameter (during build) affects build time and index size; higher values give better accuracy but larger indexes. The `search_k` parameter (during search) affects search time; higher values give better accuracy but longer search times. You must tune these parameters for your specific accuracy and performance needs.fixExperiment with different `n_trees` (e.g., 10-1000) during index creation and `search_k` (e.g., `n_trees * 2` or more) during query time to find the optimal trade-off for your dataset and latency requirements.
affects: All versions
deprecatedOlder versions (prior to 1.17.2) were known to have memory leaks, especially during index building or repeated operations.fixUpgrade to version 1.17.2 or newer to benefit from memory leak fixes.
affects: <1.17.2
breakingVersion 1.16.1 introduced stricter checks, preventing saving an index that hasn't been built or building an index that has already been built.fixEnsure `build()` is called exactly once before `save()`, and only call `build()` on an index that has not been built yet.
affects: >=1.16.1
gotchaCompilation issues have occurred on specific platforms, such as OS X (fixed in 1.17.3) and certain GCC versions with AVX instructions (fixed in 1.16.1). These can prevent successful installation or lead to runtime errors.fixEnsure you are using the latest stable version of Annoy. If issues persist, check the GitHub issues for platform-specific workarounds or compiler flags.
affects: Various pre-1.17.3, pre-1.16.1
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'annoy'
The 'annoy' library is not installed in the Python environment.
fixInstall the 'annoy' library using pip: 'pip install annoy'.
ImportError: cannot import name 'AnnoyIndex' from 'annoy'
Incorrect import statement; 'AnnoyIndex' should be imported directly from 'annoy'.
fixUse the correct import statement: 'from annoy import AnnoyIndex'.
TypeError: 'NoneType' object is not subscriptable
Attempting to access elements of a None object, possibly due to a failed 'AnnoyIndex' initialization.
fixEnsure 'AnnoyIndex' is properly initialized with correct parameters before use.
ValueError: Number of trees must be greater than zero
The 'n_trees' parameter in 'AnnoyIndex.build()' is set to zero or a negative number.
fixSet 'n_trees' to a positive integer when building the index: 'index.build(n_trees)'.
RuntimeError: You must build the index before querying
Attempting to query the 'AnnoyIndex' before building it.
fixBuild the index using 'index.build(n_trees)' before performing queries.
Upgrade
Version history
1.17.3latest on PyPI · released Jun 14, 2023
Audit
Dependencies
No dependency data recorded yet.