Production-grade backend service development across Node.js (Express/Fastify/NestJS/Hono), Bun, Python (FastAPI), Go, and Rust (Axum), with PostgreSQL and common ORMs...
Use this skill for backend service implementation and review: API boundaries, auth, data access, jobs, caching, observability, and production hardening. If the main question is platform selection, system topology, or API-contract design without implementation, hand off early.
When this skill is active, prefer these defaults unless the repo or user says otherwise:
| Need | Default Direction |
|---|---|
| Public HTTP API | REST with explicit contracts and timeouts |
| Internal TS monorepo API | tRPC when end-to-end type safety matters |
| High-throughput internal RPC | Connect or gRPC |
| Complex client-shaped reads | GraphQL |
| Relational data | PostgreSQL with migrations and pooling |
| Background work | Queue plus idempotent handlers and DLQ policy |
| Browser auth | OIDC or OAuth plus httpOnly cookies |
| Service auth | short-lived tokens, workload identity, or signed service credentials |
| Caching | explicit TTLs and invalidation rules |
| Observability | correlation IDs, traces, structured logs, saturation metrics |
Backend task
-> Define endpoint, job, service, or data boundary
-> Confirm runtime, framework, persistence, and integration contracts
-> Design request validation, auth, errors, and idempotency
-> Implement bounded slice with tests and observability
-> Check performance, security, and rollout risk
-> Verify behavior and document follow-up handoffs
Pick based on the strongest operational constraint:
sqlc/pgxUse software-baas-platforms first when the real requirement is "ship auth, storage, and realtime quickly with less custom service code."
| Category | Rule |
|---|---|
| API | Mutating endpoints require idempotency keys where retries are plausible |
| API | List endpoints require explicit pagination (limit/cursor) and at least one filter |
| API | Errors are structured and machine-readable (RFC 9457 Problem Details) |
| API | Health endpoints separate liveness (/healthz) from readiness (/readyz) |
| Data | No SELECT * on wide or high-volume paths |
| Data | Transactions kept explicit; no implicit ambient transactions |
| Data | New or changed query plans verified with EXPLAIN ANALYZE before production |
| Data | ORM convenience layers bypassed on hot paths where auditability matters |
| Dependencies | Every outbound call has an explicit timeout; no framework-default infinite wait |
| Dependencies | Retries owned at exactly one layer (no double-retry across client + service) |
| Dependencies | Cache invalidation rule documented before caching is added |
| Dependencies | Background jobs safe to retry and observable (structured log on start/finish/failure) |
| Operations | Every request carries a correlation ID propagated to all downstream calls |
| Operations | Trace, log, and metric identifiers agree (no split identity) |
| Operations | Slow paths have explicit latency budgets (p99 target, not "fast enough") |
| Operations | Deploy procedure includes rollback step and smoke-check list |
When a service is slow or unstable, debug in this order:
| Step | Check | Signal |
|---|---|---|
| 1 | Query behavior and N+1s | EXPLAIN output, ORM query log showing repeated identical queries |
| 2 | Indexes and execution plans | Seq scans on large tables, missing index on FK or filter columns |
| 3 | Connection pooling and queue depth | Pool wait time > 10ms; idle connections exhausted |
| 4 | Timeout and cancellation gaps | Requests hanging past deadline; no context propagation through outbound calls |
| 5 | Caching or read-shaping opportunities | Same query with same result executing > 10x/s; hot read path with no invalidation |
| 6 | Runtime or tier limits | CPU throttling, memory pressure, rate limit headers from upstream |
Do not add caching before you understand the real bottleneck.
Before marking a service production-ready:
EXPLAIN ANALYZE) before merge to mainGate before invoking any foundation below: Each foundation has a
When to Apply/When to Skipsection. If your task matches a skip-condition, route to the foundation it names instead — don't pull in primitives the task doesn't need.
Before applying this skill on a non-trivial task, read learnings.consolidated.md in this directory (and learnings.md if present).
After applying it, if you encountered a pattern worth remembering, a mistake worth preventing, or a domain fact that surprised you, append one dated bullet to learnings.md via agents-skills-feedback-loop/scripts/append_learning.py. Do not modify SKILL.md itself.