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-customOr 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 200If 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.