---
title: "GitHub Copilot best practices"
answer: "GitHub Copilot emits two different response payload shapes, and which one you get determines how much token detail Coolhand can record. The newer shape carries `copilotUsage.tokenDetails`; the older one omits several fields, so some cost figures are estimates rather than reported values."
category: "Coding agents"
tags: ["copilot","github","coding-agents"]
published: 2026-08-30T13:57:53Z
updated: 2026-08-30T13:57:53Z
canonical_url: https://coolhandlabs.com/help/github-copilot-best-practices
index_url: https://coolhandlabs.com/help.md
---

# GitHub Copilot best practices

GitHub Copilot emits two different response payload shapes, and which one you get determines how much token detail Coolhand can record. The newer shape carries `copilotUsage.tokenDetails`; the older one omits several fields, so some cost figures are estimates rather than reported values.

---

## Response payload shape determines data quality

Coolhand extracts fields from two different Copilot response payload shapes:

| Field | Older payload | Newer payload (`copilotUsage.tokenDetails`) |
|-------|--------------|---------------------------------------------|
| Model name | From `response_body.model` | From `response_body.model` |
| Input token breakdown | Top-level `inputTokens` (net of cache) | `tokenDetails` entry with `tokenType: "input"` |
| Cached Input Tokens | Top-level `cacheReadTokens` | `tokenDetails` entry with `tokenType: "cache_read"` |
| Cache Creation Tokens | Top-level `cacheWriteTokens` | `tokenDetails` entry with `tokenType: "cache_write"` |
| Reasoning Tokens | `response_body.reasoningTokens` | `response_body.reasoningTokens` |
| Thinking Response | `response_body.reasoningText` | `response_body.reasoningText` |

Coolhand prefers the `copilotUsage.tokenDetails` array when present and falls back to top-level fields automatically. The branching is based on what the Copilot server returns in its response payload, not on a client SDK version.

**Note:** Token fields for cache reads/writes are inconsistently populated across Copilot environments — if they are blank, this is a known upstream behavior, not a Coolhand issue.

---

## Temperature is always blank

Copilot manages generation parameters server-side. You cannot set or observe temperature — it will always be blank in Coolhand.

---

## Structured outputs

Depends on the underlying model Copilot routes to. Not configurable directly — Copilot controls routing and model parameters.

---

## Caching

Managed entirely by Copilot server-side — there is no caller API for enabling or configuring caching. Coolhand captures what Copilot reports:
- **Cached Input Tokens** — from `cache_read` in `tokenDetails`, or `cacheReadTokens` as fallback
- **Cache Creation Tokens** — from `cache_write` in `tokenDetails`, or `cacheWriteTokens` as fallback

TTL and invalidation are opaque — Copilot does not expose cache lifecycle details to callers.

---

## Batch processing

No batch API. GitHub Copilot is designed for interactive, real-time use. There is no mechanism for submitting offline batch jobs.


---

Related:
- [Claude Code best practices](https://coolhandlabs.com/help/claude-code-best-practices.md)
- [Claude Cowork best practices](https://coolhandlabs.com/help/claude-cowork-best-practices.md)
- [AWS Bedrock best practices](https://coolhandlabs.com/help/aws-bedrock-best-practices.md)
- [What every field on an LLM request log means](https://coolhandlabs.com/help/llm-request-log-fields.md)

[← All help articles](https://coolhandlabs.com/help.md) · [Coding agents](https://coolhandlabs.com/help/category/coding-agents.md)
