Performance Tuning
Get the best performance from your servers and apps with these optimization tips. Small changes can make a big difference in speed, reliability, and cost.
Performance tuning isn't about making one big change — it's about applying best practices at every layer of your stack. This guide covers optimizations for your server, applications, databases, and network, along with how to monitor everything to catch issues early.
Server Optimization
The foundation of good performance is choosing the right server and keeping it healthy. Here are the key practices for server-level optimization:
Choose the Right Server Size
Match your server size to your workload. A Starter server (2 vCPU, 4 GB RAM) handles 3-5 lightweight apps comfortably. If you're running databases or heavy workloads, consider Standard or Performance tiers. Over-provisioning wastes credits, but under-provisioning causes slow response times.
Monitor Resource Usage Regularly
Check your server's CPU, memory, and disk usage at least weekly via the Portainer dashboard. Establish a baseline so you can spot anomalies quickly. Sudden spikes often indicate a memory leak, runaway process, or traffic surge.
Use Hetzner for Best Price-to-Performance
Hetzner consistently offers the best value among Dublyo's supported providers. Their servers use modern AMD EPYC processors and NVMe SSDs, delivering excellent performance at a fraction of the cost of comparable offerings from other providers.
| Server Size | Recommended For | Max Concurrent Users |
|---|---|---|
| Starter | Personal projects, low-traffic sites | ~100-500 |
| Standard | Production apps, moderate traffic | ~500-2,000 |
| Performance | High-traffic apps, databases, AI tools | ~2,000-10,000 |
App Optimization
How you configure and deploy your applications has a significant impact on performance. These practices help keep your apps fast and resource-efficient:
Keep Images Small
Use Alpine-based Docker images whenever possible. Alpine images are typically 5-10x smaller than their Debian or Ubuntu counterparts, which means faster pulls, less disk usage, and lower memory footprint. Most Dublyo templates already use optimized images.
Set Appropriate Resource Limits
Configure memory and CPU limits for your containers via Portainer. This prevents a single app from consuming all server resources and affecting other applications. A good starting point is limiting each app to 25-50% of available RAM.
Use Environment Variables for Configuration
Store configuration values (API keys, feature flags, settings) as environment variables rather than hardcoding them. This lets you change settings without rebuilding or redeploying the container — just restart it to pick up the new values.
Image Size Comparison
| Base Image | Typical Size | RAM Usage |
|---|---|---|
| Alpine | 5-30 MB | Low |
| Debian Slim | 50-80 MB | Medium |
| Ubuntu | 70-150 MB | Higher |
.dockerignore file to exclude unnecessary files (node_modules, .git, test files) from your Docker build context. This speeds up builds significantly. Database Performance
Databases are often the biggest performance bottleneck. These optimizations can dramatically improve response times and reduce resource usage:
Use Connection Pooling
Connection pooling reuses database connections instead of creating new ones for each request. This reduces overhead and improves response times, especially under load. Tools like PgBouncer work great with PostgreSQL deployments on Dublyo.
Index Frequently Queried Columns
Missing indexes are the most common cause of slow database queries. Add indexes to columns used in WHERE clauses, JOIN conditions, and ORDER BY statements. A single index can turn a 5-second query into a 5-millisecond one.
Regular VACUUM for PostgreSQL
PostgreSQL accumulates dead rows over time from updates and deletes. Running VACUUM ANALYZE regularly reclaims disk space and updates query planner statistics. Autovacuum handles this automatically, but heavy workloads may need manual tuning.
Consider a Separate Server for Heavy Databases
If your database handles heavy read/write workloads, consider running it on a dedicated server. This prevents database I/O from competing with your application containers and gives you more control over resource allocation.
-- Check for missing indexes on frequently queried tables
SELECT schemaname, tablename, seq_scan, idx_scan
FROM pg_stat_user_tables
WHERE seq_scan > idx_scan
ORDER BY seq_scan DESC;Network & CDN
Network optimization reduces latency and protects your apps from attacks. These changes are easy to implement and make a noticeable difference for your users:
Use Cloudflare for CDN and DDoS Protection
Point your custom domains through Cloudflare (free tier works great) to get automatic CDN caching, DDoS protection, and global edge delivery. Static assets like images, CSS, and JavaScript get served from Cloudflare's nearest edge node, dramatically reducing load times for users far from your server.
Enable Gzip Compression
Traefik, which comes pre-installed on every Dublyo server, handles gzip compression automatically. This compresses text-based responses (HTML, CSS, JavaScript, JSON) by 60-80%, reducing bandwidth usage and improving load times. No configuration needed.
Keep Servers Close to Your Users
Physical distance affects latency. Choose a server region close to where most of your users are located. A server in Nuremberg serves European users with ~20ms latency, while the same request from the US would take ~100ms. For global audiences, use Cloudflare CDN to bridge the gap.
| Optimization | Impact | Effort |
|---|---|---|
| Cloudflare CDN | 30-60% faster static asset loading | Low (DNS change only) |
| Gzip Compression | 60-80% smaller text responses | None (automatic via Traefik) |
| Region Selection | 50-200ms latency reduction | Low (choose at server creation) |
Monitoring
Ongoing monitoring is essential for maintaining performance over time. Without visibility into your system, you won't catch problems until your users complain. Here's how to stay on top of things:
Check Resource Usage via Portainer Dashboard
Portainer provides a real-time view of CPU, memory, and network usage for every container on your server. Make it a habit to check the dashboard at least once a week. Look for containers using more resources than expected — this often indicates a memory leak or inefficient configuration.
Set Up Alerts for High CPU/Memory
Don't wait for problems to find you. Use monitoring tools like Uptime Kuma (available as a Dublyo template) to set up alerts when CPU or memory usage exceeds safe thresholds. A good rule of thumb: alert at 80% CPU and 85% memory so you have time to react.
Watch Deployment Logs for Warnings
Container logs often contain performance warnings before they become visible problems. Check logs via Portainer after each deployment and periodically during normal operation. Look for slow query warnings, memory allocation errors, and connection timeouts.
Key Metrics to Watch
| Metric | Healthy Range | Action If Exceeded |
|---|---|---|
| CPU Usage | Below 70% average | Identify heavy containers, consider upgrading server |
| Memory Usage | Below 80% total | Set container limits, stop unused apps, upgrade server |
| Disk Usage | Below 75% capacity | Clean up old images, prune unused volumes |
| Response Time | Under 500ms for most requests | Check database queries, add caching, optimize code |
Need Help?
Can't find what you're looking for? Check the full documentation or reach out.