This page shows you how to migrate a pod-based index to serverless. The migration process is free; the standard costs of upserting records to a new serverless index aren't applied.
Migration is supported for pod-based indexes with up to 500 million records and 20,000 namespaces across all supported clouds (AWS, GCP, and Azure). If your index has more than 500 million records, contact Pinecone Support before you migrate.
After you migrate, note that serverless indexes don't support the following features:
If you were using either feature with your pod-based index, you'll need to adapt your code. If you're blocked by these limitations, contact Pinecone Support.
Migrating a pod-based index to serverless is a 2-step process:
Save the pod-based index as a collection
Create a new serverless index from the collection
After migration, you will have both a new serverless index and the original pod-based index. Once you've switched your workload to the serverless index, you can delete the pod-based index to avoid paying for unused resources.
In most cases, migrating to serverless reduces costs significantly. However, costs can increase for read-heavy workloads with more than 1 query per second and for indexes with many records in a single namespace.
Migrating a pod-based index to serverless can take anywhere from a few minutes to several hours, depending on the size of the index. During that time, you can continue reading from the pod-based index. However, all upserts, updates, and deletes to the pod-based index won't automatically be reflected in the new serverless index, so be sure to prepare in one of the following ways:
Pause write traffic: If downtime is acceptable, pause traffic to the pod-based index before starting migration. After migration, you will start sending traffic to the serverless index.
Log your writes: If you need to continue reading from the pod-based index during migration, send read traffic to the pod-based index, but log your writes to a temporary location outside of Pinecone (e.g., S3). After migration, you will replay the logged writes to the new serverless index and start sending all traffic to the serverless index.
The dropdown won't display Migrate to serverless if the index has any of the listed limitations.
To save the legacy index and create a new serverless index now, follow the prompts.
Depending on the size of the index, migration can take anywhere from a few minutes to several hours. While migration is in progress, you'll see the yellow Initializing status:

When the new serverless index is ready, the status will change to green:

Use the create_collection operation to create a backup of your pod-based index:// Requires Node.js SDK v6.1.2 or later
import { Pinecone } from '@pinecone-database/pinecone'
const pc = new Pinecone({
apiKey: 'YOUR_API_KEY'
});
await pc.createCollection({
name: "pod-collection",
source: "pod-index"
});// Requires Go SDK v4.1.2 or later
package main
import (
"context"
"fmt"
"log"
"github.com/pinecone-io/go-pinecone/v4/pinecone"
)
func main() {
ctx := context.Background()
pc, err := pinecone.NewClient(pinecone.NewClientParams{
ApiKey: "YOUR_API_KEY",
})
if err != nil {
log.Fatalf("Failed to create Client: %v", err)
}
collection, err := pc.CreateCollection(ctx, &pinecone.CreateCollectionRequest{
Name: "pod-collection",
Source: "pod-index",
})
if err != nil {
log.Fatalf("Failed to create collection: %v", err)
} else {
fmt.Printf("Successfully created collection: %v", collection.Name)
}
}PINECONE_API_KEY="YOUR_API_KEY"
curl -s POST "https://api.pinecone.io/collections" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Api-Key: $PINECONE_API_KEY" \
-H "X-Pinecone-Api-Version: 2025-10" \
-d '{
"name": "pod-collection",
"source": "pod-index"
}'
Use the create_index operation to create a new serverless index from the collection:
Use API verison 2025-04 or later. Creating a serverless index from a collection isn't supported in earlier versions.
Set dimension to the same dimension as the pod-based index. Changing the dimension isn't supported.
Set cloud to the cloud where the pod-based index is hosted. Migrating to a different cloud isn't supported.
Set source_collection to the name of the collection you created in step 1.import { Pinecone } from '@pinecone-database/pinecone'
const pc = new Pinecone({
apiKey: 'YOUR_API_KEY'
});
await pc.createIndex({
name: 'serverless-index',
vectorType: 'dense',
dimension: 1536,
metric: 'cosine',
spec: {
serverless: {
cloud: 'aws',
region: 'us-east-1',
sourceCollection: 'pod-collection'
}
}
});package main
import (
"context"
"fmt"
"log"
"github.com/pinecone-io/go-pinecone/v4/pinecone"
)
func main() {
ctx := context.Background()
pc, err := pinecone.NewClient(pinecone.NewClientParams{
ApiKey: "YOUR_API_KEY",
})
if err != nil {
log.Fatalf("Failed to create Client: %v", err)
}
idx, err := pc.CreateServerlessIndex(ctx, &pinecone.CreateServerlessIndexRequest{
Name: "serverless-index",
VectorType: "dense",
Dimension: 1536,
Metric: pinecone.Cosine,
Cloud: pinecone.Aws,
Region: "us-east-1",
SourceCollection: "pod-collection",
})
if err != nil {
log.Fatalf("Failed to create serverless index: %v", err)
} else {
fmt.Printf("Successfully created serverless index: %v", idx.Name)
}
}PINECONE_API_KEY="YOUR_API_KEY"
curl -s "https://api.pinecone.io/indexes" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Api-Key: $PINECONE_API_KEY" \
-H "X-Pinecone-Api-Version: 2025-10" \
-d '{
"name": "serverless-index",
"vector_type": "dense",
"dimension": 1536,
"metric": "cosine",
"spec": {
"serverless": {
"cloud": "aws",
"region": "us-east-1",
"source_collection": "pod-collection"
}
}
}'
You must make some minor code changes to work with serverless indexes.
Change how you import the Pinecone library and authenticate and initialize the client:
Python
from pinecone.grpc import PineconeGRPC as Pinecone
from pinecone import ServerlessSpec, PodSpec
# ServerlessSpec and PodSpec are required only when # creating serverless and pod-based indexes.
pc = Pinecone(api_key="YOUR_API_KEY")
JavaScript
import { Pinecone } from'@pinecone-database/pinecone';
const pc = new Pinecone({ apiKey: 'YOUR_API_KEY' });
Java
import io.pinecone.clients.Pinecone;
import org.openapitools.db_control.client.model.*;
publicclass InitializeClientExample {
publicstaticvoid main(String[] args) {
Pinecone pc = new Pinecone.Builder("YOUR_API_KEY").build();
}
}
Describing an index now returns a description of an index in a different format. It also returns the index host needed to run data plane operations against the index. If you were relying on the output of this operation, you'll need to adapt your code.
Python
from pinecone.grpc import PineconeGRPC as Pinecone
pc = Pinecone(api_key="YOUR_API_KEY")
pc.describe_index(name="docs-example")
JavaScript
import { Pinecone } from'@pinecone-database/pinecone';
const pc = new Pinecone({ apiKey: 'YOUR_API_KEY' });
await pc.describeIndex('docs-example');
When you're ready to cutover to your new serverless index:
Your new serverless index has a different name and unique endpoint than your pod-based index. Update your code to target the new serverless index:
Python
index = pc.Index("YOUR_SERVERLESS_INDEX_NAME")
JavaScript
const index = pc.index("YOUR_SERVERLESS_INDEX_NAME");
Java
import io.pinecone.clients.Index;
import io.pinecone.clients.Pinecone;
publicclass TargetIndexExample {
publicstaticvoid main(String[] args) {
Pinecone pc = new Pinecone.Builder("YOUR_API_KEY").build();
Index index = pc.getIndexConnection("YOUR_SERVERLESS_INDEX_NAME");
Go
package main
import (
"context""log""github.com/pinecone-io/go-pinecone/v4/pinecone"
)
func main() {
ctx := context.Background()
pc, err := pinecone.NewClient(pinecone.NewClientParams{
ApiKey: "YOUR_API_KEY",
})
if err != nil {
log.Fatalf("Failed to create Client: %v", err)
}
idx, err := pc.DescribeIndex(ctx, "YOUR_SERVERLESS_INDEX_NAME")
if err != nil {
log.Fatalf("Failed to describe index \"%v\": %v", idx.Name, err)
}
idxConnection, err := pc.Index(pinecone.NewIndexConnParams{Host: idx.Host, Namespace: "example-namespace"})
if err != nil {
log.Fatalf("Failed to create IndexConnection for Host %v: %v", idx.Host, err)
}
}
curl
# When using the API directly, you need the unique endpoint for your new serverless index. # See https://docs.pinecone.io/guides/manage-data/target-an-index for details.
PINECONE_API_KEY="YOUR_API_KEY"
INDEX_HOST="INDEX_HOST"
curl -X POST "https://$INDEX_HOST/describe_index_stats" \
-H "Api-Key: $PINECONE_API_KEY" \
-H "X-Pinecone-Api-Version: 2025-10"
Reinitialize your clients.
If you logged writes to the pod-based index during migration, replay the logged writes to your serverless index.