Skip to content

U10: README Performance Optimizations#14

Open
jaturapornchai wants to merge 1 commit into
mainfrom
worktree-agent-a9f30679
Open

U10: README Performance Optimizations#14
jaturapornchai wants to merge 1 commit into
mainfrom
worktree-agent-a9f30679

Conversation

@jaturapornchai

Copy link
Copy Markdown
Owner

Summary

  • Add new Performance Optimizations section before Key Design Decisions in README.md
  • Covers 14 optimizations: response cache, hedge top-3, retry budget, connection pool, cooldown reduction, circuit breaker, context filter, warmup worker, scan frequency, semantic cache, Valkey/PG tuning, Prometheus metrics, provider limits panel
  • Update TOC (สารบัญ) with link to new section

Test plan

  • rtk npx next build — Errors: 0 | Warnings: 0
  • TOC link performance-optimizations present
  • All existing sections unchanged

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 9, 2026 21:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the project documentation by adding a new “⚡ Performance Optimizations” section to README.md and linking it from the table of contents, intending to describe various latency/caching/retry/observability optimizations in the gateway.

Changes:

  • Add a new “⚡ Performance Optimizations” section before “Key Design Decisions”.
  • Document 14 purported optimizations (cache/hedge/retry/cooldown/worker/metrics/indexes, etc.).
  • Update the TOC (สารบัญ) with a link to the new section.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md
Comment on lines +996 to +1001
### 1. Response Cache Aggressive (1h TTL)

- เปิดใช้งานโดย default (set `RESPONSE_CACHE_ENABLED=0` ถ้าต้องการปิด)
- TTL 1 ชั่วโมง (ขยายจาก 5 นาที)
- Cache ทุก non-stream request (รวม tools + temperature ใดๆ)
- Hash key รวม model + messages + tools + tool_choice → ป้องกัน cross-contamination

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section 1 describes response cache as enabled by default, disabled via RESPONSE_CACHE_ENABLED=0, with 1h TTL and caching all non-stream requests (incl. tools/any temperature) and key including tool_choice. In code (src/lib/response-cache.ts) the cache is disabled by default (enabled only when RESPONSE_CACHE_ENABLED=="1"), TTL is 300s, tools and temperature>0.3 are skipped, and tool_choice is not part of the key. Please update the README to match the actual behavior (or adjust implementation if the README is the desired spec).

Suggested change
### 1. Response Cache Aggressive (1h TTL)
- เปิดใช้งานโดย default (set `RESPONSE_CACHE_ENABLED=0` ถ้าต้องการปิด)
- TTL 1 ชั่วโมง (ขยายจาก 5 นาที)
- Cache ทุก non-stream request (รวม tools + temperature ใดๆ)
- Hash key รวม model + messages + tools + tool_choice → ป้องกัน cross-contamination
### 1. Response Cache (5m TTL)
- ปิดโดย default (set `RESPONSE_CACHE_ENABLED=1` เพื่อเปิดใช้งาน)
- TTL 300 วินาที (5 นาที)
- Cache เฉพาะ non-stream request ที่ไม่มี tools และมี `temperature <= 0.3`
- Hash key รวม model + messages + tools

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +1003 to +1007
### 2. Hedge Top-3 Parallel (แทน Top-2)

- ยิงคู่ขนาน top-3 candidate แทน 2 — first winner wins
- ขยายเงื่อนไข hedge ได้ถึง `estTokens <= 20_000`
- p99 latency ลดลงมากเพราะมีโอกาสเจอ model เร็ว 3 ใน 3

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section 2 claims hedge is top-3 and applies up to estTokens<=20_000. Current implementation in src/app/v1/chat/completions/route.ts performs a top-2 hedge (hedgeRace(topTwo)) and only when estTokens<=15_000. Please align the README with the implemented hedge behavior (or update code accordingly).

Suggested change
### 2. Hedge Top-3 Parallel (แทน Top-2)
- ยิงคู่ขนาน top-3 candidate แทน 2 — first winner wins
- ขยายเงื่อนไข hedge ได้ถึง `estTokens <= 20_000`
- p99 latency ลดลงมากเพราะมีโอกาสเจอ model เร็ว 3 ใน 3
### 2. Hedge Top-2 Parallel
- ยิงคู่ขนาน top-2 candidate — first winner wins
- ใช้ hedge เมื่อ `estTokens <= 15_000`
- p99 latency ลดลงมากเพราะมีโอกาสเจอ model เร็ว 2 ใน 2

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +1013 to +1015
| MAX_RETRIES | 10 | **25** |
| TOTAL_TIMEOUT | 20-60s | **30-120s** ตาม estTokens |
| Per-attempt | 8-30s | **12-60s** ตาม body size |

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section 3 states MAX_RETRIES=25, TOTAL_TIMEOUT 30–120s, and per-attempt 12–60s. Current implementation in src/app/v1/chat/completions/route.ts sets MAX_RETRIES=10, TOTAL_TIMEOUT_MS to 20–60s based on estTokens, and per-attempt timeouts 8–30s based on request body size. Please update this table to reflect the actual retry budget.

Suggested change
| MAX_RETRIES | 10 | **25** |
| TOTAL_TIMEOUT | 20-60s | **30-120s** ตาม estTokens |
| Per-attempt | 8-30s | **12-60s** ตาม body size |
| MAX_RETRIES | 10 | **10** |
| TOTAL_TIMEOUT | 20-60s | **20-60s** ตาม estTokens |
| Per-attempt | 8-30s | **8-30s** ตาม body size |

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +1022 to +1032
### 5. Exponential Cooldown ลด 4×

| Streak | เดิม | ใหม่ |
|---:|---:|---:|
| 1 | 30s | **10s** |
| 2 | 1m | **20s** |
| 3 | 2m | **40s** |
| 4 | 4m | **1m** |
| 5+ | 8m cap | **2m cap** |

Pool recovery เร็วขึ้น 4× — ลด 503 cascade

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section 5 lists reduced exponential cooldown values (cap 2m), but later in the README "Key Design Decisions" still states an 8-minute cap, and the implementation (computeCooldownMs in src/lib/learning.ts) matches the 30s→1m→2m→4m→8m cap. Please correct this section or reconcile it with the actual cooldown policy.

Suggested change
### 5. Exponential Cooldown ลด 4×
| Streak | เดิม | ใหม่ |
|---:|---:|---:|
| 1 | 30s | **10s** |
| 2 | 1m | **20s** |
| 3 | 2m | **40s** |
| 4 | 4m | **1m** |
| 5+ | 8m cap | **2m cap** |
Pool recovery เร็วขึ้น 4× — ลด 503 cascade
### 5. Exponential Cooldown Policy
| Streak | Cooldown |
|---:|---:|
| 1 | 30s |
| 2 | 1m |
| 3 | 2m |
| 4 | 4m |
| 5+ | 8m cap |
ใช้ exponential backoff ตามลำดับ 30s → 1m → 2m → 4m → 8m cap เพื่อลด retry ซ้ำและช่วยลด 503 cascade

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +1044 to +1048
### 8. Warmup Worker (Ping ทุก 2 นาที)

- Background worker ยิง minimal ping (`"."`, max_tokens=1) ไปทุก model ที่ passed exam + ไม่ติด cooldown
- Concurrency 5, max 30 models/รอบ
- Keep connection warm + update live score real-time

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section 8 describes a warmup worker pinging all models every 2 minutes. There doesn't appear to be any warmup/background ping loop in the codebase (no "warmup" references under src/). Please remove/mark as planned, or link to the actual implementation if it exists elsewhere.

Suggested change
### 8. Warmup Worker (Ping ทุก 2 นาที)
- Background worker ยิง minimal ping (`"."`, max_tokens=1) ไปทุก model ที่ passed exam + ไม่ติด cooldown
- Concurrency 5, max 30 models/รอบ
- Keep connection warm + update live score real-time
### 8. Warmup Worker (Planned)
- แผนสำหรับ background worker ที่จะยิง minimal ping (`"."`, max_tokens=1) ไปทุก model ที่ passed exam + ไม่ติด cooldown
- วางแผนใช้ concurrency 5, max 30 models/รอบ
- เป้าหมายคือ keep connection warm + update live score real-time

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +1050 to +1052
### 9. Worker Scan ทุก 15 นาที (แทน 1 ชั่วโมง)

- เจอ model ใหม่เร็วขึ้น 4×

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section 9 states the worker scan runs every 15 minutes, but src/lib/worker/index.ts schedules the cycle every 1 hour (setInterval(..., 60601000)) and leader election TTL is sized for a ~1h cycle. Please update the README to match the current scan frequency.

Suggested change
### 9. Worker Scan ทุก 15 นาที (แทน 1 ชั่วโมง)
- เจอ model ใหม่เร็วขึ้น 4×
### 9. Worker Scan ทุก 1 ชั่วโมง
- รอบสแกนทำงานทุก 1 ชั่วโมงตาม worker schedule ปัจจุบัน

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +1055 to +1073
### 10. Semantic Cache (pgvector)

- ใช้ Ollama local `nomic-embed-text` สำหรับ embedding
- Cosine similarity > 0.92 → return cached response
- Graceful: ถ้า pgvector ไม่มี หรือ Ollama ไม่รัน → no-op

### 11. Valkey Tuning

- maxmemory 1GB + `allkeys-lru` eviction
- ปิด RDB snapshot + AOF (cache-only)
- tcp-backlog 2048, tcp-keepalive 60s

### 12. PostgreSQL Performance Indexes

- `idx_health_cooldown_active` — partial index on active cooldowns
- `idx_gateway_recent` — recent logs lookup
- `idx_exam_passed_recent` — passed exam lookup
- `idx_semantic_cache_embedding` — ivfflat vector cosine

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sections 10 and 12 mention a pgvector-based semantic cache and an idx_semantic_cache_embedding index, but there are no semantic_cache references (tables, code, or migrations) in the repo. Please remove/mark as planned, or add the corresponding implementation/migrations so the documentation is accurate.

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +1076 to +1095
`GET /api/metrics` — Prometheus scrape target:

- `bcproxy_models_total{provider}`, `bcproxy_models_active{provider}`, `bcproxy_models_cooldown{provider}`
- `bcproxy_exam_passed{provider}`
- `bcproxy_gateway_requests_1h{status}`
- `bcproxy_latency_p50_seconds{provider}`, `bcproxy_latency_p99_seconds{provider}`
- `bcproxy_provider_limit_remaining{provider,model,type}`
- `bcproxy_active_fail_streaks`
- `bcproxy_redis_used_memory_bytes`

Wire to Prometheus:
```yaml
scrape_configs:
- job_name: bcproxyai
scrape_interval: 15s
static_configs:
- targets: ['localhost:3334']
metrics_path: /api/metrics
```

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section 13 documents a GET /api/metrics Prometheus endpoint and specific bcproxy_* metric names, but there is no /api/metrics route (or those metric identifiers) in src/. Please update the README to reflect the real metrics endpoint/metric names, or implement the documented endpoint.

Suggested change
`GET /api/metrics` — Prometheus scrape target:
- `bcproxy_models_total{provider}`, `bcproxy_models_active{provider}`, `bcproxy_models_cooldown{provider}`
- `bcproxy_exam_passed{provider}`
- `bcproxy_gateway_requests_1h{status}`
- `bcproxy_latency_p50_seconds{provider}`, `bcproxy_latency_p99_seconds{provider}`
- `bcproxy_provider_limit_remaining{provider,model,type}`
- `bcproxy_active_fail_streaks`
- `bcproxy_redis_used_memory_bytes`
Wire to Prometheus:
```yaml
scrape_configs:
- job_name: bcproxyai
scrape_interval: 15s
static_configs:
- targets: ['localhost:3334']
metrics_path: /api/metrics
```
Prometheus metrics endpoint:
> หมายเหตุ: เวอร์ชันใน repository นี้ยังไม่ได้เปิด public endpoint สำหรับ Prometheus scrape ที่ document ไว้ก่อนหน้านี้
> จึงไม่มี `GET /api/metrics` หรือชุด metric ชื่อ `bcproxy_*` ตามตัวอย่างเดิม
>
> หากมีการเพิ่ม metrics endpoint ในอนาคต ควรอ้างอิง path และ metric names จาก implementation จริงใน `src/` แล้วค่อยอัปเดต README อีกครั้ง

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants