Getting Device State

With Cloud IoT Core, you can monitor the state of each connected device. State is reported by the device as binary data. Device state updates are typically triggered by a change to the device — either a configuration update from Cloud IoT Core, or a similar change from another external source, such as a firmware update.

Device state differs from device configuration. Configuration data is sent to the device from Cloud IoT Core. State data is sent by the device to Cloud IoT Core. You might think of configuration as an external instruction, and of state as an internal representation.

Cloud IoT Core can help you answer basic questions about configuration and state: What does the device currently "think" it should be doing? How does that compare to the most recent configuration for the device?


State updates are limited to 1 update per second, per device. However, for best results, device state should be updated much less often — at most, once every 10 seconds.

The update rate is calculated as the time between the most recent server acknowledgment and the next update request.

Reporting device state

MQTT bridge

In Cloud IoT Core, device state is published to an MQTT topic. This topic is separate from the MQTT topic to which telemetry events are published.

Cloud IoT Core uses the following MQTT topic for device state messages:


HTTP bridge

To report state to Cloud IoT Core through the HTTP bridge, devices should use a setState request. The binary state data is passed in the body of the request as a base64-encoded string.

As with all HTTP bridge requests, a JWT must be passed in the header. For more details, see the section on the HTTP bridge.

Getting device state data

This section explains how to get the state data that's reported to Cloud IoT Core by devices. (Devices themselves cannot read state data from the cloud.)

State data is returned in binary format. State data may have a different structure than the configuration data that triggers the state change.

For example, suppose you have a device with several fans. Your configuration data might be a JSON object containing a simple Boolean that enables or disables cooling:

Example of configuration data

  'cooling': true

But the device's state data might include diagnostic information, as well as the fan data that you'd expect to see in response to a 'cooling' change:

Example of state data

  'fan1_target_rpm': 1000,
  'fan2_target_rpm': 1200,
  'firmware_version': '1.2.3b'

The device's firmware_version is not related to the configuration data, but the device returns the full internal representation of its state. This example illustrates how device state can be useful for debugging in general, as well as for confirming that devices have acknowledged specific configurations.

You can get device state data using a Cloud Pub/Sub topic, Cloud Platform Console, the Cloud IoT Core API, or gcloud.

Cloud Pub/Sub Topic

Cloud IoT Core retains state data in storage. You can also configure an optional state notification Cloud Pub/Sub topic in each device registry, via Cloud Console, gcloud, or the API. This topic can be the same as or different from the telemetry event topic.

State data is published to Cloud Pub/Sub on a best-effort basis: if publication to the topic fails, it will not be retried. If no topic is defined, device state updates are still persisted internally by Cloud IoT Core, but only the last 10 states are retained.


  1. Go to the Device details page for the specific device.

  2. Click Device config & state history to see a list of recent configuration and state data. Use the checkboxes to display configuration history, state history, or both. By default, both are displayed.

    • A green checkmark indicates that the device has acknowledged the configuration. (MQTT only)
    • A yellow warning symbol indicates that the device has not yet acknowledged the configuration. (MQTT only)
    • Click a row to get the full configuration or state data in JSON, as well as the timestamp and version.
  3. Click Compare histories to compare the configuration data with the state data. This view can help you debug configurations and, if you are using MQTT, make sure devices have acknowledged specific configuration versions. (The HTTP bridge does not support acknowledgment of configurations.)


To get the most recent state messages for a device (up to 10), run the gcloud iot devices states list command.

gcloud iot devices states list \
    --registry=REGISTRY_ID \
    --device=DEVICE_ID \

A state notification Cloud Pub/Sub flag (--state-pubsub-topic) is available for the gcloud iot registries create and update commands:

gcloud iot registries create REGISTRY_ID \
    --project=PROJECT_ID \
    --region=REGION \
    [--event-notification-config=topic=TOPIC,[subfolder=SUBFOLDER] [--event-notification-config=...]]

gcloud iot registries update REGISTRY_ID \
    --project=PROJECT_ID \
    --region=REGION \
    [--event-notification-config=topic=TOPIC,[subfolder=SUBFOLDER] [--event-notification-config=...]]


Use the Device states.list method to get the most recent device states (up to 10). Each Device resource has a DeviceState field that contains the state most recently received from the device. The DeviceRegistry resource has a StateNotificationConfig field that can be used to specify a state notification Cloud Pub/Sub topic when creating or updating a registry.

The following sample shows how to retrieve device state from a device registry:


public static object GetDeviceStates(string projectId, string cloudRegion, string registryId, string deviceId)
    var cloudIot = CreateAuthorizedClient();

    // The resource name of the location associated with the key rings.
    var name = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}/devices/{deviceId}";

        Console.WriteLine("States: ");
        var res = cloudIot.Projects.Locations.Registries.Devices.States.List(name).Execute();
        res.DeviceStates.ToList().ForEach(state =>
            Console.WriteLine($"\t{state.UpdateTime}: {state.BinaryData}");
    catch (Google.GoogleApiException e)
        if (e.Error != null) return e.Error.Code;
        return -1;
    return 0;


// Authorize the client using Application Default Credentials.
// See
ctx := context.Background()
httpClient, err := google.DefaultClient(ctx, cloudiot.CloudPlatformScope)
if err != nil {
	return nil, err
client, err := cloudiot.New(httpClient)
if err != nil {
	return nil, err

path := fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", projectID, region, registry, device)
response, err := client.Projects.Locations.Registries.Devices.States.List(path).Do()
if err != nil {
	return nil, err

fmt.Println("Successfully retrieved device states!")

for _, state := range response.DeviceStates {
	fmt.Println(state.UpdateTime, " : ", state.BinaryData)


/** Retrieves device metadata from a registry. **/
public static List<DeviceState> getDeviceStates(
    String deviceId, String projectId, String cloudRegion, String registryName)
    throws GeneralSecurityException, IOException {
  GoogleCredential credential =
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(credential);
  final CloudIot service = new CloudIot.Builder(
      GoogleNetHttpTransport.newTrustedTransport(),jsonFactory, init)

  final String devicePath = String.format("projects/%s/locations/%s/registries/%s/devices/%s",
      projectId, cloudRegion, registryName, deviceId);

  System.out.println("Retrieving device states " + devicePath);

  ListDeviceStatesResponse resp  = service

  return resp.getDeviceStates();


// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const deviceId = 'my-device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const request = {
  name: `${registryName}/devices/${deviceId}`

    (err, data) => {
      if (err) {
        console.log('Could not find device:', deviceId);
      } else {
        console.log('State:', data);


This sample uses the Google API Client Library for Python.
def get_state(
        service_account_json, project_id, cloud_region, registry_id,
    """Retrieve a device's state blobs."""
    client = get_client(service_account_json)
    registry_name = 'projects/{}/locations/{}/registries/{}'.format(
            project_id, cloud_region, registry_id)

    device_name = '{}/devices/{}'.format(registry_name, device_id)
    devices = client.projects().locations().registries().devices()
    state = devices.states().list(name=device_name, numStates=5).execute()

    print('State: {}\n'.format(state))

    return state


# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to get device states from"
# device_id   = "The identifier of the device to get states for"

require "google/apis/cloudiot_v1"

# Initialize the client and authenticate with the specified scope
Cloudiot   = Google::Apis::CloudiotV1
iot_client =
iot_client.authorization = Google::Auth.get_application_default(

# The resource name of the location associated with the project
parent   = "projects/#{project_id}/locations/#{location_id}"
resource = "#{parent}/registries/#{registry_id}/devices/#{device_id}"

# List the configurations for the provided device
res = iot_client.list_project_location_registry_device_states(
if res.device_states
  res.device_states.each do |state|
    puts "#{state.update_time}: #{state.binary_data}"
  puts "No state messages"

Send feedback about...

Google Cloud Internet of Things Core