Software Backend Engineering
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.
Defaults
When this skill is active, prefer these defaults unless the repo or user says otherwise:
- validate at the boundary and keep types explicit
- use PostgreSQL plus pooling for relational workloads
- use structured logs, OpenTelemetry, explicit timeouts, and rate limits
- make mutations idempotent and background work retry-safe
- use RFC 9457 Problem Details for machine-readable errors
Quick Reference
| 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 |
When to Use This Skill
- building or reviewing REST, GraphQL, tRPC, Connect, or gRPC services
- implementing auth, validation, rate limits, caching, queues, or webhook handling
- modelling schemas and running safe migrations
- hardening service behavior for retries, timeouts, and observability
- scaffolding or refactoring a backend with production defaults
Route Elsewhere
Workflow
- Confirm the real constraint: latency, team skill, runtime, compliance, data model, or delivery speed.
- Choose the transport and framework based on that constraint, not on trend-chasing.
- Define the boundary:
- request and response contracts
- auth and authorization rules
- error model
- idempotency and rate limiting
- Define the data path:
- schema and migrations
- transaction boundaries
- pooling and query budgets
- cache and invalidation rules
- Define the async path:
- queue semantics
- retry ownership
- deduplication and DLQ
- Add operability before calling it complete:
- timeouts and cancellation
- health checks
- structured logs and traces
- deploy and rollback expectations
ASCII Flow
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
Technology Selection
Pick based on the strongest operational constraint:
- TypeScript-heavy team -> Fastify, Hono, or NestJS plus Prisma or Drizzle
- audited SQL and predictable concurrency -> Go with
sqlc/pgx
- Python ecosystem or ML adjacency -> FastAPI plus SQLAlchemy
- enterprise .NET stack -> ASP.NET Core plus EF Core or explicit SQL access
- memory safety and explicitness -> Rust with Axum plus SQLx
- edge or serverless first -> lightweight stateless handlers with hard CPU and timeout budgets
Use software-baas-platforms first when the real requirement is "ship auth, storage, and realtime quickly with less custom service code."
Backend Non-Negotiables
| 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 |
Performance and Reliability Triage
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.
Operational Playbooks
- use references/operational-playbook.md for full service design and review checklists
- use qa-resilience when retries, deadlines, breakers, or degraded-mode behavior are the main question
- use dev-api-design when the contract itself is the main artifact
Production Readiness Checklist
Before marking a service production-ready:
Known Traps
- Introducing asynchronous jobs to hide a broken synchronous path instead of fixing the contract, timeout budget, or workload shape.
- Shipping retries without deadlines, jitter, and idempotency keys, then multiplying load during incidents.
- Changing API or webhook behavior without a compatibility window, replay plan, or structured error-versioning posture.
- Adding caches before proving whether the real bottleneck is query shape, pooling, lock contention, or outbound dependency latency.
- Treating background consumers as “fire and forget” even though poison-message handling, replay semantics, and observability are undefined.
Common Anti-Patterns
- Letting framework defaults define the service contract, error model, and cancellation semantics.
- Using one generic repository abstraction for every query, including hot paths that need explicit SQL, batching, or shape control.
- Mixing request handling, domain logic, external side effects, and persistence concerns in one controller or handler.
- Relying on eventual retries to clean up non-idempotent side effects.
- Calling a backend “production ready” before timeouts, readiness checks, trace correlation, and rollback smoke tests exist.
Navigation
Core references
- references/backend-best-practices.md
- references/edge-deployment-guide.md
- references/infrastructure-economics.md
- references/database-patterns.md
- references/message-queues-background-jobs.md
- references/rpc-and-transport-patterns.md
- references/go-best-practices.md
- references/rust-best-practices.md
- references/python-best-practices.md
- references/nodejs-best-practices.md
- references/csharp-best-practices.md
- data/sources.json
Shared review utilities
Templates
- assets/nodejs/template-nodejs-prisma-postgres.md
- assets/nodejs/template-nodejs-fastify-drizzle-postgres.md
- assets/go/template-go-fiber-gorm.md
- assets/go/template-go-chi-sqlc-pgx.md
- assets/rust/template-rust-axum-seaorm.md
- assets/rust/template-rust-axum-sqlx.md
- assets/python/template-python-fastapi-sqlalchemy.md
- assets/csharp/template-csharp-aspnet-efcore.md
Related Skills
Gate before invoking any foundation below: Each foundation has a When to Apply / When to Skip section. If your task matches a skip-condition, route to the foundation it names instead — don't pull in primitives the task doesn't need.
Fact-Checking
- Known bugs, regressions, framework/compiler/runtime footguns, and version-specific crash or workaround guidance must be verified against current primary web sources before being treated as current fact.
- Verify current runtime versions, support windows, framework capabilities, and cloud-platform constraints before final answers.
- Prefer official docs and release or support policy pages for version-sensitive recommendations.
- If web access is unavailable, mark version or support guidance as unverified.
Learnings Loop
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.
1---2name: software-backend3description: Builds backend services and APIs with durable defaults. Use when implementing REST, GraphQL, tRPC, or gRPC services with auth, queues, data, or observability.4---5
6# Software Backend Engineering
7
8Use 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.
9
10## Defaults
11
12When this skill is active, prefer these defaults unless the repo or user says otherwise:
13
14- validate at the boundary and keep types explicit
15- use PostgreSQL plus pooling for relational workloads
16- use structured logs, OpenTelemetry, explicit timeouts, and rate limits
17- make mutations idempotent and background work retry-safe
18- use RFC 9457 Problem Details for machine-readable errors
19
20## Quick Reference
21
22| Need | Default Direction |
23|------|-------------------|
24| Public HTTP API | REST with explicit contracts and timeouts |
25| Internal TS monorepo API | tRPC when end-to-end type safety matters |
26| High-throughput internal RPC | Connect or gRPC |
27| Complex client-shaped reads | GraphQL |
28| Relational data | PostgreSQL with migrations and pooling |
29| Background work | Queue plus idempotent handlers and DLQ policy |
30| Browser auth | OIDC or OAuth plus httpOnly cookies |
31| Service auth | short-lived tokens, workload identity, or signed service credentials |
32| Caching | explicit TTLs and invalidation rules |
33| Observability | correlation IDs, traces, structured logs, saturation metrics |
34
35## When to Use This Skill
36
37- building or reviewing REST, GraphQL, tRPC, Connect, or gRPC services
38- implementing auth, validation, rate limits, caching, queues, or webhook handling
39- modelling schemas and running safe migrations
40- hardening service behavior for retries, timeouts, and observability
41- scaffolding or refactoring a backend with production defaults
42
43## Route Elsewhere
44
45- frontend-only work -> [software-frontend](../software-frontend/SKILL.md)
46- infrastructure provisioning and cluster design -> [ops-devops-platform](../ops-devops-platform/SKILL.md)
47- API contract design without implementation -> [dev-api-design](../dev-api-design/SKILL.md)
48- BaaS platform selection (data/auth layer) -> [software-baas-platforms](../software-baas-platforms/SKILL.md)
49- PaaS hosting selection (compute layer: Vercel, Fly.io, Railway, Render, Cloudflare Workers, Deno Deploy) -> [software-paas-hosting](../software-paas-hosting/SKILL.md)
50- SQL tuning and indexing deep dives -> [data-sql-optimization](../data-sql-optimization/SKILL.md)
51- security reviews and threat modelling -> [software-security-appsec](../software-security-appsec/SKILL.md)
52- broader system architecture -> [software-architecture-design](../software-architecture-design/SKILL.md)
53
54---
55
56## Workflow
57
581. Confirm the real constraint: latency, team skill, runtime, compliance, data model, or delivery speed.
592. Choose the transport and framework based on that constraint, not on trend-chasing.
603. Define the boundary:
61 - request and response contracts
62 - auth and authorization rules
63 - error model
64 - idempotency and rate limiting
654. Define the data path:
66 - schema and migrations
67 - transaction boundaries
68 - pooling and query budgets
69 - cache and invalidation rules
705. Define the async path:
71 - queue semantics
72 - retry ownership
73 - deduplication and DLQ
746. Add operability before calling it complete:
75 - timeouts and cancellation
76 - health checks
77 - structured logs and traces
78 - deploy and rollback expectations
79
80---
81
82## ASCII Flow
83
84```text
85Backend task
86 -> Define endpoint, job, service, or data boundary
87 -> Confirm runtime, framework, persistence, and integration contracts
88 -> Design request validation, auth, errors, and idempotency
89 -> Implement bounded slice with tests and observability
90 -> Check performance, security, and rollout risk
91 -> Verify behavior and document follow-up handoffs
92```
93
94## Technology Selection
95
96Pick based on the strongest operational constraint:
97
98- TypeScript-heavy team -> Fastify, Hono, or NestJS plus Prisma or Drizzle
99- audited SQL and predictable concurrency -> Go with `sqlc/pgx`
100- Python ecosystem or ML adjacency -> FastAPI plus SQLAlchemy
101- enterprise .NET stack -> ASP.NET Core plus EF Core or explicit SQL access
102- memory safety and explicitness -> Rust with Axum plus SQLx
103- edge or serverless first -> lightweight stateless handlers with hard CPU and timeout budgets
104
105Use [software-baas-platforms](../software-baas-platforms/SKILL.md) first when the real requirement is "ship auth, storage, and realtime quickly with less custom service code."
106
107---
108
109## Backend Non-Negotiables
110
111| Category | Rule |
112|----------|------|
113| **API** | Mutating endpoints require idempotency keys where retries are plausible |
114| **API** | List endpoints require explicit pagination (`limit`/`cursor`) and at least one filter |
115| **API** | Errors are structured and machine-readable (RFC 9457 Problem Details) |
116| **API** | Health endpoints separate liveness (`/healthz`) from readiness (`/readyz`) |
117| **Data** | No `SELECT *` on wide or high-volume paths |
118| **Data** | Transactions kept explicit; no implicit ambient transactions |
119| **Data** | New or changed query plans verified with `EXPLAIN ANALYZE` before production |
120| **Data** | ORM convenience layers bypassed on hot paths where auditability matters |
121| **Dependencies** | Every outbound call has an explicit timeout; no framework-default infinite wait |
122| **Dependencies** | Retries owned at exactly one layer (no double-retry across client + service) |
123| **Dependencies** | Cache invalidation rule documented before caching is added |
124| **Dependencies** | Background jobs safe to retry and observable (structured log on start/finish/failure) |
125| **Operations** | Every request carries a correlation ID propagated to all downstream calls |
126| **Operations** | Trace, log, and metric identifiers agree (no split identity) |
127| **Operations** | Slow paths have explicit latency budgets (p99 target, not "fast enough") |
128| **Operations** | Deploy procedure includes rollback step and smoke-check list |
129
130---
131
132## Performance and Reliability Triage
133
134When a service is slow or unstable, debug in this order:
135
136| Step | Check | Signal |
137|------|-------|--------|
138| 1 | Query behavior and N+1s | EXPLAIN output, ORM query log showing repeated identical queries |
139| 2 | Indexes and execution plans | Seq scans on large tables, missing index on FK or filter columns |
140| 3 | Connection pooling and queue depth | Pool wait time > 10ms; idle connections exhausted |
141| 4 | Timeout and cancellation gaps | Requests hanging past deadline; no context propagation through outbound calls |
142| 5 | Caching or read-shaping opportunities | Same query with same result executing > 10x/s; hot read path with no invalidation |
143| 6 | Runtime or tier limits | CPU throttling, memory pressure, rate limit headers from upstream |
144
145Do not add caching before you understand the real bottleneck.
146
147---
148
149## Operational Playbooks
150
151- use [references/operational-playbook.md](references/operational-playbook.md) for full service design and review checklists
152- use [qa-resilience](../qa-resilience/SKILL.md) when retries, deadlines, breakers, or degraded-mode behavior are the main question
153- use [dev-api-design](../dev-api-design/SKILL.md) when the contract itself is the main artifact
154
155## Production Readiness Checklist
156
157Before marking a service production-ready:
158
159- [ ] All mutating endpoints have idempotency keys or safe-retry semantics
160- [ ] Every outbound call has an explicit timeout (no framework-default infinite waits)
161- [ ] Health endpoint distinguishes liveness from readiness
162- [ ] Correlation IDs propagated from inbound request to all downstream calls and logs
163- [ ] DLQ policy defined for every queue consumer (what happens to poison messages)
164- [ ] New query plans verified (`EXPLAIN ANALYZE`) before merge to main
165- [ ] Rollback procedure documented and smoke-test list exists
166
167## Known Traps
168
169- Introducing asynchronous jobs to hide a broken synchronous path instead of fixing the contract, timeout budget, or workload shape.
170- Shipping retries without deadlines, jitter, and idempotency keys, then multiplying load during incidents.
171- Changing API or webhook behavior without a compatibility window, replay plan, or structured error-versioning posture.
172- Adding caches before proving whether the real bottleneck is query shape, pooling, lock contention, or outbound dependency latency.
173- Treating background consumers as “fire and forget” even though poison-message handling, replay semantics, and observability are undefined.
174
175## Common Anti-Patterns
176
177- Letting framework defaults define the service contract, error model, and cancellation semantics.
178- Using one generic repository abstraction for every query, including hot paths that need explicit SQL, batching, or shape control.
179- Mixing request handling, domain logic, external side effects, and persistence concerns in one controller or handler.
180- Relying on eventual retries to clean up non-idempotent side effects.
181- Calling a backend “production ready” before timeouts, readiness checks, trace correlation, and rollback smoke tests exist.
182
183## Navigation
184
185### Core references
186
187- [references/backend-best-practices.md](references/backend-best-practices.md)
188- [references/edge-deployment-guide.md](references/edge-deployment-guide.md)
189- [references/infrastructure-economics.md](references/infrastructure-economics.md)
190- [references/database-patterns.md](references/database-patterns.md)
191- [references/message-queues-background-jobs.md](references/message-queues-background-jobs.md)
192- [references/rpc-and-transport-patterns.md](references/rpc-and-transport-patterns.md)
193- [references/go-best-practices.md](references/go-best-practices.md)
194- [references/rust-best-practices.md](references/rust-best-practices.md)
195- [references/python-best-practices.md](references/python-best-practices.md)
196- [references/nodejs-best-practices.md](references/nodejs-best-practices.md)
197- [references/csharp-best-practices.md](references/csharp-best-practices.md)
198- [data/sources.json](data/sources.json)
199
200### Shared review utilities
201
202- [../software-clean-code-standard/assets/checklists/backend-api-review-checklist.md](../software-clean-code-standard/assets/checklists/backend-api-review-checklist.md)
203- [../software-clean-code-standard/assets/checklists/secure-code-review-checklist.md](../software-clean-code-standard/assets/checklists/secure-code-review-checklist.md)
204- [../software-clean-code-standard/references/auth-utilities.md](../software-clean-code-standard/references/auth-utilities.md)
205- [../software-clean-code-standard/references/error-handling.md](../software-clean-code-standard/references/error-handling.md)
206- [../software-clean-code-standard/references/config-validation.md](../software-clean-code-standard/references/config-validation.md)
207- [../software-clean-code-standard/references/resilience-utilities.md](../software-clean-code-standard/references/resilience-utilities.md)
208- [../software-clean-code-standard/references/logging-utilities.md](../software-clean-code-standard/references/logging-utilities.md)
209- [../software-clean-code-standard/references/testing-utilities.md](../software-clean-code-standard/references/testing-utilities.md)
210- [../software-clean-code-standard/references/observability-utilities.md](../software-clean-code-standard/references/observability-utilities.md)
211
212### Templates
213
214- [assets/nodejs/template-nodejs-prisma-postgres.md](assets/nodejs/template-nodejs-prisma-postgres.md)
215- [assets/nodejs/template-nodejs-fastify-drizzle-postgres.md](assets/nodejs/template-nodejs-fastify-drizzle-postgres.md)
216- [assets/go/template-go-fiber-gorm.md](assets/go/template-go-fiber-gorm.md)
217- [assets/go/template-go-chi-sqlc-pgx.md](assets/go/template-go-chi-sqlc-pgx.md)
218- [assets/rust/template-rust-axum-seaorm.md](assets/rust/template-rust-axum-seaorm.md)
219- [assets/rust/template-rust-axum-sqlx.md](assets/rust/template-rust-axum-sqlx.md)
220- [assets/python/template-python-fastapi-sqlalchemy.md](assets/python/template-python-fastapi-sqlalchemy.md)
221- [assets/csharp/template-csharp-aspnet-efcore.md](assets/csharp/template-csharp-aspnet-efcore.md)
222
223## Related Skills
224
225> **Gate before invoking any foundation below:** Each foundation has a `When to Apply` / `When to Skip` section. If your task matches a skip-condition, route to the foundation it names instead — don't pull in primitives the task doesn't need.
226
227- [software-architecture-design](../software-architecture-design/SKILL.md)
228- [software-security-appsec](../software-security-appsec/SKILL.md)
229- [ops-devops-platform](../ops-devops-platform/SKILL.md)
230- [qa-resilience](../qa-resilience/SKILL.md)
231- [qa-testing-strategy](../qa-testing-strategy/SKILL.md)
232- [foundations-queueing-theory](../foundations-queueing-theory/SKILL.md) — Little's Law, M/M/c, and Kingman's formula for queue sizing in message-queue and rate-limiter design
233- [foundations-distributed-systems](../foundations-distributed-systems/SKILL.md) — CAP, consistency models, quorum sizing, and idempotency contracts for service mesh and RPC patterns
234- [foundations-reliability-theory](../foundations-reliability-theory/SKILL.md) — MTBF/MTTR, availability composition, and error-budget math for SLO-driven backend design
235- [software-code-review](../software-code-review/SKILL.md)
236- [dev-api-design](../dev-api-design/SKILL.md)
237- [data-sql-optimization](../data-sql-optimization/SKILL.md)
238
239## Fact-Checking
240
241- Known bugs, regressions, framework/compiler/runtime footguns, and version-specific crash or workaround guidance must be verified against current primary web sources before being treated as current fact.
242- Verify current runtime versions, support windows, framework capabilities, and cloud-platform constraints before final answers.
243- Prefer official docs and release or support policy pages for version-sensitive recommendations.
244- If web access is unavailable, mark version or support guidance as unverified.
245
246## Learnings Loop
247
248Before applying this skill on a non-trivial task, read `learnings.consolidated.md` in this directory (and `learnings.md` if present).
249
250After 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.
251