When Architects Overdesign: Tales of Microservices, MQ, Caches, and Database Chaos

The article humorously chronicles a series of real‑world over‑design incidents—excessive microservice splitting, needless multi‑database sharding, ubiquitous message‑queue usage, over‑engineered caching, design‑pattern abuse, and bloated database schemas—highlighting why simplicity (KISS) remains the best practice for backend systems.

dbaplus Community
dbaplus Community
dbaplus Community
When Architects Overdesign: Tales of Microservices, MQ, Caches, and Database Chaos

Microservice Granularity

One interviewee argued that finer granularity is always better, even splitting a monolith by controller, service and DAO layers into separate services. The result was an explosion of tiny services with no clear business boundary, increasing operational overhead and inter‑service coordination cost.

Pre‑planned Database Schema

A five‑year architecture plan allocated three physical databases and 300 tables based on an assumed peak of three million orders per day. Developers were forced to follow complex routing rules to locate data, often having to query tables one‑by‑one during debugging because the data was spread across many sharded tables.

Ubiquitous Message Queues

Message queues (MQ) were used for almost every scenario, including:

Asynchronous SMS verification where the producer and consumer belong to the same service.

Logging business events via MQ to decouple log writers.

Low‑TPS scheduling tasks (e.g., appointment booking) to achieve peak‑shaving.

Replacing most inter‑service RPC calls with MQ to claim system decoupling.

These uses added latency, increased system complexity, and made tracing difficult.

Multi‑Level Caching (Guava + Redis)

A Guava in‑process cache combined with a Redis distributed cache was deployed across OA systems, corporate websites, messaging centers, settlement, supply‑chain and CRM platforms. The layered cache improved read latency but caused frequent data‑inconsistency incidents because cache invalidation logic was not uniformly applied across services.

Design‑Pattern Overuse

Developers were repeatedly forced to apply heavyweight patterns regardless of necessity:

Builder pattern for simple POJOs.

Strategy pattern for any if‑else block.

Abstract Factory, Proxy, Observer patterns for trivial responsibilities.

This resulted in verbose code, steep learning curves for newcomers, and reduced readability.

Excessive Many‑to‑Many Relationships

Database schemas were designed with an overabundance of junction tables. While some many‑to‑many relationships (e.g., students ↔ classes, students ↔ courses, teachers ↔ students) are legitimate, the design also produced nonsensical mappings such as a single exam score belonging to multiple students or a class‑hour balance shared across students, leading to data integrity problems.

Database Portability Advice

Some architects advocated for maximum database portability by:

Using Hibernate HQL to abstract vendor‑specific syntax (e.g., limit vs. rownum).

Avoiding stored procedures to keep business logic out of the database.

Writing standard SQL to reduce future migration risk.

In practice, the team never needed to migrate databases, making the effort largely unnecessary.

Redundant Data Validation

One team re‑validated data after reading it from the database under the assumption that external actors might modify the data directly. This “defense‑in‑depth” validation duplicated checks already performed at write time and added processing overhead without measurable benefit.

Configuration‑Centric Business Logic

Numeric thresholds and business constants (e.g., HashMap.size()>0, gender code 1 for male, product status 2 for offline) were externalized to a configuration center to allow runtime changes without redeployment. While flexible, this practice scattered core business rules into configuration files, making the codebase harder to understand and increasing the risk of misconfiguration.

Conclusion

The recurring theme is over‑design: excessive service granularity, premature sharding, indiscriminate use of MQ and caches, pattern fetishism, and over‑engineered schemas. Adhering to the KISS (Keep It Simple, Stupid) principle—using the simplest architecture that satisfies functional requirements—helps maintain system reliability, reduces operational cost, and eases future evolution.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Software ArchitectureMicroservicescachingDatabase designKISS
dbaplus Community
Written by

dbaplus Community

Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.