← Back to Writing

Trade-offs I Learned the Hard Way

September 2025

Every architectural decision is a trade-off.

Consistency vs. Availability

In a financial audit system, I chose strong consistency over availability. Transactions had to be accurate, even if it meant slower responses during network partitions.

Trade-off: Users occasionally saw slower responses, but we never had data inconsistencies.

Lesson: Know your domain. In finance, correctness beats speed. In social media, availability beats consistency.

Microservices vs. Monolith

We migrated from a monolith to microservices to improve deployment velocity. It worked, but it also introduced complexity: distributed tracing, service discovery, and inter-service communication.

Trade-off: Faster deployments, but higher operational overhead.

Lesson: Microservices are not free. Only adopt them if you have the team and tooling to support them.

Normalization vs. Denormalization

We denormalized data to improve read performance. Queries became faster, but updates became more complex because we had to update multiple tables.

Trade-off: Faster reads, slower writes, and more storage.

Lesson: Optimize for your read/write ratio. If you read 100x more than you write, denormalization makes sense.

Build vs. Buy

We built a custom authentication system instead of using an existing solution. It gave us full control, but it also took months to build and required ongoing maintenance.

Trade-off: Full control, but high development and maintenance costs.

Lesson: Do not build what you can buy, unless it is core to your business.

Conclusion

There are no perfect solutions, only trade-offs. The key is to understand what you are optimizing for and accept the costs. Document your decisions so future engineers (including future you) understand why.