2.3.3 Trade-Offs
Trade-offs in IT: "Pick two" and performance optimization
The image illustrates the classic principle "Good, Fast, Cheap — choose two", adapted for IT projects:
- High performance (High-Performance)
- Deadlines (On-Time)
- Budget (Inexpensive)
They usually choose "On-Time+ Inexpensive", sacrificing performance, which leads to problems:
- Suboptimal storage architecture.
- Inefficient programming languages.
- Lack of tools for performance analysis.
1. Key trade-offs in IT
(1) CPU vs Memory
- In-memory caching → reduces CPU load, but requires more RAM.
- Data compression → saves memory, but increases CPU load.
Example:
- Redis (in-memory cache) vs PostgreSQL (page compression).
(2) File System block Size
Small block (4 KB) | Large block(64 KB) |
---|---|
Better for random I/O operations | Better for streaming reads/writes |
Uses cache more efficiently | Speeds up backups |
(3) Network Buffer size
Small buffer | Large buffer |
---|---|
Less memory load | Higher bandwidth |
2. Where is it more efficient to adjust performance?
The closer the setting is to the application level, the greater the effect.:
Level | Examples of optimizations | Potential gain |
---|---|---|
Application | Optimization of SQL queries and logic | Up to 20x |
Database | Indexes, partitioning | Up to 5x |
File system | Configuring the cache, block size | Up to 2x |
Storage | RAID, SSD vs HDD | Up to 1.5x |
** Why?**
An application-level fix eliminates work at all lower levels of the stack.
3. Problems of modern approaches
-
The race for functionality:
- Developers focus on correctness, not performance.
- Performance problems are detected already in production.
Cloud environments:
-
Frequent updates (weekly/daily) complicate long-term monitoring.
- It is important to monitor the OS, even if the problem is in the application.
4. Practical advice
(1) For developers
-
Profile the code before release (for example,
perf
for Linux,VTune
for Intel). - Avoid N+1 queries in databases.
- Cache hot data (Redis, Memcached).
(2) For admins
- Set up OS monitoring (Prometheus + Grafana for CPU/RAM/I/O metrics).
-
Optimize block sizes for load (for example,
ext4
withbs=64k
for DBMS). - Use modern storage (NVMe for high-load systems).
Conclusion
- Sacrifice one of the three: speed, quality, or cost.
- Optimize at the application level — this gives maximum effect.
- Monitor the OS, even if the problem seems to be "applied".
"Late optimization is the root of all evil. But even worse is blind optimization without measurements."
— Adaptation of a quote by Donald Knuth
Optimizing block size for PostgreSQL: how to choose and why?
The size of a block (page) in PostgreSQL critically affects performance. Let's figure out how to choose it correctly for your workload.
1. What is a "block" in PostgreSQL?
- Standard size: 8 KB (can be changed from 1 to 32 KB during compilation).
- One page = 1 block = minimum unit of I/O operations.
- Stores: table rows, indexes, metadata.
2. How does block size affect performance?
Small block (4 KB) | Large block (16-32 KB) |
---|---|
✅ Better for OLTP (lots of random reads/writes of short strings) | ✅ Better for analytical queries (scanning large ranges) |
❌ Accesses disk more often (less data per 1 I/O) | ❌ Spends memory on empty areas if the rows are small |
Example:
If you have a chat app (lots of inserts/updates of short messages) — 8 KB optimal.
For Data Warehouse (large table analytics) — 16-32 KB will speed up `SELECT * FROM large_table'.
3. How can I check my current performance?
Diagnostic requests:
`sql
-- Average row size in the table
SELECT avg(pg_column_size(t.*)) FROM my_table t;
-- How many blocks are "empty" (low occupancy)
SELECT relname, 100 - (pg_relation_size(oid) / (8192 * relpages) * 100) AS "empty_space_%"
FROM pg_class WHERE relkind = 'r';
`
If `empty_space_%' is > 30%, it may be worth reducing the block size.
4. How can I change the block size?
-
Only when compiling PostgreSQL (setting
--with-blocksize=16
in./configure
). - Cannot be changed for an existing database — only create a new cluster with a different size:
initdb -D /path/to/new/data --block-size=16384
-
Data transfer: Use
pg_dump
/`pg_restore'.
5. Optimal values for different scenarios
Load type | Recommended unit | Arguments |
---|---|---|
OLTP (short transactions) | 8 KB | Minimizing overhead |
Analytics (large scans) | 16-32 KB | Reducing the number of I/O operations |
Mixed load | 8 KB | Read/Write balance |
6. What else affects I/O efficiency?
- TOAST: PostgreSQL automatically compresses/separates large fields (> 2 KB).
-
Fillfactor: Setting the page occupancy (for example,
90
for frequently updated tables). -
File system: 'XFS
or
ZFSwith the setting
bs=16k` to match PostgreSQL.
Conclusion
- 8 KB is a safe choice for most cases.
- 16+ KB — only for post-test analytics.
- Before changing: Measure the current efficiency via 'pg_stat_io'.
Tip: For cloud databases (RDS, Cloud SQL), the block size is fixed — choose instances with preset values for your load.
The level of depth of performance analysis: when to stop?
Productivity is a balance between analysis costs and potential benefits. Let's look at how to determine the optimal level of effort for your project.
1. "Adequate level" of analysis: from startups to HFT
Organizations have different approaches to performance analysis depending on ROI (return on investment):
Company type | The level of analysis | Examples |
---|---|---|
Startups | Surface monitoring (CloudWatch, Sentry) | Checking API latency and alerts |
Corporations | Deep analysis (perf, eBPF, CPU PMC) | Linux kernel optimization, simulation |
HFT / Exchanges | Extreme optimization (nanoseconds) | Laying cables for $300 million to save 6 ms |
Key principle: > "Adequate level" is when ** the cost of the analysis is less than the potential benefit**.
2. When should I stop the analysis?
Scenarios for stopping:
- ** The main reason is explained**
-
Example: A Java application eats CPU. We found exceptions that explain 12% of the load. But since slowdown 3x, we're looking further.
- Rule: We stop if we find >66% problems.
ROI is less than the cost of analysis
-
Optimization of a microservice that saves $100/year is not worth 10 hours of an engineer's work.
- Exception: If the problem is a "canary" for future disasters (for example, memory leak).
-
There are more important tasks
- Even if the problem is not completely clear, there are critical bugs elsewhere.
3. Recommendations "at a given time"
Performance settings ** become obsolete** after:
- Hardware upgrades (for example, switching from 10 Gbit/s to 100 Gbit/s).
- Software updates (the new version of PostgreSQL may change the optimal `shared_buffers').
- Growth in the number of users.
How to avoid mistakes:
-
Do not copy tunings from the Internet blindly. Example:
nginx # Old recommendation for Linux 2.6: net.ipv4.tcp_tw_reuse = 1 # May be harmful in modern kernels!
-
Version the settings (Git + annotations like: "Increased
vm.swappiness=10
due to swap load in 2023-01").
4. Practical rules
For startups
- Minimum: Latency/error monitoring (New Relic, Datadog).
- Optimum: Once a quarter — deep check of slow queries and caching.
For corporations
- Permanent team of performance engineers.
- Tools:
-
perf
/`eBPF' — for core analysis.- Load forecasting (for example, via ML).
For HFT/Exchanges
- Hard SLA: Every microsecond is money.
- Investments: Custom network stacks, FPGA instead of CPU.
5. Checklist "Where to stay?"
- Have you found the cause of >50% of the problem? → Stop, we're fixing.
- Do the remaining hypotheses take a disproportionate amount of time? → Postpone.
- Are there more important tasks with high ROI? → Switch to.
Metric: If the analysis takes longer than the potential savings, you have overdone it.
Conclusion
- The depth of the analysis depends on budget and risks.
- Tuning is outdated — document the changes.
- 80/20 rule: 20% of efforts give 80% of the result.
Case study:
After updating the AWS instance from m5.large
to m6i.xlarge', the old
kernel.schedul_migration_cost_ns` settings began to slow down the application. Solution: reset the parameters to default + measurements under load.
Top comments (0)