Files
coder/docs/tutorials/best-practices/speed-up-templates.md
T
Nick Vigilante c84aa564ba docs: normalize code-fence languages for Shiki compatibility (#27161)
Normalizes non-standard code-fence language tags across `docs/**` so a
strict highlighter (Shiki, used by Fumadocs) won't fail the build on an
unrecognized language, and unifies redundant synonym tags onto one
canonical form per language. The current renderer (Speed-Highlight)
detects the language from the code content, not the fence label, so this
drift wasn't visible until now.

## Changes

- `hcl` -> `tf` (199 fences, including indented ones nested in
numbered/bulleted lists). Shiki ships `hcl` and `terraform` as two
distinct grammars (not aliases); every `hcl`-tagged fence in `docs/**`
is actually Terraform resource/data/provider syntax, so the more
specific `terraform` grammar is correct for all of them. `tf` is Shiki's
own alias for that grammar, and it's also what GitHub's own markdown
renderer resolves to the same HCL/Terraform highlighting.
- `pwsh`/`powershell` -> `ps1`. Both `ps` and `ps1` are registered
PowerShell aliases in Shiki, but on GitHub's renderer only `.ps1` is a
registered file extension (`.ps` isn't), so `ps1` renders identically to
`powershell` there today while bare `ps` would silently lose
highlighting.
- `env` -> `dotenv` (a dedicated Shiki grammar for `KEY=VALUE` files)
- `text`/`output`/`none`/`url` -> `txt`. Same built-in plain-text
fallback either way, just shorter.
- `Dockerfile` -> `dockerfile` (lowercase)
- `bash`/`shell` -> `sh` (732 fences). Shiki and GitHub both alias all
three to a single shell grammar; this was already the style guide's
stated preference, just not enforced across the existing corpus until
now.
- `markdown` -> `md` (4 fences). Alias of the same grammar in both Shiki
and GitHub.
- `jsonc` -> `json` (1 fence). The block has no comments or trailing
commas, so it doesn't need the comments-capable grammar.
- `ts` -> `tsx` (2 fences, `docs/about/contributing/frontend.md`).
Verified the actual content tokenizes identically under both grammars,
and a sibling block in the same file already needs `tsx` for real JSX,
so unifying to one tag is safe for this file. Documented a caveat: `tsx`
mis-tokenizes the legacy angle-bracket type-assertion syntax
(`<Type>value`), which is invalid in real `.tsx` files anyway, so use
`value as Type` instead.
- `yml` -> `yaml` (1 fence)
- Updated `docs/.style/style-guide/formatting.md` to document all
canonical tags

`promql` (2 fences) and `caddyfile` (2 fences) are left as-is. Shiki
doesn't bundle a grammar for either, so they need a custom grammar
registration when the site adopts Shiki, rather than degrading to `txt`.
Tracked as follow-up work under DOCS-118 and
[DOCS-544](https://linear.app/codercom/issue/DOCS-544/vendor-a-local-promql-grammar-for-shiki-syntax-highlighting)
(promql).

Does not touch `offlinedocs/`.

Linear:
[DOCS-476](https://linear.app/codercom/issue/DOCS-476/normalize-docs-code-fence-languages-de-risk-shikifumadocs)

<details>
<summary>How the fence tags were verified</summary>

Each tag was tested against a real `shiki@latest` highlighter instance
(`codeToHtml`/`codeToTokens`) and cross-checked against GitHub's
`@wooorm/starry-night` grammar sources (the renderer that actually
displays these `.md` files today, in repo browsing and PR diffs), since
that's what determines whether brevity is safe before Shiki adoption:

```text
FAIL  env        -- Language `env` is not included in this bundle.
FAIL  Dockerfile -- Language `Dockerfile` is not included in this bundle.
FAIL  promql     -- Language `promql` is not included in this bundle.
FAIL  caddyfile  -- Language `caddyfile` is not included in this bundle.
FAIL  pwsh       -- Language `pwsh` is not included in this bundle.
FAIL  output     -- Language `output` is not included in this bundle.
```

`hcl` doesn't error in Shiki, since it's a real grammar, but that's
exactly the trap: it was silently rendering every fence with the generic
HCL grammar instead of the Terraform-specific one. Every `hcl`-tagged
fence in `docs/**` was manually checked against `origin/main` and is
genuinely Terraform content.

For `ts`/`tsx`, tokenizing the actual doc content confirmed identical
output under both grammars; a synthetic test with the legacy
angle-bracket cast syntax confirmed `tsx` degrades on that specific
construct, which the style guide now calls out.

The first normalization pass only matched fence tags at column 0
(`^```tag$`), missing tags indented inside numbered/bulleted lists. A
follow-up pass caught the remaining occurrences at any indentation
level.

</details>


---

*This PR description and the underlying changes were prepared with Coder
Agents assistance.*
2026-07-15 14:07:09 -04:00

5.9 KiB

Speed up your Coder templates and workspaces

October 31, 2024


If it takes your workspace a long time to start, find out why and make some changes to your Coder templates to help speed things up.

Monitoring

You can monitor Coder logs through the system-native tools on your deployment platform, or stream logs to tools like Splunk, Datadog, Grafana Loki, and others.

Workspace build timeline

Use the Build timeline to monitor the time it takes to start specific workspaces. Identify long scripts, resources, and other things you can potentially optimize within the template.

Screenshot of a workspace and its build timeline

You can also retrieve this detail programmatically from the API:

curl -X GET https://coder.example.com/api/v2/workspacebuilds/{workspacebuild}/timings \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'

Visit the API documentation for more information.

Coder Observability Chart

Use the Observability Helm chart for a pre-built set of dashboards to monitor your Coder deployments over time. It includes pre-configured instances of Grafana, Prometheus, Loki, and Alertmanager to ingest and display key observability data.

We recommend that all administrators deploying on Kubernetes or on an existing Prometheus or Grafana stack set the observability bundle up with the control plane from the start. For installation instructions, visit the observability repository, or our Kubernetes installation guide.

Enable Prometheus metrics for Coder

Coder exposes a variety of application metrics, such as coderd_provisionerd_job_timings_seconds and coderd_agentstats_startup_script_seconds, which measure how long the workspaces take to provision and how long the startup scripts take.

To make use of these metrics, you will need to enable Prometheus metrics exposition.

If you are not using the Observability Chart, you will need to install Prometheus and configure it to scrape the metrics from your Coder installation.

Provisioners

coder server by default provides three built-in provisioner daemons (controlled by the CODER_PROVISIONER_DAEMONS config option). Each provisioner daemon can handle one single job (such as start, stop, or delete) at a time and can be resource intensive. When all provisioners are busy, workspaces enter a "pending" state until a provisioner becomes available.

Increase provisioner daemons

Provisioners are queue-based to reduce unpredictable load to the Coder server. If you require a higher bandwidth of provisioner jobs, you can do so by increasing the CODER_PROVISIONER_DAEMONS config option.

You risk overloading Coder if you use too many built-in provisioners, so we recommend a maximum of five built-in provisioners per coderd replica. For more than five provisioners, we recommend that you move to External Provisioners and also consider High Availability to run multiple coderd replicas.

Visit the CLI documentation for more information about increasing provisioner daemons, configuring external provisioners, and other options.

Adjust provisioner CPU/memory

We recommend that you deploy Coder to its own respective Kubernetes cluster, separate from production applications. Keep in mind that Coder runs development workloads, so the cluster should be deployed as such, without production-level configurations.

Adjust the CPU and memory values as shown in Helm provisioner values.yaml:

…
  resources:
    limits:
      cpu: "0.25"
      memory: "1Gi"
    requests:
      cpu: "0.25"
      memory: "1Gi"
…

Visit the validated architecture documentation for more information.

Set up Terraform provider caching

Template lock file

On each workspace build, Terraform will examine the providers used by the template and attempt to download the latest version of each provider unless it is constrained to a specific version. Terraform exposes a mechanism to build a static list of provider versions, which improves cacheability.

Without caching, Terraform will download each provider on each build, and this can create unnecessary network and disk I/O.

terraform init generates a .terraform.lock.hcl which instructs Coder provisioners to cache specific versions of your providers.

To use terraform init to build the static provider version list:

  1. Pull your template to your local device:

    coder templates pull <template>
    
  2. Run terraform init inside the template directory to build the lock file:

    terraform init
    
  3. Push the templates back to your Coder deployment:

    coder templates push <template>
    

This bundles up your template and the lock file and uploads it to Coder. The next time the template is used, Terraform will attempt to cache the specific provider versions.

Cache directory

Coder will instruct Terraform to cache its downloaded providers in the configured CODER_CACHE_DIRECTORY directory.

Ensure that this directory is set to a location on disk which will persist across restarts of Coder or external provisioners, if you're using them.