Skip to main content

CREATE DATABASE

The CREATE DATABASE statement creates a new database in MotherDuck.

It can be used for the following operations:

  • Create a MotherDuck database from a local DuckDB database.
  • Create a MotherDuck database from a remote DuckDB database file in cloud storage (for example, a file in Amazon S3).
  • Create a MotherDuck database from another MotherDuck database or share using zero-copy clone (without physically copying data).
Copy to local database

To copy a MotherDuck database to a local database, use the COPY FROM DATABASE statement.

Zero-copy clone

When the source is another MotherDuck database or a share, CREATE DATABASE ... FROM performs a zero-copy clone. The command completes almost instantly because no data is physically duplicated. When the source is a local file, a remote file, or CURRENT_DATABASE(), data is physically copied to MotherDuck.

warning

A share that carries an include pattern can't be a zero-copy clone source. A clone copies the underlying snapshot, which would carry the tables the pattern hides, so CREATE DATABASE ... FROM rejects a filtered share whether you name its attached alias or its share URL. To copy the tables the share does expose, use COPY FROM DATABASE instead.

Syntax

CREATE [ OR REPLACE ] DATABASE [ IF NOT EXISTS ] <database name>
[
FROM <database name> |
FROM <snapshot_name> | <snapshot_id> | <snapshot_time>
FROM '<local/file/path.db>' |
FROM '<remote/file/path.db>' |
FROM 'md:_share/...' |
FROM CURRENT_DATABASE() -- Important: this command does not work with attached shares
]

[(
[ TYPE { DEFAULT | DUCKLAKE | ICEBERG }, ]
<option> [ <value> ] [, ...]
)];

TYPE selects the database type and defaults to DEFAULT, a native storage database. Which other options you can pass depends on the type, see Database options.

You can also pass the name of an attached share or a share URL as the database name, for example CREATE DATABASE FROM my_share or CREATE DATABASE FROM 'md:_share/...'.

If the database name already exists, the statement returns an error unless you specify IF NOT EXISTS.

Similar to DuckDB table name conventions, database names that start with a number or contain special characters must be double-quoted when used. Example: CREATE DATABASE "123db"

Creating a database does not change the active database. Run USE DATABASE <database name> to switch.

Database options

Databases on MotherDuck are native storage databases, DuckLake databases, or Iceberg catalogs. Each type has its own set of options you can configure at creation time.

Note that SNAPSHOT_RETENTION_DAYS exists for both native storage and DuckLake databases, but means something different in each.

Native storage options

All native storage databases have a transient status and a historical retention period. These properties are inherited on new databases created with the CREATE DATABASE dest_db FROM source_db syntax.

Set the historical retention period at creation, or change it later with ALTER DATABASE. You can set the transient status when creating a database, but it can't be altered after. Transient databases have a different failsafe period than non-transient databases.

NameDescription
TYPE DEFAULTOptional. Any database created without a TYPE is a native storage database.
TRANSIENTSpecify TRANSIENT at database creation to enable transient storage. Refer to the Storage lifecycle management overview for more details.
SNAPSHOT_RETENTION_DAYSProvide an integer to specify the number of days to retain automatic and unnamed snapshots as historical_bytes. Named snapshots are retained until unnamed. Refer to the Storage lifecycle management overview for more details.
-- A native storage database:
CREATE DATABASE cloud_db;

-- A transient database:
CREATE DATABASE scratch_db (TRANSIENT);

-- A database that keeps seven days of snapshots:
CREATE DATABASE archive_db (SNAPSHOT_RETENTION_DAYS 7);

DuckLake options

NameDescription
TYPE DUCKLAKESpecify TYPE DUCKLAKE at database creation to create a fully managed DuckLake. Refer to the DuckLake overview for more details.
DATA_PATHOptional data path for DuckLake storage (for example, DATA_PATH 's3://bucket/prefix'). Buckets must be in the same AWS region as your MotherDuck org (us-east-1 or us-west-2 for US, eu-central-1 or eu-west-1 for EU).
ENCRYPTEDEnables encryption for DuckLake storage. To enable it, specify ENCRYPTED at database creation. Refer to Encryption for more details.
DATA_INLINING_ROW_LIMITRow-size threshold (bytes) for inline data storage. Provide an integer value.
SNAPSHOT_RETENTION_DAYSNumber of days to retain DuckLake snapshots before they are eligible for expiration. Defaults to NULL (infinite retention). DuckLake snapshots are expired by running maintenance operations manually; MotherDuck does not expire them automatically.
-- A fully managed DuckLake:
CREATE DATABASE cloud_ducklake (TYPE DUCKLAKE);

-- A DuckLake that keeps seven days of snapshots:
CREATE DATABASE my_ducklake (TYPE DUCKLAKE, SNAPSHOT_RETENTION_DAYS 7);

-- A DuckLake in your own bucket, with encryption:
CREATE DATABASE my_encrypted_ducklake
(
TYPE DUCKLAKE,
DATA_PATH 's3://my-bucket/ducklake',
ENCRYPTED
);

Iceberg catalog options

Refer to Apache Iceberg for the full set of catalog options and examples.

NameDescription
TYPE ICEBERGSpecify TYPE ICEBERG to attach an Iceberg REST catalog as a persisted MotherDuck database.
SECRETRequired. Name of the MotherDuck Iceberg or S3 secret holding catalog credentials. secret is a reserved word, so quote it as "secret".
DEFAULT_SCHEMARequired. Schema used to resolve unqualified table names. Must exist in the catalog.
ENDPOINTURL of the Iceberg REST catalog. Required unless set in the secret or derived from endpoint_type.
WAREHOUSECatalog warehouse identifier. For S3 Tables, the bucket ARN.
ENDPOINT_TYPESelects a well-known catalog flavor, for example 's3_tables' or 'glue'.
DEFAULT_REGIONPer-catalog region override. Defaults to your MotherDuck org region.
READ_ONLYAttach the catalog as read-only.
ACCESS_DELEGATION_MODEControls vended-credential delegation, for example 'none'.
-- Attach an Iceberg REST catalog as a persisted database:
CREATE DATABASE my_datalake
(
TYPE ICEBERG,
"secret" my_iceberg_secret,
ENDPOINT 'https://my-catalog.example.com',
WAREHOUSE 'my_warehouse',
DEFAULT_SCHEMA 'default'
);

Source database options

These options are only available for native MotherDuck databases. They apply to the source database that is being cloned.

Snapshot selectors are only supported when cloning a native MotherDuck database. They are not supported for DuckLake databases. Cloning a DuckLake database with CREATE DATABASE ... FROM is supported, but the resulting database is a native storage database containing a copy of the data, not a DuckLake.

NameData TypeValue
SNAPSHOT_TIMETIMESTAMPSelects the newest snapshot created before or at this timestamp
SNAPSHOT_IDUUIDID of the snapshot to clone
SNAPSHOT_NAMESTRINGName of the snapshot to clone

Example usage

To create an empty database:

CREATE DATABASE empty_ducks;

If the database name already exists, the statement fails unless you use OR REPLACE or IF NOT EXISTS.

CREATE DATABASE ducks;
-- Succeeds if 'ducks' does not exist

CREATE DATABASE ducks;
-- Error: Failed to create database: database with name 'ducks' already exists

CREATE OR REPLACE DATABASE ducks; -- Replaces existing 'ducks' with an empty database

CREATE DATABASE IF NOT EXISTS ducks; -- No-op if 'ducks' already exists

To copy an entire database from your local DuckDB instance into MotherDuck:

USE ducks_db;
CREATE DATABASE ducks FROM CURRENT_DATABASE();

-- Or alternatively, use the following command - if ducks_db exists, even if populated, it will be replaced with an empty one:
CREATE OR REPLACE DATABASE ducks FROM ducks_db;

-- In the following, if ducks_db exists, the operation will be skipped, but it will not error:
CREATE DATABASE IF NOT EXISTS ducks_db;

For examples of the per-type creation options, see Database options.

To zero-copy clone a database that is already attached in MotherDuck:

CREATE DATABASE cloud_db FROM another_cloud_db;

To zero-copy clone a past snapshot of a database in MotherDuck

CREATE DATABASE cloud_db FROM another_cloud_db (SNAPSHOT_NAME 'prod_backup');
CREATE DATABASE cloud_db FROM another_cloud_db (SNAPSHOT_ID '3f2504e0-4f89-11d3-9a0c-0305e82c3301');
CREATE DATABASE cloud_db FROM another_cloud_db (SNAPSHOT_TIME '2025-07-29 14:30:25.123456');

To upload a local DuckDB database file:

CREATE DATABASE flying_ducks FROM './databases/local_ducks.db';

To create a database from a remote DuckDB database file in cloud storage:

CREATE DATABASE flying_ducks FROM 's3://my-bucket/ducks.db';

Reading from private cloud storage uses a configured secret.

To upload an attached local DuckDB database:

ATTACH './databases/local_ducks.db';
CREATE DATABASE flying_ducks FROM local_ducks;