Step 8 of 1173% complete

Understanding Arkiv (Optional)

Estimated time: 10 minutes

Understanding Arkiv (Optional)

Learning Objectives

By the end of this step, you'll:

  • Understand key Arkiv concepts (entities, spaces, attributes)
  • Know how queries work
  • Understand the difference between reads and writes
  • See how Arkiv differs from traditional databases

Content

What is Arkiv?

Arkiv is a decentralized database built on blockchain. It provides:

  • On-chain storage: Data is stored on the blockchain
  • Query interface: Read data using familiar query patterns
  • EVM compatibility: Works with Ethereum wallets and tools
  • No vendor lock-in: Your data is independent of any service

📄 Source: These concepts are explained in detail in the Arkiv Litepaper. The litepaper provides deeper context on Arkiv's architecture and philosophy.

Architecture Comparison

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.

Key Concepts

Entities

An entity is a piece of data stored on Arkiv. Think of it like a row in a database table.

Each entity has:

  • Key: Unique identifier (generated automatically)
  • Payload: The actual data (can be JSON, text, binary, etc.)
  • Attributes: Key-value pairs for querying (like indexed columns)
  • Content Type: MIME type of the payload (e.g., application/json)

Entity Structure

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"
}

Spaces

A space is like a namespace or database. It isolates your data from other apps.

  • Use SPACE_ID to organize data
  • All entities in the same space can query each other
  • Different spaces are isolated from each other
  • In this workshop, we use SPACE_ID=ns (shared space)

Attributes

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 to
  • wallet: The wallet address that created it
  • Custom attributes: Anything you want to query on

Queries

You 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."

Data Flow - Read

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).

Reads vs Writes

Reads (Public Client)

  • No authentication needed: Anyone can read public data
  • Free: Reading doesn't cost gas
  • Fast: Queries are served by indexers
  • Use case: Displaying data, searching, filtering
const publicClient = getPublicClient();
const result = await publicClient.buildQuery()...fetch();

Writes (Wallet Client)

  • Authentication required: Must sign with a private key
  • Costs gas: Each write is a blockchain transaction
  • Slower: Must wait for blockchain confirmation
  • Use case: Creating, updating, deleting data
const walletClient = getWalletClientFromPrivateKey(privateKey);
const result = await walletClient.createEntity({...});

How It Differs from Traditional Databases

| 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

Indexer lag is the delay between when a transaction is confirmed and when it appears in queries.

  • Transactions are confirmed immediately (on-chain)
  • But indexers need time to process and index them
  • Usually 5-30 seconds on testnet
  • This is why you might need to refresh to see new data

Best Practices

  1. Use meaningful attributes: Make queries efficient
  2. Store structured data in payload: Use JSON for complex data
  3. Use unique space IDs in production: Don't use "ns" for real apps
  4. Handle indexer lag: Refresh or poll for new data
  5. Store txHash separately: Create companion entities for reliable querying

Building with AI Assistants: Arkiv AI Agent Kit

If you're using AI coding assistants (Cursor, Copilot, Claude, etc.) to build Arkiv apps, check out the Arkiv AI Agent Kit. It provides:

  • Drop-in LLM context for building Arkiv integrations correctly from day one
  • Patterns and prompts that prevent common mistakes
  • Best practices enforced automatically (wallet normalization, query shapes, timeout handling)
  • Engineering guidelines and checklists

The kit helps AI assistants understand Arkiv's unique characteristics:

  • Indexer lag is normal (not an error)
  • Immutable history design patterns
  • Query shape standardization (type + spaceId + limit)
  • Wallet normalization everywhere

Concept Bridges

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.

✓ Checkpoint

Troubleshooting

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.