r/softwarearchitecture • • Sep 14 '25

Article/Video Why Event-Driven Systems are Hard?

Thumbnail
newsletter.scalablethread.com
0 Upvotes

r/softwarearchitecture • • Jan 08 '25

Article/Video How Tinder Secures Its 500+ Microservices

Thumbnail
newsletter.betterstack.com
0 Upvotes

r/softwarearchitecture • • Oct 16 '26

Discussion/Advice I gave every user their own database instead of one shared Postgres. Talk me out of it.

0 Upvotes

Early-stage app, and everything a user stores is sensitive. Instead of one shared database, each user gets an isolated "home":

- a git repo with append-only event logs

- a SQLite index derived from the logs, rebuildable from zero

- encryption at rest, and one service process per user under its own OS user

Why I like it:

- there's no shared table, so a forgotten `WHERE tenant_id` can't leak data between users

- deleting an account is deleting a folder, exporting is handing over the repo

- changing the index schema is bump the version and rebuild from the log

What worries me:

- every rebuild runs for every user. Fine with a handful, no idea with 10k

- anything cross-user (metrics, support) means fanning out over N homes

- N processes, N backups, and it all sits on one machine for now

The alternative is one Postgres with row-level security and per-tenant encryption keys.

If you've run either in production, what broke first, and at how many users? And did RLS isolation ever actually fail for you, or is that a fear that doesn't show up in practice?


r/softwarearchitecture • • Nov 06 '25

Article/Video Why TypeScript Won't Save You

Thumbnail
cekrem.github.io
0 Upvotes

r/softwarearchitecture • • Jul 09 '26

Discussion/Advice Exception vs Result pattern

0 Upvotes

I don't find any actual good arguments to use Result pattern besided "somebody said it on Internet"

  1. Exceptions should only be for exceptional things -> every single language breaks this rule. Int.Parse, Json parsers, any encrypt/decrypt libraries throws on invalid input - invalid input should be one of most expected things to ever happen. This argument does not hold any value in real APIs, libraries, framewroks. For example, "Connection refused" exception is being throw by any network library, isn't not connecting to remote server most obvious and most expected thing to happen? Literally every network library throws exceptions on connection issues

  2. Exceptions shoudn't be used for control flow -> why? I can make very clean exception pattern. This is literally one of most "somebody said this, so it must be true". you try-catch-catch-catch. Where is difference between that and if-elseif-else or any variation of that aka switch case, when {} etc..

  3. Performance - maybe not for all languages but in some languages you can throw stackless exceptions (you don't build stack and stuck is null). You can log "real exception" with stack then throw stackless exception which is going to have same data and same performance as Result object

  4. Exceptions are not visible in signatures - you can document this, maybe this is relevant for libraries (which all throw exceptions everywhere anyway), but what is the problem of just checking the underlying code or documenting this?


r/softwarearchitecture • • Dec 26 '21

Article/Video What Is The CQRS Pattern?

0 Upvotes

CQRS stands for Command Query Responsibility Segregation and is an evolution of the CQS, Command Query Separation from Bertrand Meyer. CQRS seems to be stated by Greg Young.

Do you want to know more?

https://alexhernandez.info/blog/what-is-the-cqrs-pattern/?utm_campaign=what-is-the-cqrs-pattern/


r/softwarearchitecture • • Feb 22 '26

Discussion/Advice BreakPointLocator: The Pattern That Can Save Your Team Weeks of Work (Java example)

Thumbnail lasu2string.blogspot.com
0 Upvotes

When debugging or extending functionality, there are many possible entry points:

  • You already know

  • Ask a coworker

  • Search the codebase

  • Google it

  • Trial and error

  • Step-by-step debugging

  • "Debug sniping" - pause the program at the 'right' time and hope you’ve stopped at a useful place

Over time, one of the most versatile solutions I’ve found is to use an enum that provides domain‑specific spaces for breakpoints.

public enum BreakPointLocator {

   ToJson {
      @ Override
      public void locate() {
•         doNothing();
      }

      @ Override
      public <T> T locate(T input) {
•         return input;
      }
   },

   SqlQuery {
      @ Override
      public void locate() {
         doNothing();
      }

      @ Override
      public <T> T locate(T input) {
         // Example: inspect or log SQL query before execution
         if (input instanceof String) {
            String sql = (String) input;
            if (sql.contains("UserTable")){
•               System.out.println("Executing SQL: " + sql);
            }
         }
         return input;
      }
   },

   SqlResult {
      @ Override
      public void locate() {
         doNothing();
      }

      @ Override
      public <T> T locate(T input) {
         return input;
      }
   },

   ValidationError {
      @ Override
      public void locate() {
         doNothing();
      }

      @ Override
      public <T> T locate(T input) {
         return input;
      }
   },

   Exception {
      @ Override
      public void locate() {
         doNothing();
      }

      @ Override
      public <T> T locate(T input) {
         return input;
      }
   },
   ;

   public abstract void locate();

   public abstract <T> T locate(T input);

   // Optional method for computation-heavy debugging
   // Don't include it by default.
   // supplier.get() should never be called by default
   public <T> java.util.function.Supplier<T> locate(java.util.function.Supplier<T> supplier);

   public static void doNothing() { /* intentionally empty */ }
}

Binding:

public String buildJson(Object data) {
    BreakPointLocator.ToJson.locate(data);

    String json = toJson(data); // your existing JSON conversion

    return json;
}

public <T> T executeSqlQuery(String sql, Class<T> resultType) {
    BreakPointLocator.SqlQuery.locate(sql);

    T result = runQuery(sql, resultType);

    return result;
}

Steps:

  • Each time that we identify a useful debug point, or logic location that is time consuming, we can add new element to BreakPointLocator or use existing one.

  • When we have multiple project, we can extend naming convention to BreakPointLocator4${ProjectName}.

  • Debug logic is for us to change, including runtime.

Gains:
The value of this solution is directly proportional to project complexity, the amount of conventions and frameworks in the company, as well as the specialization of developers.

  • New blood can became fluent in legacy systems much faster.

  • We have a much higher chance of changing service code without breaking program state while debugging (most changes would be are localized to the enum).

  • We are able to connect breakpoints & code & runtime in one coherent mechanism.

  • Greatly reducing hot swapping fail rate.

  • All control goes through breakpoints, so there is no need to introduce an additional control layer(like switches that needs control).

  • Debug logic can be shared and reused if needed.

  • This separate layer protects us from accidentally re‑run business logic and corrupting the data.

  • We don’t need to copy‑paste code into multiple breakpoints.


r/softwarearchitecture • • Jul 20 '26

Discussion/Advice Does AI naturally produce good architecture

1 Upvotes

I have over 15 years of experience in the IT industry and have spent most of my career building applications using traditional software design principles and architectures, including three-tier architecture, Onion Architecture, and GoF design patterns such as Factory, Adapter, and Strategy.

Over the past three years, however, I've noticed a significant shift toward microservices and distributed architectures. As a result, individual services often contain relatively little business logic compared to the large, object-oriented applications we used to build.

Now, with AI coding assistants generating much of the implementation, I'm curious about how experienced developers are approaching software design today.

My question is: Are teams still consciously applying GoF design patterns and object-oriented design principles, or are they becoming less relevant as developers increasingly rely on AI-generated code? Do you review and refactor AI-generated code to align with established design patterns, or do you generally accept the structure that AI produces as long as it works?

I'd love to hear how architects and senior engineers are balancing classic software engineering principles with today's AI-assisted development practices.


r/softwarearchitecture • • Oct 17 '25

Article/Video From Runtime Risk to Compile-Time Contract: A Case for Strong Initialization

Thumbnail
medium.com
1 Upvotes

In object-oriented systems, especially when following interface-driven design, object creation must often be abstracted away behind factories or builders. These patterns are designed to isolate low-level instantiation details from the rest of the codebase. Yet ironically, the process of constructing objects becomes even more fragile, because not all fields are guaranteed to be initialized before the object is handed off to other parts of the system.

This fragility is exacerbated in languages where uninitialized references default to null. The compiler provides no signal. There is no indication that anything is wrong—until it is. The result is runtime exceptions, often at arbitrary moments and under edge-case conditions.


r/softwarearchitecture • • Mar 31 '25

Article/Video Must Read Books for Software Architects and Solution Architects

Thumbnail
javarevisited.blogspot.com
0 Upvotes

r/softwarearchitecture • • Dec 27 '24

Article/Video My DOs and DON’Ts of Software Architecture

Thumbnail
itnext.io
0 Upvotes

r/softwarearchitecture • • Feb 17 '26 Heartwarming

Discussion/Advice Chatbot architecture design

0 Upvotes

Hi guys, i'm taking my first steps as a software architect, and this time the challenge is to create a chatbot that can answer user queries about data within a SQL database. The system is expected to handle roughly 1000 active users in the long run, and it’s a project where I can experiment without too much risk. That's why i came up with this (possible) solution.

The app is gonna be just a chatbot, nothing more. The user asks a question, the agent generates the answer and the user sees it. I know that someone would use a synchronous API call and a polling to get all the answers of a chat, but i'd like to make some experience with queues and streaming responses. Here the components i thought of and why i chose them:

- Backend API - just a simple NestJS API which handles user chats and queries. For each new query it saves it in DynamoDB and sends it to the agent through SQS along with the history of the chat

- DynamoDB - i've always used Postgres without even thinking about it, and it's time i try something new. I chose DynamoDB to experiment with a NoSQL database and because chat messages fit well with a partition key like conversationId and a sort key timestamp.

- Streaming service - here i just instantiate SSE connections to stream agent answers to each client. Once a new instance of the service is created, it creates a dedicated redis stream consumer and stores a mapping like {conversationId → streamingServiceInstanceId} in Redis with TTL. This allows the agent to know which streaming service instance should receive the response, even if the service scales because of the SSE connections

- SQS - i want the Backend API to be light and fast, shifting the heavy work of answer generation to a dedicated service. I was thinking about a single redis queue but with Redis Streams i would need at least one worker always running. Using SQS allows the agent service to scale down to zero when there are no messages.

- SQL Agent - it's a simple python service that reads a single message at a time and with a LangChain ReActAgent generates the answer. Once it's been generated it saves it in DynamoDB, gets from the cache the redis stream and notifies the right redis consumer of the response

- Redis Stream - Redis Streams are used to route the agent response to the correct streaming service instance that holds the user’s SSE connection

First of all, do you think it's applicable? I know it's probably an overkill for what i need, but i really want to learn and try new things. Last but not least, i'm not sure about how to deploy it yet. It could be a great opportunity to experiment with K8s too.

Each comment is gonna be really useful to me, even if it's against my plan.

Thanks a lot to everyone!


r/softwarearchitecture • • Nov 22 '25

Article/Video System Design: 7 Patterns Decoded

Thumbnail medium.com
0 Upvotes

r/softwarearchitecture • • Sep 04 '25

Article/Video REST API Essentials: What Every Developer Needs to Know

Thumbnail
javarevisited.substack.com
0 Upvotes

r/softwarearchitecture • • Nov 10 '25

Discussion/Advice How are you handling projected AI costs ($75k+/mo) and data conflicts for customer-facing agents?

0 Upvotes

Hey everyone,

I'm working as an AI Architect consultant for a mid-sized B2B SaaS company, and we're in the final forecasting stage for a new "AI Co-pilot" feature. This agent is customer-facing, designed to let their Pro-tier users run complex queries against their own data.

The projected API costs are raising serious red flags, and I'm trying to benchmark how others are handling this.

1. The Cost Projection: The agent is complex. A single query (e.g., "Summarize my team's activity on Project X vs. their quarterly goals") requires a 4-5 call chain to GPT-4T (planning, tool-use 1, tool-use 2, synthesis, etc.). We're clocking this at ~$0.75 per query.

The feature will roll out to ~5,000 users. Even with a conservative 20% DAU (1,000 users) asking just 5 queries/day, the math is alarming: *(1,000 DAUs * 5 queries/day * 20 workdays * $0.75/query) = ~$75,000/month.

This turns a feature into a major COGS problem. How are you justifying/managing this? Are your numbers similar?

2. The Data Conflict Problem: Honestly, this might be worse than the cost. The agent has to query multiple internal systems about the customer's data (e.g., their usage logs, their tenant DB, the billing system).

We're seeing conflicts. For example, the usage logs show a customer is using an "Enterprise" feature, but the billing system has them on a "Pro" plan. The agent doesn't know what to do and might give a wrong or confusing answer. This reliability issue could kill the feature.

My Questions:

  • Are you all just eating these high API costs, or did you build a sophisticated middleware/proxy to aggressively cache, route to cheaper models, and reduce "ping-pong"?

  • How are you solving these data-conflict issues? Is there a "pre-LLM" validation layer?

  • Are any of the observability tools (Langfuse, Helicone, etc.) actually helping solve this, or are they just for logging?

Would appreciate any architecture or strategy insights. Thanks!


r/softwarearchitecture • • Jun 06 '24

Article/Video Defying Gravity: The Unique Challenges of Software Architecture. "How do you define 'good software design' when you can't even tell which way is up?"

Thumbnail
aleph0.io
0 Upvotes

r/softwarearchitecture • • Sep 04 '26

Article/Video Our 40-second guardrails check just became a 0.5-second check 🤡

2 Upvotes

3 years later, we finally fixed the thing that was taking 40 seconds to do what now takes 0.5 seconds 😭

I work at a service-based company on a project that has a pretty large multi-agent AI setup — around 10 agents.

Earlier, the whole thing was basically:

- One giant dependency file

- One virtual environment for all 10 agents

- Everything tightly coupled

- Development needed a VM

- And the funniest part: our guardrails validation was taking ~40 seconds per query 💀

Recently we migrated the setup to microservices + Docker, and while doing that we finally found out that we were creating the guardrails object on every single query.

So instead of initializing it once and reusing it... we were rebuilding it every damn time. 😂

It took the team 3 years to discover this.

After fixing that + moving to the new architecture, guardrail validation went from:

40 seconds → ~0.5 seconds

And the overall deployment/dev setup is now ridiculously faster.

The best part is that we don't need to spin up a VM just to develop anymore. I can run the services locally with Docker and actually work on the system without waiting forever.

Honestly, this is one of those engineering moments where you step back and think:

«"How the hell did we live with this before?"»

Not even a fancy AI breakthrough. Just architecture + finding one stupid initialization bottleneck.

But damn, the setup feels sexy now. 😂


r/softwarearchitecture • • Jun 04 '25

Article/Video Synchronous vs Asynchronous Communication: Choosing the Right Way to Connect Services

0 Upvotes

Imagine you're organizing a dinner party. You need to coordinate with the caterer, decorator, and musicians. You have two options:

Option 1: Call each person and wait on the phone until they give you an answer (synchronous). Option 2: Send everyone a text message and continue planning while they respond when convenient (asynchronous)

This simple analogy captures the essence of service communication patterns. Both approaches have their place, but choosing the wrong one can make your system slow, unreliable, or overly complex.

Read More: https://www.codetocrack.dev/blog-single.html?id=cnd7dDuGU0HgIEohRaTj


r/softwarearchitecture • • Oct 06 '26

Discussion/Advice Why calling public LLM APIs breaks enterprise sovereignty (and how to architect a true Sovereign AI stack in VPC/On-Prem)

0 Upvotes

Many enterprise AI initiatives hit an immediate wall when the CISO or InfoSec team reviews the architecture. Sending internal contracts, customer PII, or proprietary code to public commercial endpoints—even with basic data processing agreements—means losing control over the execution plane and context window.

The industry is rapidly shifting toward Sovereign AI: deploying, orchestrating, and controlling models entirely within your own security perimeter (VPC or air-gapped on-premise) so no data, prompt tokens, or operational telemetry ever leave your environment.

Here is the architectural pattern required to build a production-grade, sovereign LLM stack without sacrificing performance or scalability:

1. Isolated Inference Layer (Ditching External APIs)

If an LLM call crosses an external public endpoint, model sovereignty is lost.

The Fix: Host open-weight models (like Llama 3.3, Mistral, or specialized domain-tuned weights) inside dedicated Kubernetes clusters on isolated cloud tenancies (AWS GovCloud, Azure Sovereign, or private VPCs). Use optimized serving frameworks (vLLM, TGI, or TensorRT-LLM) to achieve sub-second generation throughput on local GPU instances.

2. Zero-Egress AI Gateways & PII Sanitization

Deploying a private model isn't enough if the surrounding orchestration leaks context.

The Fix: Place an internal AI Gateway at the edge of your infrastructure. The gateway enforces strict rate limiting, audit logging, and automated PII redaction/tokenization before any text hits the vector database or model context.

3. Permission-Aware RAG (RBAC/ABAC Synchronization)

A common RAG flaw is returning retrieved documents to a user who doesn't have native read access to the underlying database (e.g., a junior employee querying sensitive HR payroll files).

The Fix: Integrate your Retrieval-Augmented Generation pipeline directly with your Identity Provider (Okta, Azure AD). Enforce document-level permission filtering at query time so the vector store only retrieves chunks the active user's credentials allow.

4. Deterministic Guardrails over Pure Generative Output

Relying solely on system prompts to prevent model drift or policy violations is insufficient for regulated industries (finance, healthcare, legal).

The Fix: Layer deterministic guardrail engines (like NeMo Guardrails or custom structural output parsers) around model responses. Force JSON Schema adherence, block unsafe tool execution, and route low-confidence outputs to human review queues before downstream execution.

Curious how other teams are approaching data sovereignty—are you deploying open-weight models inside your own VPC, using sovereign cloud enclaves, or sticking with commercial APIs with strict NDAs?


r/softwarearchitecture • • Oct 02 '25

Article/Video Before You Publish Your First Event… Stop

Thumbnail
open.substack.com
5 Upvotes

Hey folks,

My name is Dave Boyne, I've been diving into event-driven architectures (deep) over the past 10 years, and I still see the same mistakes happening all the time.

The barrier to entry these days is SUPER low, which is exciting but also quite dangerous... I see many people going into an implementation first mindset... without consider the system itself....

So this is just a thought/reminder to anyone that cares, to explore system thinking, modelling etc, before writing that event onto the SDK.....

Thanks!


r/softwarearchitecture • • Feb 27 '21

Why NodeJs is NOT "single threaded"

Thumbnail
stackchief.com
0 Upvotes

r/softwarearchitecture • • Jul 08 '22

If you are a architect in a start up and you are asked to propose technology stack for a green field project then which technology stack will you popose and why?

0 Upvotes

This was an interview question and the use case is video platform like tik tok.


r/softwarearchitecture • • Dec 24 '25

Discussion/Advice What architecture to use?

1 Upvotes

Hi everyone.

need advice on this decision i made and think it's premature optimization . long story short, I designed a system for an OTC only exchange (with wallet ofc) in microservice architecture but I think it's too much for start, keeping in mind that right now the team size of backend is just two people.

what do you think?! do you think using microservice here is premature optimization or a proper decision?

what should I consider?


r/softwarearchitecture • • Jul 15 '26

Tool/Product The problem with AI-generated architecture diagrams isn't prompting

0 Upvotes

I've been working on an open-source project called drawio-ai-kit, and after spending the last month building it, I realized something interesting.

GitHub:
https://github.com/sparklabx/drawio-ai-kit

LLMs are actually pretty good at understanding software architecture.

What they're not very good at is generating a complete draw.io diagram.

When I asked models to produce .drawio files directly, I kept seeing the same kinds of problems:

  • Wrong AWS/Azure/GCP icons

  • Overlapping components

  • Broken hierarchy (for example, subnets outside VPCs)

  • Connectors crossing through nodes

  • Inconsistent colors and layouts

At first I thought this was a prompting problem.

I tried longer prompts, more examples, and different models.

It helped a little, but the same issues kept coming back.

Eventually I changed the approach.

Instead of asking the AI to generate the final diagram, I ask it to describe the architecture:

  • what components exist

  • how they're grouped

  • how they're connected

Everything else is handled by the toolkit:

  • automatic layout

  • validated stencil catalog (no hallucinated icons)

  • structural validation

  • optional vision-based self-check after rendering

The AI focuses on describing the system.

The engine focuses on drawing it.

That separation made the generated diagrams much more consistent, especially for larger architectures.

After about a month, the project has grown to 500 GitHub stars, which was honestly beyond my expectations.

I'm still improving the layout engine, validators, and adding more platform catalogs (AWS, Azure, GCP, Databricks, BPMN).

I'd love to hear how others are approaching AI-generated architecture diagrams.

What has worked well for you?