Slow Align Evaluator and experiment views: enable static-asset caching

Last updated: August 5, 2026

Symptom

On self-hosted LangSmith, the Align Evaluator UI (annotation queue and experiment comparison/results view) is slow to unusable. Loading a page fires a large burst of asset requests, and individual requests sit queued in the browser for tens of seconds. A fresh incognito window can feel faster briefly because it opens new connections instead of reusing a backed-up keep-alive queue.

Cause

The frontend nginx ConfigMap that ships with the LangSmith Helm chart does not set Cache-Control or expires on static assets (JS, CSS, fonts, SVG, images). Every page load re-downloads them. Over HTTP/1.1 those requests share a small number of connections, so later assets queue behind earlier ones and stall for seconds.

There is also a known product bug in the experiment comparison view: as you scroll, each new page of results also re-fetches page 0. With several pages loaded this multiplies request volume and adds seconds per scroll. This is tracked as LSE-2434 and requires a product fix; there is no operator-side workaround.

Resolution

The fix is to supply a custom frontend nginx ConfigMap that caches hashed static assets, and to confirm HTTP/2 is active at the browser-facing ingress. LangSmith frontend assets are content-hash-named at build time, so a long immutable cache is safe.

1. Retrieve the current nginx config

kubectl get configmap langsmith-frontend \
  -n <namespace> \
  -o jsonpath='{.data.nginx\.conf}'

2. Add a caching location block before the catch-all location /

# Cache hashed static assets permanently - safe because filenames include content hash
location ~* \.(woff2|woff|ttf|eot|js|css|svg|ico|png)$ {
    root   /tmp/build;
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable" always;
    try_files $uri =404;
}

location / {
    root   /tmp/build;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
}

3. Ship the modified config as a custom ConfigMap

Create a ConfigMap holding the full modified nginx.conf. Terraform example:

resource "kubernetes_config_map_v1" "langsmith_frontend_nginx" {
  metadata {
    name      = "langsmith-frontend-nginx-custom"
    namespace = kubernetes_namespace_v1.langsmith.metadata[0].name
  }
  data = {
    "nginx.conf" = <<-EOT
      <PASTE MODIFIED nginx.conf HERE>
    EOT
  }
}

4. Point the Helm release at the custom ConfigMap

Set frontend.existingConfigMapName in your Helm values to the name of the new ConfigMap:

frontend:
  existingConfigMapName: langsmith-frontend-nginx-custom

Or in a Terraform helm_release values block:

frontend = {
  existingConfigMapName = kubernetes_config_map_v1.langsmith_frontend_nginx.metadata[0].name
}

Apply with helm upgrade or terraform apply.

5. Confirm HTTP/2 at the ingress

HTTP/2 removes the head-of-line blocking that makes uncached assets painful. Istio handles HTTP/2 inside the mesh automatically. Check the browser-facing ingress:

curl -sI --http2 https://<langsmith-hostname>/ | head -1
# Expected: HTTP/2 200

If the response is not HTTP/2 200, enable HTTP/2 on the external ingress or gateway.

Experiment view pagination

The duplicate page-0 re-fetch on each lazy-load in the experiment comparison view is a tracked product bug (LSE-2434) and will be fixed in a future release. Caching static assets and confirming HTTP/2 removes the dominant source of slowness in the meantime.

References