Storage¶
Base classes and types for persistent key-value stores.
Stores provide long-term memory that persists across threads and conversations. Supports hierarchical namespaces, key-value storage, and optional vector search.
Core types
- BaseStore: Store interface with sync/async operations
- Item: Stored key-value pairs with metadata
- Op: Get/Put/Search/List operations
NamespacePath = tuple[Union[str, Literal['*']], ...]
module-attribute
¶
NamespaceMatchType = Literal['prefix', 'suffix']
module-attribute
¶
Specifies how to match namespace paths.
Values
"prefix": Match from the start of the namespace "suffix": Match from the end of the namespace
Item
¶
Represents a stored item with metadata.
Parameters:
-
value(dict[str, Any]) –The stored data as a dictionary. Keys are filterable.
-
key(str) –Unique identifier within the namespace.
-
namespace(tuple[str, ...]) –Hierarchical path defining the collection in which this document resides. Represented as a tuple of strings, allowing for nested categorization. For example: ("documents", 'user123')
-
created_at(datetime) –Timestamp of item creation.
-
updated_at(datetime) –Timestamp of last update.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
SearchItem
¶
Bases: Item
Represents an item returned from a search operation with additional metadata.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
__init__(namespace: tuple[str, ...], key: str, value: dict[str, Any], created_at: datetime, updated_at: datetime, score: Optional[float] = None) -> None
¶
Initialize a result item.
Parameters:
-
namespace(tuple[str, ...]) –Hierarchical path to the item.
-
key(str) –Unique identifier within the namespace.
-
value(dict[str, Any]) –The stored value.
-
created_at(datetime) –When the item was first created.
-
updated_at(datetime) –When the item was last updated.
-
score(Optional[float], default:None) –Relevance/similarity score if from a ranked operation.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
GetOp
¶
Bases: NamedTuple
Operation to retrieve a specific item by its namespace and key.
This operation allows precise retrieval of stored items using their full path (namespace) and unique identifier (key) combination.
Examples
Basic item retrieval:
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
SearchOp
¶
Bases: NamedTuple
Operation to search for items within a specified namespace hierarchy.
This operation supports both structured filtering and natural language search within a given namespace prefix. It provides pagination through limit and offset parameters.
Note
Natural language search support depends on your store implementation.
Examples
Search with filters and pagination:
SearchOp(
namespace_prefix=("documents",),
filter={"type": "report", "status": "active"},
limit=5,
offset=10
)
Natural language search:
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | |
namespace_prefix: tuple[str, ...]
instance-attribute
¶
filter: Optional[dict[str, Any]] = None
class-attribute
instance-attribute
¶
Key-value pairs for filtering results based on exact matches or comparison operators.
The filter supports both exact matches and operator-based comparisons.
Supported Operators
- $eq: Equal to (same as direct value comparison)
- $ne: Not equal to
- $gt: Greater than
- $gte: Greater than or equal to
- $lt: Less than
- $lte: Less than or equal to
limit: int = 10
class-attribute
instance-attribute
¶
Maximum number of items to return in the search results.
offset: int = 0
class-attribute
instance-attribute
¶
Number of matching items to skip for pagination.
query: Optional[str] = None
class-attribute
instance-attribute
¶
Natural language search query for semantic search capabilities.
Examples
- "technical documentation about REST APIs"
- "machine learning papers from 2023"
MatchCondition
¶
Bases: NamedTuple
Represents a pattern for matching namespaces in the store.
This class combines a match type (prefix or suffix) with a namespace path pattern that can include wildcards to flexibly match different namespace hierarchies.
Examples
Prefix matching:
Suffix matching with wildcard:
Simple suffix matching:
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
ListNamespacesOp
¶
Bases: NamedTuple
Operation to list and filter namespaces in the store.
This operation allows exploring the organization of data, finding specific collections, and navigating the namespace hierarchy.
Examples
List all namespaces under the "documents" path:
ListNamespacesOp(
match_conditions=(MatchCondition(match_type="prefix", path=("documents",)),),
max_depth=2
)
List all namespaces that end with "v1":
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
match_conditions: Optional[tuple[MatchCondition, ...]] = None
class-attribute
instance-attribute
¶
Optional conditions for filtering namespaces.
max_depth: Optional[int] = None
class-attribute
instance-attribute
¶
Maximum depth of namespace hierarchy to return.
Note
Namespaces deeper than this level will be truncated.
limit: int = 100
class-attribute
instance-attribute
¶
Maximum number of namespaces to return.
offset: int = 0
class-attribute
instance-attribute
¶
Number of namespaces to skip for pagination.
PutOp
¶
Bases: NamedTuple
Operation to store, update, or delete an item in the store.
This class represents a single operation to modify the store's contents, whether adding new items, updating existing ones, or removing them.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | |
namespace: tuple[str, ...]
instance-attribute
¶
Hierarchical path that identifies the location of the item.
The namespace acts as a folder-like structure to organize items. Each element in the tuple represents one level in the hierarchy.
key: str
instance-attribute
¶
Unique identifier for the item within its namespace.
The key must be unique within the specific namespace to avoid conflicts. Together with the namespace, it forms a complete path to the item.
Example
If namespace is ("documents", "user123") and key is "report1", the full path would effectively be "documents/user123/report1"
value: Optional[dict[str, Any]]
instance-attribute
¶
The data to store, or None to mark the item for deletion.
The value must be a dictionary with string keys and JSON-serializable values. Setting this to None signals that the item should be deleted.
Example
{ "field1": "string value", "field2": 123, "nested": {"can": "contain", "any": "serializable data"} }
index: Optional[Union[Literal[False], list[str]]] = None
class-attribute
instance-attribute
¶
Controls how the item's fields are indexed for search operations.
Indexing configuration determines how the item can be found through search
- None (default): Uses the store's default indexing configuration (if provided)
- False: Disables indexing for this item
- list[str]: Specifies which json path fields to index for search
The item remains accessible through direct get() operations regardless of indexing. When indexed, fields can be searched using natural language queries through vector similarity search (if supported by the store implementation).
Path Syntax
- Simple field access: "field"
- Nested fields: "parent.child.grandchild"
- Array indexing:
- Specific index: "array[0]"
- Last element: "array[-1]"
- All elements (each individually): "array[*]"
Examples
- None - Use store defaults (whole item)
- list[str] - List of fields to index
[
"metadata.title", # Nested field access
"context[*].content", # Index content from all context as separate vectors
"authors[0].name", # First author's name
"revisions[-1].changes", # Most recent revision's changes
"sections[*].paragraphs[*].text", # All text from all paragraphs in all sections
"metadata.tags[*]", # All tags in metadata
]
InvalidNamespaceError
¶
Bases: ValueError
Provided namespace is invalid.
IndexConfig
¶
Bases: TypedDict
Configuration for indexing documents for semantic search in the store.
If not provided to the store, the store will not support vector search.
In that case, all index arguments to put() and aput() operations will be ignored.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | |
dims: int
instance-attribute
¶
Number of dimensions in the embedding vectors.
embed: Union[Embeddings, EmbeddingsFunc, AEmbeddingsFunc]
instance-attribute
¶
Optional function to generate embeddings from text.
Can be specified in three ways
- A LangChain Embeddings instance
- A synchronous embedding function (EmbeddingsFunc)
- An asynchronous embedding function (AEmbeddingsFunc)
Examples
Using LangChain's initialization with InMemoryStore:
from langchain.embeddings import init_embeddings
from langgraph.store.memory import InMemoryStore
store = InMemoryStore(
index={
"dims": 1536,
"embed": init_embeddings("openai:text-embedding-3-small")
}
)
Using a custom embedding function with InMemoryStore:
from openai import OpenAI
from langgraph.store.memory import InMemoryStore
client = OpenAI()
def embed_texts(texts: list[str]) -> list[list[float]]:
response = client.embeddings.create(
model="text-embedding-3-small",
input=texts
)
return [e.embedding for e in response.data]
store = InMemoryStore(
index={
"dims": 1536,
"embed": embed_texts
}
)
Using an asynchronous embedding function with InMemoryStore:
from openai import AsyncOpenAI
from langgraph.store.memory import InMemoryStore
client = AsyncOpenAI()
async def aembed_texts(texts: list[str]) -> list[list[float]]:
response = await client.embeddings.create(
model="text-embedding-3-small",
input=texts
)
return [e.embedding for e in response.data]
store = InMemoryStore(
index={
"dims": 1536,
"embed": aembed_texts
}
)
fields: Optional[list[str]]
instance-attribute
¶
Fields to extract text from for embedding generation.
Controls which parts of stored items are embedded for semantic search. Follows JSON path syntax:
- ["$"]: Embeds the entire JSON object as one vector (default)
- ["field1", "field2"]: Embeds specific top-level fields
- ["parent.child"]: Embeds nested fields using dot notation
- ["array[*].field"]: Embeds field from each array element separately
Note
You can always override this behavior when storing an item using the
index parameter in the put or aput operations.
Examples
# Embed entire document (default)
fields=["$"]
# Embed specific fields
fields=["text", "summary"]
# Embed nested fields
fields=["metadata.title", "content.body"]
# Embed from arrays
fields=["messages[*].content"] # Each message content separately
fields=["context[0].text"] # First context item's text
Note
- Fields missing from a document are skipped
- Array notation creates separate embeddings for each element
- Complex nested paths are supported (e.g., "a.b[*].c.d")
BaseStore
¶
Bases: ABC
Abstract base class for persistent key-value stores.
Stores enable persistence and memory that can be shared across threads,
scoped to user IDs, assistant IDs, or other arbitrary namespaces.
Some implementations may support semantic search capabilities through
an optional index configuration.
Note
Semantic search capabilities vary by implementation and are typically
disabled by default. Stores that support this feature can be configured
by providing an index configuration at creation time. Without this
configuration, semantic search is disabled and any index arguments
to storage operations will have no effect.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | |
batch(ops: Iterable[Op]) -> list[Result]
abstractmethod
¶
Execute multiple operations synchronously in a single batch.
Parameters:
-
ops(Iterable[Op]) –An iterable of operations to execute.
Returns:
-
list[Result]–A list of results, where each result corresponds to an operation in the input.
-
list[Result]–The order of results matches the order of input operations.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
abatch(ops: Iterable[Op]) -> list[Result]
abstractmethod
async
¶
Execute multiple operations asynchronously in a single batch.
Parameters:
-
ops(Iterable[Op]) –An iterable of operations to execute.
Returns:
-
list[Result]–A list of results, where each result corresponds to an operation in the input.
-
list[Result]–The order of results matches the order of input operations.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
get(namespace: tuple[str, ...], key: str) -> Optional[Item]
¶
search(namespace_prefix: tuple[str, ...], /, *, query: Optional[str] = None, filter: Optional[dict[str, Any]] = None, limit: int = 10, offset: int = 0) -> list[SearchItem]
¶
Search for items within a namespace prefix.
Parameters:
-
namespace_prefix(tuple[str, ...]) –Hierarchical path prefix to search within.
-
query(Optional[str], default:None) –Optional query for natural language search.
-
filter(Optional[dict[str, Any]], default:None) –Key-value pairs to filter results.
-
limit(int, default:10) –Maximum number of items to return.
-
offset(int, default:0) –Number of items to skip before returning results.
Returns:
-
list[SearchItem]–List of items matching the search criteria.
Examples
Basic filtering:
# Search for documents with specific metadata
results = store.search(
("docs",),
filter={"type": "article", "status": "published"}
)
Natural language search (requires vector store implementation):
# Initialize store with embedding configuration
store = YourStore( # e.g., InMemoryStore, AsyncPostgresStore
index={
"dims": 1536, # embedding dimensions
"embed": your_embedding_function, # function to create embeddings
"fields": ["text"] # fields to embed. Defaults to ["$"]
}
)
# Search for semantically similar documents
results = store.search(
("docs",),
query="machine learning applications in healthcare",
filter={"type": "research_paper"},
limit=5
)
Note: Natural language search support depends on your store implementation and requires proper embedding configuration.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
put(namespace: tuple[str, ...], key: str, value: dict[str, Any], index: Optional[Union[Literal[False], list[str]]] = None) -> None
¶
Store or update an item in the store.
Parameters:
-
namespace(tuple[str, ...]) –Hierarchical path for the item, represented as a tuple of strings. Example: ("documents", "user123")
-
key(str) –Unique identifier within the namespace. Together with namespace forms the complete path to the item.
-
value(dict[str, Any]) –Dictionary containing the item's data. Must contain string keys and JSON-serializable values.
-
index(Optional[Union[Literal[False], list[str]]], default:None) –Controls how the item's fields are indexed for search:
- None (default): Use
fieldsyou configured when creating the store (if any) If you do not initialize the store with indexing capabilities, theindexparameter will be ignored - False: Disable indexing for this item
- list[str]: List of field paths to index, supporting:
- Nested fields: "metadata.title"
- Array access: "chapters[*].content" (each indexed separately)
- Specific indices: "authors[0].name"
- None (default): Use
Note
Indexing support depends on your store implementation.
If you do not initialize the store with indexing capabilities,
the index parameter will be ignored.
Examples
Store item. Indexing depends on how you configure the store.
Do not index item for semantic search. Still accessible through get() and search() operations but won't have a vector representation.
Index specific fields for search.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
delete(namespace: tuple[str, ...], key: str) -> None
¶
list_namespaces(*, prefix: Optional[NamespacePath] = None, suffix: Optional[NamespacePath] = None, max_depth: Optional[int] = None, limit: int = 100, offset: int = 0) -> list[tuple[str, ...]]
¶
List and filter namespaces in the store.
Used to explore the organization of data, find specific collections, or navigate the namespace hierarchy.
Parameters:
-
prefix(Optional[Tuple[str, ...]], default:None) –Filter namespaces that start with this path.
-
suffix(Optional[Tuple[str, ...]], default:None) –Filter namespaces that end with this path.
-
max_depth(Optional[int], default:None) –Return namespaces up to this depth in the hierarchy. Namespaces deeper than this level will be truncated.
-
limit(int, default:100) –Maximum number of namespaces to return (default 100).
-
offset(int, default:0) –Number of namespaces to skip for pagination (default 0).
Returns:
-
list[tuple[str, ...]]–List[Tuple[str, ...]]: A list of namespace tuples that match the criteria.
-
list[tuple[str, ...]]–Each tuple represents a full namespace path up to
max_depth.
???+ example "Examples": Setting max_depth=3. Given the namespaces:
# Example if you have the following namespaces:
# ("a", "b", "c")
# ("a", "b", "d", "e")
# ("a", "b", "d", "i")
# ("a", "b", "f")
# ("a", "c", "f")
store.list_namespaces(prefix=("a", "b"), max_depth=3)
# [("a", "b", "c"), ("a", "b", "d"), ("a", "b", "f")]
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
aget(namespace: tuple[str, ...], key: str) -> Optional[Item]
async
¶
Asynchronously retrieve a single item.
Parameters:
-
namespace(tuple[str, ...]) –Hierarchical path for the item.
-
key(str) –Unique identifier within the namespace.
Returns:
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
asearch(namespace_prefix: tuple[str, ...], /, *, query: Optional[str] = None, filter: Optional[dict[str, Any]] = None, limit: int = 10, offset: int = 0) -> list[SearchItem]
async
¶
Asynchronously search for items within a namespace prefix.
Parameters:
-
namespace_prefix(tuple[str, ...]) –Hierarchical path prefix to search within.
-
query(Optional[str], default:None) –Optional query for natural language search.
-
filter(Optional[dict[str, Any]], default:None) –Key-value pairs to filter results.
-
limit(int, default:10) –Maximum number of items to return.
-
offset(int, default:0) –Number of items to skip before returning results.
Returns:
-
list[SearchItem]–List of items matching the search criteria.
Examples
Basic filtering:
# Search for documents with specific metadata
results = await store.asearch(
("docs",),
filter={"type": "article", "status": "published"}
)
Natural language search (requires vector store implementation):
# Initialize store with embedding configuration
store = YourStore( # e.g., InMemoryStore, AsyncPostgresStore
index={
"dims": 1536, # embedding dimensions
"embed": your_embedding_function, # function to create embeddings
"fields": ["text"] # fields to embed
}
)
# Search for semantically similar documents
results = await store.asearch(
("docs",),
query="machine learning applications in healthcare",
filter={"type": "research_paper"},
limit=5
)
Note: Natural language search support depends on your store implementation and requires proper embedding configuration.
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
aput(namespace: tuple[str, ...], key: str, value: dict[str, Any], index: Optional[Union[Literal[False], list[str]]] = None) -> None
async
¶
Asynchronously store or update an item in the store.
Parameters:
-
namespace(tuple[str, ...]) –Hierarchical path for the item, represented as a tuple of strings. Example: ("documents", "user123")
-
key(str) –Unique identifier within the namespace. Together with namespace forms the complete path to the item.
-
value(dict[str, Any]) –Dictionary containing the item's data. Must contain string keys and JSON-serializable values.
-
index(Optional[Union[Literal[False], list[str]]], default:None) –Controls how the item's fields are indexed for search:
- None (default): Use
fieldsyou configured when creating the store (if any) If you do not initialize the store with indexing capabilities, theindexparameter will be ignored - False: Disable indexing for this item
- list[str]: List of field paths to index, supporting:
- Nested fields: "metadata.title"
- Array access: "chapters[*].content" (each indexed separately)
- Specific indices: "authors[0].name"
- None (default): Use
Note
Indexing support depends on your store implementation.
If you do not initialize the store with indexing capabilities,
the index parameter will be ignored.
Examples
Store item. Indexing depends on how you configure the store.
Do not index item for semantic search. Still accessible through get() and search() operations but won't have a vector representation.
Index specific fields for search (if store configured to index items):
Source code in venv/lib/python3.11/site-packages/langgraph/store/base/__init__.py
adelete(namespace: tuple[str, ...], key: str) -> None
async
¶
alist_namespaces(*, prefix: Optional[NamespacePath] = None, suffix: Optional[NamespacePath] = None, max_depth: Optional[int] = None, limit: int = 100, offset: int = 0) -> list[tuple[str, ...]]
async
¶
List and filter namespaces in the store asynchronously.
Used to explore the organization of data, find specific collections, or navigate the namespace hierarchy.
Parameters:
-
prefix(Optional[Tuple[str, ...]], default:None) –Filter namespaces that start with this path.
-
suffix(Optional[Tuple[str, ...]], default:None) –Filter namespaces that end with this path.
-
max_depth(Optional[int], default:None) –Return namespaces up to this depth in the hierarchy. Namespaces deeper than this level will be truncated to this depth.
-
limit(int, default:100) –Maximum number of namespaces to return (default 100).
-
offset(int, default:0) –Number of namespaces to skip for pagination (default 0).
Returns:
-
list[tuple[str, ...]]–List[Tuple[str, ...]]: A list of namespace tuples that match the criteria.
-
list[tuple[str, ...]]–Each tuple represents a full namespace path up to
max_depth.
Examples
Setting max_depth=3 with existing namespaces: