Configure statement timeout

This page describes how to set a timeout for a single statement execution usingthe Spanner client libraries. This can be used to override thedefault timeout configuration of the client library. The statement fails with aDEADLINE_EXCEEDED error if the statement cannot finish within the giventimeout value.

Note: It is possible that the timeout occurs after the statement has finishedexecuting on Spanner, but before the response reaches theclient. In that case, it's possible that the statement was committed toSpanner successfully.

These samples show how to set a timeout for a single statement execution in theCloud Spanner client library.

Go

import("context""fmt""io""time""cloud.google.com/go/spanner""google.golang.org/grpc/codes")funcsetStatementTimeout(wio.Writer,dbstring)error{client,err:=spanner.NewClient(context.Background(),db)iferr!=nil{returnerr}deferclient.Close()_,err=client.ReadWriteTransaction(context.Background(),func(ctxcontext.Context,txn*spanner.ReadWriteTransaction)error{// Create a context with a 60-second timeout and apply this timeout to the insert statement.ctxWithTimeout,cancel:=context.WithTimeout(context.Background(),60*time.Second)defercancel()stmt:=spanner.Statement{SQL:`INSERT Singers (SingerId, FirstName, LastName)VALUES (39, 'George', 'Washington')`,}rowCount,err:=txn.Update(ctxWithTimeout,stmt)// Get the error code from the error. This function returns codes.OK if err == nil.code:=spanner.ErrCode(err)ifcode==codes.DeadlineExceeded{fmt.Fprintf(w,"Insert statement timed out.\n")}elseifcode==codes.OK{fmt.Fprintf(w,"%d record(s) inserted.\n",rowCount)}else{fmt.Fprintf(w,"Insert statement failed with error %v\n",err)}returnerr})iferr!=nil{returnerr}returnnil}

Java

staticvoidexecuteSqlWithTimeout(){// TODO(developer): Replace these variables before running the sample.StringprojectId="my-project";StringinstanceId="my-instance";StringdatabaseId="my-database";try(Spannerspanner=SpannerOptions.newBuilder().setProjectId(projectId).build().getService()){DatabaseClientclient=spanner.getDatabaseClient(DatabaseId.of(projectId,instanceId,databaseId));executeSqlWithTimeout(client);}}staticvoidexecuteSqlWithTimeout(DatabaseClientclient){CallContextConfiguratorconfigurator=newCallContextConfigurator(){public<ReqT,RespT>ApiCallContextconfigure(ApiCallContextcontext,ReqTrequest,MethodDescriptor<ReqT,RespT>method){// DML uses the ExecuteSql RPC.if(method==SpannerGrpc.getExecuteSqlMethod()){// NOTE: You can use a GrpcCallContext to set a custom timeout for a single RPC// invocation. This timeout can however ONLY BE SHORTER than the default timeout// for the RPC. If you set a timeout that is longer than the default timeout, then// the default timeout will be used.returnGrpcCallContext.createDefault().withCallOptions(CallOptions.DEFAULT.withDeadlineAfter(60L,TimeUnit.SECONDS));}// Return null to indicate that the default should be used for other methods.returnnull;}};// Create a context that uses the custom call configuration.Contextcontext=Context.current().withValue(SpannerOptions.CALL_CONTEXT_CONFIGURATOR_KEY,configurator);// Run the transaction in the custom context.context.run(()->client.readWriteTransaction().<long[]>run(transaction->{Stringsql="INSERT INTO Singers (SingerId, FirstName, LastName)\n"+"VALUES (20, 'George', 'Washington')";longrowCount=transaction.executeUpdate(Statement.of(sql));System.out.printf("%d record inserted.%n",rowCount);returnnull;}));}

Node.js

/** * TODO(developer): Uncomment the following lines before running the sample. */// const projectId = 'my-project-id';// const instanceId = 'my-instance';// const databaseId = 'my-database';// Imports the Google Cloud client libraryconst{Spanner}=require('@google-cloud/spanner');// Creates a clientconstspanner=newSpanner({projectId:projectId,});asyncfunctionexecuteSqlWithTimeout(){// Gets a reference to a Cloud Spanner instance and database.constinstance=spanner.instance(instanceId);constdatabase=instance.database(databaseId);try{awaitdatabase.runTransactionAsync(asynctx=>{// NOTE: You can use gaxOptions to set a custom timeout for a single RPC// invocation. This timeout can however ONLY BE SHORTER than the default timeout// for the RPC. If you set a timeout that is longer than the default timeout, then// the default timeout will be used.constquery={sql:"INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (110, 'George', 'Washington')",gaxOptions:{timeout:60000,// 60 seconds timeout},};constresults=awaittx.run(query);console.log(`${results[1].rowCountExact} record inserted.`);awaittx.commit();});}catch(err){console.error('ERROR:',err);}finally{awaitdatabase.close();}}executeSqlWithTimeout();

Python

# instance_id = "your-spanner-instance"# database_id = "your-spanner-db-id"spanner_client=spanner.Client()instance=spanner_client.instance(instance_id)database=instance.database(database_id)defwrite(transaction):# Insert a record and configure the statement timeout to 60 seconds# This timeout can however ONLY BE SHORTER than the default timeout# for the RPC. If you set a timeout that is longer than the default timeout,# then the default timeout will be used.row_ct=transaction.execute_update("INSERT INTO Singers (SingerId, FirstName, LastName) "" VALUES (110, 'George', 'Washington')",timeout=60,)print("{} record(s) inserted.".format(row_ct))database.run_in_transaction(write)

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.