Performance Optimization
Temps gives you direct access to the server, so you can tune at every layer — build, runtime, database, and network. This page covers the highest-impact levers.
Build Optimization
Slow builds extend your deploy time. The fastest wins:
Use multi-stage Docker builds to avoid shipping dev dependencies and build tools in the final image. A Next.js app goes from ~1.5 GB to ~150 MB — see Custom Buildpacks for the pattern.
Structure Dockerfiles to maximize layer caching — copy dependency manifests before source files so npm install is only re-run when dependencies change.
Enable TypeScript transpileOnly in ts-node or esbuild for faster compilation when type-checking runs separately in CI.
Caching
HTTP response caching
Set Cache-Control headers on static assets and immutable routes:
// Next.js route handler
return new Response(data, {
headers: {
'Cache-Control': 'public, max-age=31536000, immutable',
},
});
For dynamic routes that can tolerate brief staleness:
Cache-Control: public, s-maxage=60, stale-while-revalidate=300
Redis caching
Cache expensive database queries or external API responses in Redis:
const cached = await redis.get(`user:${id}`);
if (cached) return JSON.parse(cached);
const user = await db.query('SELECT * FROM users WHERE id = $1', [id]);
await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 300);
return user;
Cache TTLs should reflect how stale the data can safely be, not an arbitrary large number.
CDN Integration
Temps serves all traffic directly from your VPS. For global audiences, put a CDN in front:
Cloudflare (recommended) — point your domain's nameservers to Cloudflare, enable proxying (orange cloud), and Cloudflare caches static assets at edge locations worldwide. No config changes to your app needed.
Cache rules to set in Cloudflare:
- Static assets (
/_next/static/*,/images/*,/fonts/*) — Cache Everything, Edge TTL 1 year - HTML pages — Respect Existing Headers (lets your
Cache-Controlheaders govern) - API routes (
/api/*) — Bypass Cache
Resource Tuning
CPU and memory
Under-resourced containers cause slowdowns that look like application bugs. Monitor under Project → Metrics and look for:
- CPU throttling — sustained >80% CPU means you need more cores
- OOM restarts — container killed and restarted means it needs more memory
Adjust under Project → Settings → Resources.
Connection pooling
Databases accept a limited number of concurrent connections. Without pooling, each server process opens its own connection and you hit the limit quickly.
For Node.js with PostgreSQL:
import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 10 });
For Python, use SQLAlchemy's built-in pool or PgBouncer as a sidecar.
Database Profiling
Slow queries are the most common source of backend latency. Enable query logging in PostgreSQL:
ALTER SYSTEM SET log_min_duration_statement = 100;
SELECT pg_reload_conf();
View the slowest queries:
psql "postgresql://postgres:yourpassword@localhost:16432/yourdb" \
-c "SELECT query, mean_exec_time, calls FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 20;"
The most common fixes:
- Add an index on columns used in
WHERE,JOIN ON, orORDER BY - Avoid
SELECT *— fetch only the columns you need - Use
EXPLAIN ANALYZEto understand the query plan
Monitoring Performance
Temps built-in monitoring tracks response time (p50, p95, p99), error rate, and uptime. Set an alert threshold under Monitoring → Alerts so you're notified before users notice a regression.