A LlamaIndex index can retain stale text when a source changes but the application keeps using the previously indexed nodes. Refreshing by document ID replaces only the changed document while leaving unrelated index content in place.
The refresh_ref_docs() method compares each incoming document with the hash stored for the same ID. It inserts a missing ID, rebuilds an ID whose text or metadata changed, and skips an unchanged document.
Document identity therefore matters more than the filename or loader used to obtain the text. Keep each doc_id stable across refreshes, use the same embedding model when reloading the index, and persist the storage context after the refresh so another process can load the replacement nodes.
Steps to refresh updated LlamaIndex index documents:
- Install LlamaIndex core in the active Python environment.
$ python3 -m pip install --upgrade llama-index-core
The environment that builds and serves the index needs this package. The full llama-index package also installs llama-index-core.
Related: How to install LlamaIndex with pip - Create refresh_updated_documents.py with the imports and local test storage.
- refresh_updated_documents.py
from pathlib import Path import shutil from llama_index.core import ( Document, MockEmbedding, Settings, StorageContext, VectorStoreIndex, load_index_from_storage, ) Settings.embed_model = MockEmbedding(embed_dim=8) storage_dir = Path("storage") shutil.rmtree(storage_dir, ignore_errors=True)
MockEmbedding makes the test deterministic without an API key. An existing index requires the embedding model that created its stored vectors.
The last line deletes the local storage directory before the test. Retained data requires a disposable storage_dir value and omission of that reset line.
- Add the original document and initial index below the storage setup.
original = Document( text="Escalate payment failures to the billing queue.", id_="support-policy", ) index = VectorStoreIndex.from_documents([original]) index.storage_context.persist(persist_dir=storage_dir)
The explicit support-policy ID is the lookup key that connects the original and replacement documents.
- Define the replacement document below the initial persistence block.
updated = Document( text="Escalate payment failures to the revenue operations queue.", id_="support-policy", )
- Load the persisted index below the replacement document.
storage_context = StorageContext.from_defaults(persist_dir=storage_dir) index = load_index_from_storage(storage_context)
- Refresh the matching document ID.
refresh_flags = index.refresh_ref_docs([updated])
refresh_ref_docs() returns one Boolean per input document. True means that document was inserted or updated; False means its stored hash already matched.
- Persist the changed index to storage_dir.
index.storage_context.persist(persist_dir=storage_dir)
- Append a reload-based retrieval check below the refresh block.
storage_context = StorageContext.from_defaults(persist_dir=storage_dir) index = load_index_from_storage(storage_context) nodes = index.as_retriever(similarity_top_k=1).retrieve("payment failures") print(f"Refresh flags: {refresh_flags}") print(f"Reloaded text: {nodes[0].node.get_content(metadata_mode='none')}")
- Compare the completed refresh_updated_documents.py file with the assembled program.
- refresh_updated_documents.py
from pathlib import Path import shutil from llama_index.core import ( Document, MockEmbedding, Settings, StorageContext, VectorStoreIndex, load_index_from_storage, ) Settings.embed_model = MockEmbedding(embed_dim=8) storage_dir = Path("storage") shutil.rmtree(storage_dir, ignore_errors=True) original = Document( text="Escalate payment failures to the billing queue.", id_="support-policy", ) index = VectorStoreIndex.from_documents([original]) index.storage_context.persist(persist_dir=storage_dir) updated = Document( text="Escalate payment failures to the revenue operations queue.", id_="support-policy", ) storage_context = StorageContext.from_defaults(persist_dir=storage_dir) index = load_index_from_storage(storage_context) refresh_flags = index.refresh_ref_docs([updated]) index.storage_context.persist(persist_dir=storage_dir) storage_context = StorageContext.from_defaults(persist_dir=storage_dir) index = load_index_from_storage(storage_context) nodes = index.as_retriever(similarity_top_k=1).retrieve("payment failures") print(f"Refresh flags: {refresh_flags}") print(f"Reloaded text: {nodes[0].node.get_content(metadata_mode='none')}")
- Run the completed program to confirm that a reloaded index retrieves the replacement text.
$ python3 refresh_updated_documents.py Refresh flags: [True] Reloaded text: Escalate payment failures to the revenue operations queue.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.