The lightning-fast vector database Qdrant has supported creating snapshots of its collection on S3 since version v1.10. That’s convenient and simplifies storing snapshots as backups on multiple machines. However, as of 2025, there is no way to restore a collection from a snapshot on S3. This article describes a walkaround using pre-signed URLs in S3.

Illustration of a backup and restore workflow in Qdrant via an S3 bucket

Creating the snapshot

A Qdrant instance can be configured to use S3 as its storage for snapshots.

storage:
  snapshots_config:
    snapshots_storage: s3
    s3_config:
      bucket: your_bucket_here
      region: your_bucket_region_here
      access_key: your_access_key_here
      secret_key: your_secret_key_here
      endpoint_url: your_url_here

The next snapshot request will be written to the S3 bucket.

from qdrant_client import QdrantClient

client = QdrantClient(url="http://localhost:6333")
snapshot_info = client.create_snapshot(collection_name="my-collection")

Creating a pre-signed URL

From the snapshot_info object, we can figure out the name of the snapshot within the bucket. Alternatively, inspecting the bucket directly works as well. Let’s assume, the snapshot is called

snapshots/my-collection/my-collection_123456789.snapshot

Since Qdrant is not able to read and restore a snapshot from S3 directly, we can use S3’s pre-signed URLs. A pre-signed URL contains a signature that authorizes everyone with the URL to access a specific object in the bucket—assuming that the API and the bucket is not configured to be entirely private.

AWS’s Python client boto3 is an easy way to create pre-signed URLs.

import boto3


session = boto3.session.Session()
s3 = session.client(
        service_name='s3',
        aws_access_key_id='...',
        aws_secret_access_key='...',
        endpoint_url='...',
)

url = s3.generate_presigned_url(
        'get_object',
        Params={
            'Bucket': '...',
            'Key': 'snapshots/my-collection/my-collection_123456789.snapshot',
        },
        ExpiresIn=3600 * 24 * 7,  # Expires in 7 days
)

Creating pre-signed URLs doesn’t require internet access. The key id and access key pair is sufficient to create the signature offline. The S3 server validates the signature and evaluates permissions once the resource is requested.

The HTTP URL points to the snapshot file. This could look like

>>> url
'https://s3.sauerburger.com/' \
    'qdrant-backup/snapshots/my-collection/my-collection_123456789.snapshot?' \
    'X-Amz-Algorithm=AWS4-HMAC-SHA256&' \
    'X-Amz-Credential=a4tw715etr74zq2dhxdp70s1%2F20250212%2Feu-central-1%2Fs3%2Faws4_request&' \
    'X-Amz-Date=20250212T194041Z&' \
    'X-Amz-Expires=604800&' \
    'X-Amz-SignedHeaders=host&' \
    'X-Amz-Signature=23ea0fcfa91bb5e3ebea847e79cc69f08224e58275890097e28bed9e1de018df'

Restoring a collection

The final step is to instruct Qdrant to restore a collection from a snapshot via HTTP.

from qdrant_client import QdrantClient

client = QdrantClient(url="http://localhost:6333")
success = qdrant.recover_snapshot(
    "my-collection",
    url,
    wait=True,
    priority='snapshot'
)

Done.

Summary

Qdrant → S3 → Pre-signed HTTP URL → Qdrant