> ## Documentation Index
> Fetch the complete documentation index at: https://namespace.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Report on usage

> Query compute, volume, and artifact usage, time series, concurrency, and instance reports with the TypeScript SDK.

`client.usage` reports what a workspace consumed. Compute, volume, and object storage usage are reported per billing period, while time series, concurrency, and instance reports answer more detailed questions.

The examples on this page use a Compute client:

```typescript theme={null}
import { createComputeClient } from "@namespacelabs/sdk/api/compute";

const client = createComputeClient();
```

Period-based methods take `periodStart` and `periodEnd` as calendar dates, not JavaScript `Date` objects. Each one is a `GetUsageRequest_Date` message, which you pass as an object literal. Both bounds are inclusive and must fall in the same month. When `periodStart` is omitted, the period starts on the first day of the current month.

## `usage.getUsage()`

Return compute usage for a billing period, in total and broken down per day.

<h3 id="usage-getusage-example">
  Example
</h3>

```typescript {1-3} theme={null}
const usage = await client.usage.getUsage({
  periodStart: { year: 2026, month: 9, day: 1 },
});

console.log(usage.total?.instanceMinutes?.unit);

for (const day of usage.perDay) {
  console.log(day.day, day.total?.instanceMinutes?.wall);
}
```

<h3 id="usage-getusage-api-reference">
  API reference
</h3>

```typescript theme={null}
getUsage(
  request: MessageInitShape<typeof GetUsageRequestSchema>,
  options?: CallOptions,
): Promise<GetUsageResponse>
```

<h4 id="usage-getusage-arguments-and-options">
  Arguments and options
</h4>

<ResponseField name="periodStart" type="{ year: number; month: number; day: number }">
  The first day of the period. Defaults to the first day of the current month.
</ResponseField>

<ResponseField name="periodEnd" type="{ year: number; month: number; day: number }">
  The last day of the period, inclusive. Must be in the same month as `periodStart`.
</ResponseField>

<ResponseField name="matchPlatform" type="StringMatcher">
  Only include usage from instances on a matching platform, such as `linux/amd64`.
</ResponseField>

<ResponseField name="matchShape" type="StringMatcher">
  Only include usage from instances with a matching shape, such as `2x8`.
</ResponseField>

<ResponseField name="matchGithubProfile" type="StringMatcher">
  Only include usage from instances with a matching GitHub profile.
</ResponseField>

<ResponseField name="matchGithubRepository" type="StringMatcher">
  Only include usage from instances with a matching GitHub repository.
</ResponseField>

<ResponseField name="options" type="CallOptions">
  Cancellation, timeout, and header options. See [Shared call options](/docs/reference/typescript-sdk/compute/manage#shared-call-options).
</ResponseField>

<h4 id="usage-getusage-return-value">
  Return value
</h4>

Returns a `GetUsageResponse` with `total` for the period and `perDay` records. Both report `instanceMinutes` and `builds`:

<ResponseField name="instanceMinutes" type="Minutes">
  `unit` counts compute units, where one unit is 1 vCPU and 2 GB of RAM for a minute. `wall` counts the total elapsed minutes instances were running.
</ResponseField>

<ResponseField name="builds" type="Builds">
  `count` is the number of build requests processed, with `unitMinutes` and `wallMinutes` reported the same way as for instances.
</ResponseField>

***

## `usage.getVolumeUsage()`

Return volume usage for a billing period. This covers cache volume snapshots and at-rest storage, and persistent block volume storage.

<h3 id="usage-getvolumeusage-example">
  Example
</h3>

```typescript {1-3} theme={null}
const { total } = await client.usage.getVolumeUsage({
  periodStart: { year: 2026, month: 9, day: 1 },
});

const cacheSnapshotGbHours = Number(total!.cacheSnapshotGbMinutes) / 60;
console.log(cacheSnapshotGbHours);
```

<h3 id="usage-getvolumeusage-api-reference">
  API reference
</h3>

```typescript theme={null}
getVolumeUsage(
  request: MessageInitShape<typeof GetVolumeUsageRequestSchema>,
  options?: CallOptions,
): Promise<GetVolumeUsageResponse>
```

<h4 id="usage-getvolumeusage-arguments-and-options">
  Arguments and options
</h4>

<ResponseField name="periodStart" type="{ year: number; month: number; day: number }">
  The first day of the period. Defaults to the first day of the current month.
</ResponseField>

<ResponseField name="periodEnd" type="{ year: number; month: number; day: number }">
  The last day of the period, inclusive.
</ResponseField>

<ResponseField name="options" type="CallOptions">
  Cancellation, timeout, and header options. See [Shared call options](/docs/reference/typescript-sdk/compute/manage#shared-call-options).
</ResponseField>

<h4 id="usage-getvolumeusage-return-value">
  Return value
</h4>

Returns a `GetVolumeUsageResponse` whose `total` reports three `bigint` values:

<ResponseField name="cacheSnapshotGbMinutes" type="bigint">
  Active cache volume snapshot usage, in GB-minutes. Divide by 60 for GB-hours.
</ResponseField>

<ResponseField name="cacheStorageMbMinutes" type="bigint">
  At-rest cache volume storage, in MB-minutes. Divide by `1024 * 60 * 24` for GB-days.
</ResponseField>

<ResponseField name="persistentVolumeStorageGbMinutes" type="bigint">
  At-rest persistent volume storage, in GB-minutes. Divide by `60 * 24` for GB-days.
</ResponseField>

***

## `usage.getArtifactUsage()`

Return object storage usage per product, covering at-rest storage and reads.

<h3 id="usage-getartifactusage-example">
  Example
</h3>

```typescript {1-3} theme={null}
const { products } = await client.usage.getArtifactUsage({
  periodStart: { year: 2026, month: 9, day: 1 },
});

for (const product of products) {
  console.log(product.product, product.storageGbMinutes, product.readsBytes);
}
```

<h3 id="usage-getartifactusage-api-reference">
  API reference
</h3>

```typescript theme={null}
getArtifactUsage(
  request: MessageInitShape<typeof GetArtifactUsageRequestSchema>,
  options?: CallOptions,
): Promise<GetArtifactUsageResponse>
```

<h4 id="usage-getartifactusage-arguments-and-options">
  Arguments and options
</h4>

<ResponseField name="periodStart" type="{ year: number; month: number; day: number }">
  The first day of the period. Defaults to the first day of the current month.
</ResponseField>

<ResponseField name="periodEnd" type="{ year: number; month: number; day: number }">
  The last day of the period, inclusive.
</ResponseField>

<ResponseField name="products" type="ArtifactProduct[]">
  Restricts the results to the given products: `REGISTRY`, `TURBOREPO`, `GITHUB_ARTIFACTS`, `BAZEL`, or `GRADLE`. When empty, all products are reported.
</ResponseField>

<ResponseField name="options" type="CallOptions">
  Cancellation, timeout, and header options. See [Shared call options](/docs/reference/typescript-sdk/compute/manage#shared-call-options).
</ResponseField>

<h4 id="usage-getartifactusage-return-value">
  Return value
</h4>

Returns a `GetArtifactUsageResponse` with one entry per product, each reporting `storageGbMinutes` and `readsBytes`.

***

## `usage.getUsageTimeSeries()`

Return compute usage as a time series over an explicit time range, with optional filters and breakdowns.

<h3 id="usage-getusagetimeseries-example">
  Example
</h3>

```typescript {3-7} theme={null}
import { timestampFromDate } from "@bufbuild/protobuf/wkt";

const { timeSeries } = await client.usage.getUsageTimeSeries({
  startTime: timestampFromDate(new Date("2026-09-01T00:00:00Z")),
  endTime: timestampFromDate(new Date("2026-09-08T00:00:00Z")),
  breakdownBy: ["shape"],
});

console.log(timeSeries?.timestamps.length);
```

<h3 id="usage-getusagetimeseries-api-reference">
  API reference
</h3>

```typescript theme={null}
getUsageTimeSeries(
  request: MessageInitShape<typeof GetUsageTimeSeriesRequestSchema>,
  options?: CallOptions,
): Promise<GetUsageTimeSeriesResponse>
```

<h4 id="usage-getusagetimeseries-arguments-and-options">
  Arguments and options
</h4>

<ResponseField name="startTime" type="Timestamp" required>
  Start of the time range, inclusive.
</ResponseField>

<ResponseField name="endTime" type="Timestamp" required>
  End of the time range, exclusive.
</ResponseField>

<ResponseField name="filter" type="UsageFilter">
  Restricts the data by platform, shape, purpose, GitHub repository, branch, workflow, job, profile, and conclusion, or by Buildkite organization, pipeline, repository, branch, job, and state. Each field is a `StringMatcher`.
</ResponseField>

<ResponseField name="breakdownBy" type="string[]">
  Dimension names to break the results down by. The response contains a separate time series per unique combination of breakdown values.

  Valid values are `platform`, `shape`, `purpose`, `github_repository`, `github_branch`, `github_workflow_name`, `github_job_name`, `buildkite_org_id`, `buildkite_pipeline_id`, `buildkite_pipeline_slug`, `buildkite_repository`, `buildkite_branch`, `buildkite_job_name`, and `buildkite_job_state`. The filter accepts some dimensions that are not valid here, such as `github_profile`.
</ResponseField>

<ResponseField name="options" type="CallOptions">
  Cancellation, timeout, and header options. See [Shared call options](/docs/reference/typescript-sdk/compute/manage#shared-call-options).
</ResponseField>

<h4 id="usage-getusagetimeseries-return-value">
  Return value
</h4>

Returns a `GetUsageTimeSeriesResponse` with a `timeSeries`. The series holds a shared `timestamps` array and named `doubles`, `integers`, and `strings` series aligned to it.

***

## `usage.getConcurrency()`

Return the configured concurrency limits and current active concurrency, per platform.

<h3 id="usage-getconcurrency-example">
  Example
</h3>

```typescript {1} theme={null}
const { concurrency } = await client.usage.getConcurrency({});

for (const platform of concurrency) {
  console.log(platform.name, platform.platforms, platform.activeConcurrency);
}
```

<h3 id="usage-getconcurrency-api-reference">
  API reference
</h3>

```typescript theme={null}
getConcurrency(
  request: MessageInitShape<typeof GetConcurrencyRequestSchema>,
  options?: CallOptions,
): Promise<GetConcurrencyResponse>
```

<h4 id="usage-getconcurrency-arguments-and-options">
  Arguments and options
</h4>

The request has no fields. Pass an empty object.

<ResponseField name="options" type="CallOptions">
  Cancellation, timeout, and header options. See [Shared call options](/docs/reference/typescript-sdk/compute/manage#shared-call-options).
</ResponseField>

<h4 id="usage-getconcurrency-return-value">
  Return value
</h4>

Returns a `GetConcurrencyResponse` with one `PlatformConcurrency` per platform group. Each entry carries a display `name` such as `Linux`, the `platforms` it covers such as `linux/amd64`, the configured `limits`, and the `activeConcurrency` in use. See [billing and limits](/docs/workspaces/billing-and-limits) for how limits are set.

***

## `usage.generateReport()`

Stream a detailed report listing every compute instance created in a time range. The server emits entries in batches.

<h3 id="usage-generatereport-example">
  Example
</h3>

```typescript {3-6} theme={null}
import { timestampFromDate } from "@bufbuild/protobuf/wkt";

for await (const batch of client.usage.generateReport({
  startTime: timestampFromDate(new Date("2026-09-01T00:00:00Z")),
  endTime: timestampFromDate(new Date("2026-09-08T00:00:00Z")),
})) {
  for (const entry of batch.entries) {
    console.log(entry.instanceId, entry.resourcesCpu, entry.destroyedAt);
  }
}
```

<h3 id="usage-generatereport-api-reference">
  API reference
</h3>

```typescript theme={null}
generateReport(
  request: MessageInitShape<typeof GenerateReportRequestSchema>,
  options?: CallOptions,
): AsyncIterable<GenerateReportResponse>
```

<h4 id="usage-generatereport-arguments-and-options">
  Arguments and options
</h4>

<ResponseField name="startTime" type="Timestamp" required>
  Start of the time range, inclusive. Only instances created within the range are reported.
</ResponseField>

<ResponseField name="endTime" type="Timestamp" required>
  End of the time range, exclusive.
</ResponseField>

<ResponseField name="filter" type="UsageFilter">
  The same filter accepted by [`getUsageTimeSeries()`](#usage-getusagetimeseries-arguments-and-options).
</ResponseField>

<ResponseField name="options" type="CallOptions">
  Cancellation, timeout, and header options. See [Shared call options](/docs/reference/typescript-sdk/compute/manage#shared-call-options).
</ResponseField>

<h4 id="usage-generatereport-return-value">
  Return value
</h4>

Returns an async iterable of `GenerateReportResponse`. Each message carries a batch of `entries`, and the server chooses how many entries to place in each message. An `InstanceReportEntry` reports the instance ID, creation, start, and destruction timestamps, requested and observed CPU and memory, attached volumes, and the GitHub or Buildkite job the instance served.

<Info>
  Report execution is constrained to 30 seconds. Any number of records can be downloaded within that window. Narrow the time range or the filter if a report does not complete.
</Info>

## Related documentation

<Columns cols={2}>
  <Card title="Billing and limits" icon="calculator" href="/docs/workspaces/billing-and-limits">
    How usage is priced and where workspace limits apply.
  </Card>

  <Card title="Usage explorer" icon="chart-column" href="/docs/dashboard/usage-explorer">
    Explore the same usage data in the dashboard.
  </Card>
</Columns>
