Can Claude's Persistent Storage API Be Used as a Key-Value Store for Artifacts?
Yes, Claude's Persistent Storage API exposes a fully functional key-value store to artifacts via the window.storage object, supporting get, set, delete, and list operations with both personal and shared data scopes.
The asgeirtj/system_prompts_leaks repository reveals that Claude Opus 4.6 implements a Persistent Storage API specifically designed to give artifacts persistent key-value storage capabilities. This API allows artifacts to store JSON-serializable data that persists across sessions without requiring external databases or backend infrastructure.
How the Persistent Storage API Implements Key-Value Storage
Core Methods and Signatures
According to the system prompt defined in Anthropic/claude-opus-4.6.md (lines 889-898), the API exposes four asynchronous methods through the global window.storage object:
get(key, shared?)- Retrieves values stored under a specific keyset(key, value, shared?)- Stores JSON-serializable valuesdelete(key, shared?)- Removes entries by keylist(prefix?, shared?)- Enumerates keys matching a prefix pattern
Each method returns a promise resolving to an object containing the operation results or null if the operation fails.
Data Scoping: Personal vs. Shared
The Persistent Storage API implements a dual-scope architecture controlled by the optional shared parameter:
shared: false(default): Data is personal to the current user and isolated from other usersshared: true: Data is visible to all users of the artifact, enabling collaborative features like shared leaderboards or multiplayer game states
This scoping mechanism is enforced by the backend storage service hosting the data.
Technical Constraints and Design Patterns
Key Naming Conventions
As specified in Anthropic/claude-opus-4.6.md (lines 181-188), keys must follow strict hierarchical conventions:
- Maximum length of 200 characters
- No whitespace or path separators allowed
- Recommended format:
table_name:record_id
This hierarchical pattern enables efficient prefix-based lookups and prevents namespace collisions between different artifact components.
Value Limits and Serialization
The API imposes specific constraints on stored values (lines 554-557):
- Format: Text/JSON only
- Size limit: 5 MiB per key
- Serialization: Values must be JSON-serializable before storage
These constraints ensure compatibility with the underlying storage infrastructure while preventing abuse of the persistent storage system.
Concurrency and Race Conditions
According to lines 545-549 in the system prompt, the storage backend employs a last-write-wins strategy for concurrent updates. To minimize race conditions:
- Batch related data into single keys rather than distributing across multiple keys
- Implement client-side versioning if strict consistency is required
- Avoid rapid successive updates to the same key from multiple artifact instances
Practical Code Examples
Storing Personal Data
To store user-specific data that persists across sessions:
// Save a user's todo entry
const entry = { title: "Buy milk", completed: false };
await window.storage.set('todos:entry_1', JSON.stringify(entry));
// Retrieve it later
const result = await window.storage.get('todos:entry_1');
const todo = result ? JSON.parse(result.value) : null;
console.log(todo); // {title:"Buy milk",completed:false}
Creating Shared Leaderboards
For collaborative features using the shared scope:
// Increment a user's score (shared data)
async function addScore(user, points) {
const key = `leaderboard:${user}`;
let record = await window.storage.get(key, true); // shared=true
let score = record ? JSON.parse(record.value) : 0;
score += points;
await window.storage.set(key, JSON.stringify(score), true);
}
// List all leaderboard entries
const keys = await window.storage.list('leaderboard:', true);
console.log(keys); // e.g. ["leaderboard:alice","leaderboard:bob"]
Handling Errors and Missing Keys
As noted in lines 331-339, missing keys throw errors rather than returning null:
try {
const res = await window.storage.get('nonexistent:key');
console.log(JSON.parse(res.value));
} catch (e) {
console.warn('Key not found:', e.message);
}
Summary
- Claude's Persistent Storage API provides a native key-value store for artifacts via
window.storagewithget,set,delete, andlistoperations. - Data can be scoped as personal (default) or shared across users, enabling both private user data and collaborative features.
- Keys must follow hierarchical conventions (≤200 chars, no whitespace) and values are limited to 5 MiB JSON-serializable data.
- The last-write-wins concurrency model requires careful key design to avoid race conditions.
Frequently Asked Questions
What is the maximum size limit for values in Claude's Persistent Storage API?
Values stored via the Persistent Storage API are limited to 5 MiB per key and must be JSON-serializable text. This constraint is enforced by the underlying storage backend to ensure system stability and prevent resource abuse.
Can multiple users access the same data using the Persistent Storage API?
Yes, by setting the optional shared parameter to true in any storage method, data becomes visible to all users of the artifact. When shared is false (the default), data remains private to the individual user who created it.
How does the Persistent Storage API handle concurrent updates?
The API implements a last-write-wins strategy for concurrent modifications. To minimize race conditions, you should batch related data into single keys rather than distributing across multiple keys, and implement client-side versioning if strict consistency is required.
Where is the Persistent Storage API documented in the Claude system prompts?
The complete API specification is documented in the <persistent_storage_for_artifacts> section of the Claude Opus 4.6 system prompt, specifically within the Anthropic/claude-opus-4.6.md file at lines 889-898, with additional implementation details scattered throughout the document.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →