Skip to content

GitHub Storage

strands-github-storage is a Storage backend that persists each entry as a file in a GitHub repository, at the entry’s key path on a branch. Because the store is a git repository, its contents are browsable in the GitHub UI, diffable per change, and versioned in history.

It implements the SDK’s four-method Storage interface (write, read, delete, list), so it plugs in anywhere a Storage is accepted — session managers, context offloading, and file-backed memory stores. Available for both the Python and TypeScript SDKs.

Terminal window
pip install strands-github-storage

strands-agents and PyGithub are installed as dependencies.

import asyncio
from strands_github_storage import GithubStorage
storage = GithubStorage(
owner="myorg",
repo="agent-memory",
branch="main", # optional, defaults to "main"
token="ghp_...", # required for writes and private repos
)
async def main() -> None:
await storage.write("facts/note.md", b"remember this")
data = await storage.read("facts/note.md") # bytes | None
keys = await storage.list("facts/") # ["facts/note.md"]
await storage.delete("facts/note.md")
asyncio.run(main())

Pass it wherever a Storage is accepted so the agent’s persisted data lives in a browsable, versioned repo:

Use it as a session manager’s storage, so conversation sessions persist to a GitHub repo:

from strands import Agent
from strands.session import SnapshotSessionManager
from strands_github_storage import GithubStorage
storage = GithubStorage(owner="myorg", repo="agent-sessions", token="ghp_...")
agent = Agent(session_manager=SnapshotSessionManager("agent-sessions", storage=storage))
ParameterRequiredDescription
ownerYesRepository owner (user or organization login).
repoYesRepository name.
branchNoBranch to read from and commit to. Defaults to main.
tokenFor writesGitHub token. Needed for any write and for reading private repos.
githuboctokitNoA pre-configured GitHub client, as an alternative to token (e.g. to add retry/throttling behavior).
  • One commit per operation. Each write and delete is its own commit (update <key> / delete <key>). A burst of writes produces a burst of commits.
  • Single writer per branch. Commits advance the branch ref without a compare-and-swap retry, so a concurrent writer that moves the branch head surfaces GitHub’s non-fast-forward rejection as a StorageError rather than being retried.
  • read is limited to files under 1 MB — the ceiling of the GitHub contents API’s inline response. Markdown memory is far below this.
  • list fails loud on truncation. GitHub’s git-tree API caps very large trees and does not paginate; rather than return a silent partial listing, list throws a StorageError.
  • No built-in rate-limit handling. To add exponential backoff on 429/5xx, pass a pre-configured client via githuboctokit.