Estimated time: 10 minutes
By the end of this step, you'll:
Arkiv is a decentralized database built on blockchain. It provides:
📄 Source: These concepts are explained in detail in the Arkiv Litepaper. The litepaper provides deeper context on Arkiv's architecture and philosophy.
This comparison shows how serverless dapps with Arkiv differ from traditional apps. The most fundamental difference is where and who owns the data. With Arkiv, data lives on-chain, owned by users.
An entity is a piece of data stored on Arkiv. Think of it like a row in a database table.
Each entity has:
application/json)This diagram shows the structure of an Arkiv entity: unique ID, queryable attributes, content payload, and transaction hash for verification. Use attributes for anything you want to query on (they're indexed and fast), and store complex data in the payload as JSON.
Example entity:
{
key: "0xabc123...",
payload: JSON.stringify({ text: "Hello", createdAt: "2024-01-01" }),
attributes: [
{ key: "type", value: "message" },
{ key: "spaceId", value: "ns" },
{ key: "wallet", value: "0x742d35..." }
],
contentType: "application/json"
}A space is like a namespace or database. It isolates your data from other apps.
SPACE_ID to organize dataSPACE_ID=ns (shared space)Attributes are key-value pairs that you can query on. Think of them like indexed columns.
Common attributes:
type: What kind of entity this is (e.g., "message", "user", "post")spaceId: Which space this entity belongs towallet: The wallet address that created itYou query Arkiv using a builder pattern:
const result = await publicClient
.buildQuery()
.where(eq('type', 'message'))
.where(eq('spaceId', 'ns'))
.withAttributes(true)
.withPayload(true)
.limit(100)
.fetch();This reads: "Find entities where type='message' AND spaceId='ns', return up to 100 results, include attributes and payload."
This diagram shows how queries work: your app makes a query request, which goes to Arkiv indexers. Indexers filter entities by your criteria and return matching results. Reads are public (anyone can query), free (no gas fees), and fast (served by indexers).
const publicClient = getPublicClient();
const result = await publicClient.buildQuery()...fetch();const walletClient = getWalletClientFromPrivateKey(privateKey);
const result = await walletClient.createEntity({...});| Traditional Database | Arkiv | |---------------------|-------| | Centralized server | Decentralized (blockchain) | | Vendor lock-in | Independent data | | Private by default | Public by default | | Fast writes | Slower writes (blockchain) | | Requires infrastructure | No infrastructure needed | | Data can be lost | Data persists on-chain |
This comparison highlights the fundamental differences between traditional databases and Arkiv. The key tradeoff is speed for independence: Arkiv writes are slower (blockchain confirmation), but your data is truly independent and verifiable.
Indexer lag is the delay between when a transaction is confirmed and when it appears in queries.
If you're using AI coding assistants (Cursor, Copilot, Claude, etc.) to build Arkiv apps, check out the Arkiv AI Agent Kit. It provides:
The kit helps AI assistants understand Arkiv's unique characteristics:
If you've taken the Vibes to App workshop, this visual shows how those concepts extend into the decentralized world. The progression from app ideas to traditional apps to serverless dapps demonstrates how Arkiv builds on familiar development patterns.
🤖 Learn More: See the AI Agent Kit section in the Visual Lesson, or check out the Next Steps section for links to the kit.
I'm at step 8: Understanding Arkiv (Optional).
Help me understand:
1. What entities, spaces, and attributes are
2. How queries work in Arkiv
3. The difference between reads and writes
4. How Arkiv differs from traditional databases
5. Why indexer lag happens
Provide clear explanations with examples from the code we've been using.
Update the internal implementation plan with notes and show me the plan so I can track your progress.Q: Can I update or delete entities? A: Arkiv is append-only. You can't update or delete entities, but you can create new ones that reference old ones (like marking a message as "deleted" with an attribute).
Q: How do I make data private?
A: Use a unique SPACE_ID that only you know. While technically public on-chain, it's only discoverable if someone knows your space ID. For truly private data, encrypt the payload before storing.
Q: What's the cost of storing data? A: On testnet, it's free. On mainnet, you pay gas fees (similar to Ethereum). The cost depends on the size of your payload and current gas prices.
Q: How much data can I store? A: There are practical limits based on gas costs. For large files, consider storing a hash on-chain and the actual file elsewhere (IPFS, Arweave, etc.).
Q: Can I query across multiple spaces? A: No, queries are scoped to a single space. If you need data from multiple spaces, make separate queries and combine the results.
Q: How do shared spaces work?
A: When multiple users use the same SPACE_ID, all entities with that space ID are queryable by anyone. Queries filter by spaceId attribute, not by wallet address. This means messages from different wallets appear together if they share the same space ID. In this tutorial, we use SPACE_ID=ns as a shared space so all participants can see each other's messages on the deployed hello-world page.