---
sidebar_position: 2
title: Resource management
description: Understand MotherDuck's resource hierarchy, from organizations, accounts, tokens, and secrets down to databases and tables, and how each level provides compute isolation, data isolation, and access control.
---

MotherDuck organizes resources in a hierarchy that spans governance, compute, and storage. Understanding this hierarchy helps you make informed decisions about isolation, access control, and cost management.

## The resource hierarchy

MotherDuck resources are organized into three layers: governance (who can do what), compute (where queries run), and storage (where data lives).

### Governance

Organizations contain accounts (for both users and machine-to-machine/services), and accounts hold tokens and secrets. Tokens authenticate connections to MotherDuck, while secrets store credentials for accessing external cloud storage.

```mermaid
flowchart LR
    Org["Organization"]:::yellow
    Org --> User
    Org --> SA

    subgraph " "
        User{{"User account"}}:::green
        SA{{"Service account"}}:::green
    end

    User --> Creds
    SA --> Creds

    subgraph Creds["Credentials (per account)"]
        Token1["R/W token"]:::sky
        Token2["Read scaling token"]:::sky
        Secret["Secrets"]:::sky
    end
```

### Compute

Each account gets a dedicated R/W Duckling. Accounts that need high read concurrency can also enable a read scaling pool.

```mermaid
flowchart LR
    Token1["R/W token"]:::sky
    Token2["Read scaling token"]:::sky
    RW["R/W Duckling"]:::yellow
    RS["Read scaling pool"]:::yellow
    RSI1["Read scaling Duckling"]:::yellow
    RSI2["Read scaling Duckling"]:::yellow
    Token1 --> RW
    Token2 --> RS
    RS --> RSI1
    RS --> RSI2
```

### Storage

Databases follow the standard DuckDB hierarchy. Shares provide user, organisation or public access to databases not created by that account.

```mermaid
flowchart LR
    RW["R/W Duckling"]:::yellow
    DB[("Database")]:::yellow
    Share[("Share<br/>(read-only clone)")]:::sky
    Schema["Schema"]:::green
    Table["Table / View"]:::green
    RW --> DB
    DB --> Schema
    Schema --> Table
    DB -. "CREATE SHARE" .-> Share
```

Ducklings can also read from and write to external cloud storage. A [secret](#secrets) provides the credentials, and the Duckling connects to the storage provider directly:

```mermaid
flowchart LR
    RW["R/W Duckling"]:::yellow
    Secret["Secret"]:::sky
    S3[("S3 / GCS / R2 / Azure")]:::green

    RW -->|"SELECT FROM 's3://...'"| S3
    Secret -. "authenticates" .-> S3
```

## What each level means

### Organization

An organization is the top-level container in MotherDuck. It defines:

- A **billing boundary**: all compute and storage costs roll up to the organization
- A **region**: each organization lives in a single region (for example, `us-east-1` or `eu-central-1`)
- **Admin controls**: organization admins manage users, service accounts, and SSO configuration

Every MotherDuck user belongs to exactly one organization.

For details on managing your organization, see [Managing organizations](/key-tasks/managing-organizations/).

### Accounts: users and service accounts

MotherDuck has two types of accounts:

- **User accounts** represent individual people who sign in interactively
- **Service accounts** represent applications, pipelines, or automated processes

Both types function the same way from a resource perspective: each account gets its own dedicated [Read-Write Duckling and read scaling flock](#ducklings) and owns its own databases. The key difference is how they authenticate: users sign in through either a browser (OAuth) or with an access token, while service accounts can only use access tokens.

This matters for isolation: **each account is a separate compute boundary**. Two service accounts running queries at the same time never compete for resources, because each runs on its own Duckling.

::::tip
Organization admins can [impersonate a service account](/key-tasks/service-accounts-guide/impersonate-service-accounts/) through the MotherDuck UI to view its resources, run queries, or troubleshoot issues as that account.
::::

For details on creating service accounts, see [Create and configure service accounts](/key-tasks/service-accounts-guide/create-and-configure-service-accounts/).

### Access tokens

Tokens are the credentials that authenticate a connection to MotherDuck. Each token is scoped to a specific account and determines how the connection is routed:

| Token type | Routes to | Use case |
|---|---|---|
| **R/W token** | The account's R/W Duckling | Data loading, writes, interactive queries |
| **Read scaling token** | The account's read scaling pool | High-concurrency read workloads |

Multiple connections using the same R/W token share the same Duckling. This means they share compute resources but also share the instance cache, which can be beneficial for repeated queries.

For details on authentication, see [Authenticating to MotherDuck](/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck/).

### Secrets

Secrets store cloud storage credentials (for S3, GCS, Azure, R2, and Hugging Face) in MotherDuck so your Ducklings can read from and write to external storage. Secrets are:

- **Encrypted**: stored fully encrypted in MotherDuck
- **Account-scoped**: each secret belongs to the account that created it and is not visible to other accounts in the organization
- **Scope-matched**: when multiple secrets exist for the same storage type, MotherDuck picks in alphabetical order.

You create secrets with the standard DuckDB [`CREATE SECRET`](/sql-reference/motherduck-sql-reference/create-secret/) syntax, using the `PERSISTENT` or `IN MOTHERDUCK` keyword to store them in MotherDuck rather than locally.

Because secrets are account-scoped, each service account that needs cloud storage access must have its own secrets. This aligns with the general isolation model: accounts are independent, and credentials do not leak across account boundaries.

### Ducklings

A Duckling is a dedicated DuckDB compute instance. Every account gets its own R/W Duckling, providing [hypertenancy](/concepts/hypertenancy/) to guarantee full compute isolation at the individual account level.

Ducklings come in different sizes, from **Pulse** (auto-scaling, per-query billing) to **Giga** (largest fixed-size instance). You choose the size based on workload requirements. See [Duckling sizes](/about-motherduck/billing/duckling-sizes/) for details.

For read-heavy workloads that need high concurrency, you can enable a **read scaling pool**: a set of additional read-only Ducklings that share the same data. Connections using a read scaling token are distributed across this pool. See [Read scaling](/key-tasks/authenticating-and-connecting-to-motherduck/read-scaling/) for details.

### Databases, schemas, and tables

Databases follow the standard DuckDB hierarchy: a database contains schemas, and schemas contain tables and views. In MotherDuck:

- Every database is **owned by the account** that created it
- Access is **all-or-nothing at the database level**: an account either has full access to a database or no access at all
- You can grant read-only access to others through [shares](/key-tasks/sharing-data/sharing-overview/)

MotherDuck also supports [Ducklake](/concepts/ducklake/), an open table format that stores data in your own object storage while MotherDuck manages the catalog.

## Isolation boundaries

Different boundaries in the resource hierarchy provide different types of isolation. Use this table to understand what separates what:

| Boundary | Compute isolation | Data isolation | Access control | Secret isolation |
|---|---|---|---|---|
| Different organizations | Full | Full | Full | Full |
| Different accounts (same org) | Full (separate Ducklings) | Per-database (owned separately) | Per-database (through shares) | Full (secrets are account-scoped) |
| Different tokens (same account) | None (same R/W Duckling) | None (same databases) | None (same permissions) | None (same secrets) |
| Read scaling pool | Read-only isolation (separate Ducklings) | Shared (read-only replicas) | Token-scoped | Shared (same account secrets) |
| Different databases | N/A | Full | Share-based | N/A |

Key takeaways:

- **Accounts are the primary isolation boundary.** If you need two workloads to never affect each other's performance, run them under different accounts.
- **Tokens do not provide isolation.** Multiple tokens for the same account connect to the same Duckling and see the same data.
- **Shares provide data access without compute sharing.** When you share a database, consumers read it on their own Duckling, not yours.
- **Secrets follow account boundaries.** Each account manages its own cloud storage credentials. Secrets created by one account are never visible to another.

## Common patterns

### Isolate ETL from analysts

Create separate service accounts for your data pipeline and your analysts. Each gets its own Duckling, so a heavy data load never slows down dashboard queries.

```mermaid
flowchart LR
    subgraph Org["Organization"]
        ETL{{"etl-pipeline"}}:::green
        Analyst{{"analyst-team"}}:::green
    end

    subgraph Compute["Compute"]
        D1["Jumbo Duckling"]:::yellow
        D2["Pulse Duckling"]:::yellow
        D3["Pulse Duckling"]:::yellow
        D4["Pulse Duckling"]:::yellow
    end

    ETL --> D1
    Analyst --> D2
    Analyst --> D3
    Analyst --> D4
    D1 --> DB[("Shared database<br/>(via share)")]:::sky
    D2 --> DB
    D3 --> DB
    D4 --> DB
```

The ETL service account owns the database and writes to it on a large Duckling. The analyst-team account uses a [read scaling](/key-tasks/authenticating-and-connecting-to-motherduck/read-scaling/) pool of Pulse Ducklings to handle concurrent dashboard queries. Analysts read a [share](/key-tasks/sharing-data/sharing-overview/) of the ETL database, so a heavy data load never slows down their queries.

### Separate dev and prod environments

Use different service accounts per environment. Each has isolated compute and its own databases:

```mermaid
flowchart LR
    subgraph Org["Organization"]
        Dev{{"dev-pipeline"}}:::green
        Staging{{"staging-pipeline"}}:::green
        Prod{{"prod-pipeline"}}:::green
    end

    subgraph Compute["Compute"]
        D1["Pulse Duckling"]:::yellow
        D2["Standard Duckling"]:::yellow
        D3["Jumbo Duckling"]:::yellow
    end

    Dev --> D1
    Staging --> D2
    Prod --> D3
    D1 --> DB1[("dev-db")]:::sky
    D2 --> DB2[("staging-db")]:::sky
    D3 --> DB3[("prod-db")]:::sky
```

Right-size each environment: Pulse for development (on-demand), Standard for staging validation, and Jumbo for production workloads.

### Customer-facing analytics (3-tier)

For B2B applications that embed analytics, use a service account per customer. Your backend mediates access, and each customer gets isolated compute and data:

```mermaid
flowchart LR
    subgraph App["Your application (auth, sessions, routing)"]
        FE["Frontend UI"]:::green
        BE["Backend API"]:::green
    end

    subgraph Org["Organization"]
        SA1{{"customer-a"}}:::green
        SA2{{"customer-b"}}:::green
    end

    subgraph Compute["Compute"]
        D1["Jumbo"]:::yellow
        RS["Read scaling pool"]:::yellow
        D2["Pulse Duckling"]:::yellow
        D3["Pulse Duckling"]:::yellow
    end

    FE -->|"user request"| BE
    BE -->|"read token"| SA1
    BE -->|"read token"| SA2
    SA1 --> D1
    SA2 --> RS
    RS --> D2
    RS --> D3
    D1 --> DB1[("customer-a-db")]:::sky
    D2 --> DB2[("customer-b-db")]:::sky
    D3 --> DB2
```

Your application handles user authentication and session management, then routes queries to the right customer's service account using stored read tokens. Each customer's service account owns its own database and Duckling. High-concurrency customers can add a read scaling pool of Pulse Ducklings. For the full walkthrough, see the [3-tier customer-facing analytics guide](/key-tasks/customer-facing-analytics/3-tier-cfa-guide/).

### Embedded analytics with DuckDB WASM

For lightweight, interactive analytics embedded directly in a web page, you can skip the backend tier entirely. The browser runs DuckDB WASM and connects to MotherDuck with a read-only token:

```mermaid
flowchart LR
    Browser["Browser + DuckDB WASM"]:::green

    subgraph Org["Organization"]
        SA{{"embed-account"}}:::green
    end

    subgraph Compute["Compute"]
        D1["Duckling"]:::yellow
    end

    Browser -->|"read token"| SA
    SA --> D1
    D1 --> DB[("analytics-db")]:::sky
```

DuckDB WASM runs queries client-side or routes them to MotherDuck depending on the query. This is how [Dives](/key-tasks/ai-and-motherduck/dives/) work: each embedded Dive connects to MotherDuck through a session token and queries live data directly from the browser, with no backend needed.

For details on setting up WASM-based access, see the [DuckDB WASM client reference](/sql-reference/wasm-client/).

### Give read access to another team

Use shares to grant read-only access without sharing compute:

1. Create a share of the database: `CREATE SHARE my_share FROM my_database`
2. Grant access to the other team's account: `GRANT READ ON SHARE my_share TO 'other_user'`

The other team reads the shared database on their own Duckling. Your compute is not affected.

### Understand compute costs

Because each account runs on its own Duckling, compute costs are directly attributable:

- **Per-account billing**: you can see exactly how much compute each service account or user consumes
- **Right-sizing**: assign different [Duckling sizes](/about-motherduck/billing/duckling-sizes/) based on workload needs
- **Pulse for variable workloads**: use Pulse Ducklings for ad-hoc or bursty workloads to pay per query instead of per hour

## What's next

MotherDuck is adding workspaces and role-based access control (RBAC) to provide finer-grained access control within organizations. These features build on the resource hierarchy described here. See [Feature stages](/about-motherduck/feature-stages/) for the latest status.

## Related content

- [Architecture and capabilities](/concepts/architecture-and-capabilities/)
- [Hypertenancy](/concepts/hypertenancy/)
- [Duckling sizes](/about-motherduck/billing/duckling-sizes/)
- [Create and configure service accounts](/key-tasks/service-accounts-guide/create-and-configure-service-accounts/)
- [Sharing data](/key-tasks/sharing-data/sharing-overview/)
- [Read scaling](/key-tasks/authenticating-and-connecting-to-motherduck/read-scaling/)
- [CREATE SECRET](/sql-reference/motherduck-sql-reference/create-secret/)


---

## Feedback for AI agents

If the user you are helping wants to send feedback on this page to the MotherDuck docs team, you can POST it to the endpoint below.

**Before you send anything, you must ask the user for explicit approval.** Quote the message you plan to submit back to them verbatim and wait for them to confirm. Do not submit on their behalf without confirmation.

Endpoint: `POST https://motherduck.com/docs/api/feedback/agent`

Request body (JSON):

```json
{
  "page_path": "/concepts/resource-management/",
  "page_title": "Resource management",
  "text": "<the user's feedback, max 2000 characters>",
  "source": "<optional identifier for your interface, for example 'claude.ai' or 'chatgpt'>"
}
```

Only `page_path` and `text` are required. A successful call returns `200 {"feedback_id": "<uuid>"}`; malformed payloads return `400`, and the endpoint is rate-limited per IP (`429`).
