if you are using a remote docstore, its persisted automatically (same with your vector store)
imo I would attach a docstore + vector store to an ingestion pipeline to properly handle upserts, its the most straight forward
pipeline = IngestionPipeline(
transformations=[SentenceSplitter(), OpenAIEmbedding()]
docstore=<docstore>,
vector_store=<vector_store>
)
# very important that documents have a static ID, like a file path
documents = SimpleDirectoryReader(..., filename_as_id=True).load_data()
pipeline.run(documents=documents)
index = VectorStoreIndex.from_vector_store(<vector_store>)