Posts

Showing posts from 2023

My second book is out: Principles of Software Architecture Modernization

Image
After 1+ year of hard work, my second book is finally out. Introducing: Principles of Software Architecture Modernization: Delivering Engineering Excellence with the art of fixing microservices, monoliths, and distributed monoliths. I've 20+ years of experience with technology and have been an architect and a technology consultant for most of this time, software architecture is a deep passion of mine. It is a huge pride and joy, for me to come here today to share this with you, my friends, and dear readers. 🎉🎉🎉 I deeply appreciate all the blessings God has given me, from my family, my daughter Clara, my wife Andressa, my work, and my friends. It was not easy to write this book 📘, there was sweat, blood, and tears, lots of remote work with my co-author Sam . Rest assured you are getting my passion, vision, and perspective of software architecture. First and foremost the book is about principles, tradeoffs, and software architecture design at the heart of complexity. The book is

Continuous Refactoring

Image
Software is very interesting, it's amazing how little things make a huge difference, being able to see all the small intricacies and how the pieces fit together is a complex and fascinating task. The more we understand, the more we learn effectively, better we can do it. Software complexity does not reduce, it only grows, working with a relentless mindset of continuous improvement is the only way to go forward. Refactoring is often seen as a "bad word" a big spooky thing because everybody believes is busy, so why are you risking breaking a lot of things if you can move forward and "live" with the problems. XP (Extreme Programming) got this right from the get-go, you need the principles and values. XP has a value called: courage; courage to do refactoring, especially when the conditions are not in your favor, considering monoliths and distributed monoliths the odds are never in your favor. Once you start doing so, slowly put all guardrails in place, would such c

The Death of CI/CD

Image
XP (Extreme Programming) leaders popularized CI (Continous Integration) in the late 90s. The idea was very simple, to continuously integrate code in a common branch usually called trunk, nowadays we call it main. The principles behind CI were (A) Reduce feedback cycles (B) Increase response time and release software faster. CI it's a powerful concept, that requires automation of the build process and of course, automated tests. In order to do CI you also an SCM (Source Code Management system), in the past there were various solutions like CVS (not a drugstore), SVN, and GIT rules today. By definition CI also requires continuous merging, which leads to interesting realizations like, how often should we merge, the answer is as much as possible, as frequent as possible. Today's environments are more complicated than they were in the 90s, back in that time, the CI process was generating one single binary. 

Principles for Code Reviews and Reviewers

Image
Last month I was blogging about how code review is dead . Today I want to share some principles and practices to make things better. In the previous post I shared some actions, now let's understand the principles behind many of these actions.  First of all, can we save code reviews, and make them better, for sure we can. It's not that hard, for the code review it self-improve we need a couple of things in place. Usually, engineers have the same complaints like It takes a long time to do code reviews, there are too many files, I don't know this code or this service, etc... The fact is there are multiple mindset problems here. 

The Death of Code Review

Image
How we work matters, a lot. Unfortunately, very often engineers and managers don't care about engineering working practices, which is a big mistake. How we work is the key to heaven or the highway to hell. Code review is a pretty default practice, it's everywhere, companies do code review, at least that is what they claim. But how good is the code review? How many times do you need to be chasing engineers to beg them to merge your code? How many times are you actually getting useful feedback or bugs are being caught? Very often engineers don't prioritize code review, which means that quality is not being prioritized. Quality, to some degree, needs to be prioritized and to some degree enforced. There are many forces that make code reviews skipped and not performed with the due diligence that they need such as unrealistic release pressure, lack of critical talent density, poor engineering culture, low standards, and many other factors. Some languages have stronger type system

Tagging Everything

Image
I was always a big believer in metadata and observability. Tagging is another form of observability, the idea is very basic and yet not well explored in our industry. You add metadata to a resource. Metadata is just data that describes data. Why bother? Well, at scale, there will be hundreds to thousands of resources including ec2 machines, container images, security groups, load balancers, and all kinds of applications like services, bffs, aggregators, a much more. How do you make sense of these resources? How do you know if you need them after all? Cloud computing is great but also is a big cost center. Understanding your resources is critical, not only for savings but for better infrastructure management. Tags help with cost, but they go beyond cost.  Endless Resources So let's say you have some scale, easily you can have hundreds to thousands of ec2 and dozens to hundreds of lamdas. The first question that should come to mind is ownership, how own all these resources? By not ha

Design Patterns

Image
Once upon a time, Design Patterns was a big thing. In current times, perceptions have shifted and the industry has mixed feelings about them. I've thought a lot of blogging about design patterns was worth it or not. I used a lot of patterns in my life, there were moments when I was completely okay with design patterns, and other times not so okay. I got some mixed feelings but today I think they are fine. IMHO there are some fairness and some misconceptions. There are hundreds of Design Patterns, there are patterns for everything you can imagine. Usually when people complain about patterns they are talking about OOP patterns, more specifically from the 90s book from the GOF .   Patterns are not limited to OO, there are functional programming patterns, system programming patterns, OS patterns, cloud computing patterns, frontend patterns, and mobile patterns. Lots of these patterns are very similar, at the end of the day not all problems are that different, and are all about ideas an

Shallow vs Deep Mindset

Image
Every single activity we do in engineering is an opportunity. We need to see this way, with positivity, and do more than we are asked to. That's how we improve. PRO players from football, basketball, or any pro sports, practice like there is no tomorrow. Practice or training is one dimension, and another dimension is vision, we need to be able to see things differently. For instance, we live in an attention economy , the issue with such an economy is that is shallow, so we live in a shallow attention economy. We need to start seeing the opportunities and encouraging a deep mindset instead of a shallow mindset. A shallow mindset is okay as a starting point, but quickly we need to switch to a deep mindset. It's all about vision because we can execute the very same task with completely different takes: Shallow vs Deep Mindsets. 

Embedded Mocks and Hidden Contracts

Image
Testing is essential . Testing requires diversity, from integration to chaos , from your local machine to production . Writing tests not always is fun because sometimes is hard to write tests because not all contracts are good, and clean and went through a lot of thought processes. Is easy to blame the design, architecture, and even the implementation, but are we sure we are not missing anything? Something that is hard to test very likely will not be tested. Testability is a good property of any design or architecture sure. Making good solutions that are easy to test is a good thing. However, mocking is often taken for granted, meaning is seen as something that is just good and has no drawbacks, but that is not true. Everything has drawbacks. Integration tests are often seen as bad practices and people tend to lean toward unit tests instead. Just keep in mind Integration tests don't require mocks. Unit tests often require mocks to keep them isolated and cut off external dependencie

Fighting Complexity

Image
Complexity is everywhere. Small, medium, or big company, does not matter, no one can escape complexity. Complexity just tends to get bigger, we depend on software more and more. Ask yourself, if your subscriptions on iPhone are increasing or decreasing in the last 5 years. There is more competition, and more streaming providers, and everything becomes a subscription, from grocery to transportation to even video games. Complexity increases, maintainability decreases, and maintaining software becomes harder. More software, more complexity. Complexity needs to be fought 24x7 at all times. However, how can we figure out something if we don't fully understand it? Is easy to just give up and do whatever since there is no escape, but there is a better way, we can do better. So what is complexity after all?

Tokenization, Encryption and Compensation Controls

Image
Security Matters. How do you know you are secure? One of the many practices is to run Threat Analysis considering attacking vectors.  Threat Modeling should be a continuous activity. Movements like DevSecOps aim to put security on the day-to-day work. Cybersecurity Ventures predicts costs will grow 15% per year over the next five years reaching 10.5 Trillion USD by 2025. Security is a never-ending game. Security is something companies will need to do forever. IF they cost more and more, maybe we should get better and learn more about security. Lack of security can destroy a brand, and damage the customer's trust and relationship with your solutions. Security is difficult because it cannot be fixed in a central place with one tool, it requires principles and continuous fighting. There are infinite amounts of attack vectors. Common attacking vectors include compromised credentials: users/passwords, weak credentials: low entropy passwords, Insider Threats: from bad actors,  Misconf

Tradeoffs

Image
Tradeoffs are key for design and architecture. Being able to run proper tradeoffs is an important skill you should master. Decisions we make in software should happen based on tradeoff analysis. Tradeoffs are about pros and cons, which can be done with a simple list of pros and cons. However it looks simple and easy, it is way harder than it looks. Running proper tradeoffs requires knolowsge of the domain, creativity, and lots of debate club skills. Tradeoffs are about trading one thing for another like speed vs. flexibility. Tradeoffs are about balancing factors that might not be attainable at the same time like consistency and availability. Without good tradeoffs skills, we can make wrong decisions and be fooling ourselves. Tradeoffs do not require fancy tools, we can do it with pen and paper, or any plaintext editor like vim. Before we do a deep dive into tradeoffs let's understand why they matter a lot. Why do Tradeoffs Matter? Tradeoffs matter for a variety of reasons: Better

The Specification Pattern

Image
Business domains can be very different due to the different natures of each business. Some domains are more static and allow us to easily understand them and produce an efficient core model. However, some business domains are very dynamic, and it is difficult to get the gist and essence of the domain. Some problems require the code to change all the time. The first thing that comes to mind is to externalize business rules either in the form of configuration or in the form of database tables. Externalization to configs and databases works well when the business rules are simple, however, when the business rules are complex, such externalization is more complex and tends to generate more complexity. Nothing is better than code to express complex ideas. Good domain modeling via proper OO design is a very powerful way to map and describe domains.

GraphQL: Highway for a Distributed Monolith?

Image
GraphQL makes a lot of sense for mobile applications. Especially when we consider poor networks. Aggregating data in one call is very powerful and makes a lot of sense for mobile. GraphQL allows a single interface for all operations for reads and writes. GraphQL is not that different from an API gateway or aggregation service. Selecting only the fields you need allows you to reduce the payload of requests, and latency resulting in improvements in the user experience via the mobile app. GraphQL has a lot of power and flexibility, which requires lots of attention to detail as well. Understanding the tradeoffs is important, one thing you are giving away by using only GraphQL is the ability to make multiple service calls in an asynchronous fashion, GraphQL is synchronous. GraphQL performance will have penalties . GraphQL never will be as fast as a modular monolith doing proper queries in the database. We can mitigate some performance issues by doing pre-loading, batching, or just caching

S3: The Next Distributed Monolith?

Image
S3 is an object storage that scales within reasonable performance. S3 can be used for a variety of use cases like Big Data analytical workloads, data pipelines, and AI/ML pipelines. S3 is big in the data universe but is also used in services and microservices for a variety of other use cases like file sharing, document management, legal signatures, and many other use cases. S3 is not a relational database, however, from the isolation point of view , S3 should be seen in the same way we see data stores . Since 2020, S3 guarantee strong consistency Read-After-Write. S3 performance handle reads up to 5500 rps and 3500 rps for write. S3 is easy to use and reliable, now everything that is popular and useful can be misused. 

Distributed Monolith

Image
Distributed Monoliths are the worst. Nothing good comes from distributed monoliths. No one wants to have distributed monoliths, and still, they are very common in the industry. Complexity just gets bigger, our industry just gets more and more entangled. Complexity has everything to do with distributed monoliths. Distributed Monoliths are very complex, much more than monoliths. How can you avoid a trap? By definition, the only way is not to follow into the trap. Understanding the trap is how you can avoid it. However, some traps cannot be avoided because there are bigger forces like acquisitions, pandemics, economic downturns, wars, or time. Time can easily be the biggest trap of all. We need to learn how to work effectively with monoliths and distributed monoliths because they are to stay and we can't ignore them. Fishing monoliths is a long-turn battle, that requires persistence, patience, and allies. Let's start by understanding monoliths and Distributed Monoliths a bit more.

Languages over Libraries

Image
Internal shared Libraries are a trap . Sorry, not one trap, multiple traps because often there are multiple internal shared libraries. Engineers often take libraries for granted and fail to see the hidden costs in libraries. Libraries should be designed carefully . Libraries provide functionality, code reuse and allow us to be productive to some degree. I’m not against the usage of libraries. However, we need to understand that libraries have issues and hidden problems. For instance, productivity cannot be measured only on how fast you get things done in the sense of days, number of user stories, or releases. Several side effects need to be taken into account such as: Bugs: How many bugs did you produce by direct or indirect usage of a library. Incidents: If the bug creates a major incident, how much money did you lose, and how much your customers got affected? Any brand damage or loss of trust of your users? Debugging & Troubleshooting: How many hours, do teams spend debugging