In this example, we want to access data stored in R2 which is Cloudflare’s S3-compatible solution, but cheaper and with less consistency quirks:

CREATE NAMED COLLECTION s3_store ON CLUSTER default AS
access_key_id = 'xxx',
secret_access_key = 'xxx',
url = 'https://abcdef1234567890.r2.cloudflarestorage.com/my_path/here/';

Note the ON CLUSTER default bit - this replicates the named collection to all nodes in the cluster. If you’re running a single node or only need the collection locally, just drop it:

CREATE NAMED COLLECTION s3_store AS
access_key_id = 'xxx',
secret_access_key = 'xxx',
url = 'https://abcdef1234567890.r2.cloudflarestorage.com/my_path/here/';

Same logic applies when you want to get rid of it:

-- created with ON CLUSTER? drop with ON CLUSTER
DROP NAMED COLLECTION s3_store ON CLUSTER default;

-- created without? drop without
DROP NAMED COLLECTION s3_store;

If you mix these up, you’ll end up with orphaned entries on other nodes. Ask me how I know.

Need to rotate credentials? ALTER is your friend:

ALTER NAMED COLLECTION s3_store ON CLUSTER default
SET secret_access_key = 'new_key';

No need to recreate the whole thing. You can also add or remove keys:

-- add a new key
ALTER NAMED COLLECTION s3_store ON CLUSTER default
SET some_new_setting = 'value';

-- remove a key
ALTER NAMED COLLECTION s3_store ON CLUSTER default
DELETE access_key_id;

This allows us to use it with s3() and s3Cluster() functions like so:

SELECT count(*) 
FROM s3Cluster(
  'default', 
  s3_store, 
  filename='2025/12/25/01/**.json.gz', 
  format='JSONEachRow'
);

Note that the filename will be appended to the url we specified in the named collection. This should save you some time while building queries OR should allow your MCP to use your S3 buckets without knowing the actual credentials.