- Knowledge
- technology
- OOP
- Tips
- Programming
- Tips
- Tutorial
- SEO
- Ranking
- Knowledge
- Special Day
- Seo
- Bug
- Data science
- Seo
- artificial intelligence
- Machine Learning
- Robotics
- happyNewYear2021
- newYearEve
- 2021
- Automation
- Smart Home
- Career
- Best Practices
- Git
- Logging
- Web Fundamentals
- DNS
- HTTPS
- Performance
- AI Tools
- ChatGPT
- Claude
- Gemini
- Laravel
- Eloquent
- MySQL
- HTTPS
- TLS
- Web Security
- Certificates
- Developer Life
- Debugging
- Docker
- DevOps
- Transactions
- Queues
- LLMs
- AI
- AI Coding
- Developer Tools
- React Native
- Expo
- Kate PMS
- Mobile Apps
- Laravel
- Authentication
- Sanctum
- Cookies
- API Design
- Payments
- Idempotency
- DeepSeek
- Open Source AI
- LLMs
- AI News
- Git
- Version Control
- AI Coding
- Prompting
- PHP
- Checklist
- MCP
- AI Agents
- OpenAI
- Architecture
- Microservices
- Modular Monolith
- Estimation
- Developer Life
- Project Planning
- Humour
- OAuth
- OpenID Connect
- Authentication
- Embeddings
- Vector Search
- RAG
- pgvector
- OpenAI
- GPT-4.1
- Codex CLI
- Events
- Testing
- Clean Code
- Maintainability
- Code Review
- Webhooks
- API
- Security
- Claude Code
- Workflow
- AI
- LLM
- Prompt Injection
- Mobile
- React
- Networking
- TCP
- UDP
- HTTP/3
- CLAUDE.md
- AWS
- Cloud Security
- Backups
- PHPUnit
- Software Engineering
- Leadership
- Communication
- RAG
- Embeddings
- AI Engineering
- IT Infrastructure
- Networking
- Access Control
- CI/CD
- GitHub Actions
- Gemini CLI
- Claude Code
- JavaScript
- Async/Await
- Node.js
- Promises
- Security
- Cryptography
- Passwords
- MySQL
- Database
- Vibe Coding
- Software Quality
- DNS
- Code Reading
- Onboarding
- Productivity
- Background Jobs
- Developer Humour
- Estimates
- Dev Life
- JWT
- o3-mini
- DeepSeek R1
- Rate Limiting
- Kate PMS
- E-Signing
- Audit Trail
- REST
- GraphQL
- API Design
- Laravel 12
- Upgrade Guide
- Open Source
- Self-Hosting
- Task Scheduling
- Cron
- Secrets
- CORS
- PHP
- PHP-FPM
- OPcache
- GitHub Copilot
- Software Architecture
- Engineering
- TypeScript
- JavaScript
- Type Safety
- AI Security
- React Native
- Product Design
- AI Agents
- Kiro
- Queues
- Redis
- RabbitMQ
- AWS SQS
- Nginx
- Apache
- GPT-5
- gpt-oss
- Clean Code
- Architecture
- Naming
- Documentation
- Career
- ADR
- Teamwork
- Supply Chain
- Kate HRM
- HR Software
- Permissions
- System Design
- Pagination
- SSH
- Linux
- Big O
- Databases
- Laravel Boost
- MCP
- Developer Skills
- Validation
- Databases
- Indexes
- Code Quality
- Deployment
- Developer Humour
- Feature Flags
- Code Review
- Pull Requests
- Docker
- Cursor
- Authorization
- RBAC
- Gemini
- Long Context
- PHP 8.4
- Caching
- Dependency Injection
- Web Performance
- Browser
- CSS
- Database
- Migrations
- ChatGPT
- AI for Developers
- Monitoring
- On-Call
- REST
- Backend
- SQL
- NoSQL
- Database Design
- Coding Agents
- Claude 4
- API Resources
- REST API
- Load Balancing
- Scaling
- AWS
- AI Tools
- Claude
- Sora 2
- CTE
- 2FA
- TOTP
- Programming Languages
- Prompts
- Developer Workflow
- API Gateway
- APIs
- Passport
- API Auth
- Learning
- Burnout
- Developer Growth
- Web Development
- SEO
- Kate Mall
- ChatGPT Atlas
- Agent Skills
- Middleware
- Laravel 12
- Collections
- Context Window
- Monitoring
- Commit Messages
- Self Review
- Growth
- Regex
- Programming Basics
- Text Processing
- Database Design
- Normalization
- Linux
- Server Security
- Linux Foundation
- Open Standards
- Legacy Code
- Documentation
- AI Workflow
- File Uploads
- Test Data
- Hashing
- Performance
- Caching
- Enums
- Scope Creep
- Estimation
- Codex
- Gemini CLI
- Timezones
- Carbon
- Bugs
- PHP 8.5
- Gemini 3
- GPT-5.1
- Data Integrity
- Event Loop
- Async
- Opus 4.5
- AI Models
- React
- Forms
- Frontend
- Backups
- AI Images
- DALL-E
- Midjourney
- Race Conditions
- Concurrency
- Legacy Code
- Refactoring
- Senior Engineer
- Scope
- LLM
- CDN
- Web
- Sub-Agents
- Soft Deletes
- Audit Log
- Concurrency
- AI Learning
- NestJS
- AI Evals
- Policies
- SPF DKIM DMARC
- Unicode
- UTF-8
- Knowledge Graph
- Value Objects
- Technical Debt
- Feature Flags
- Laravel Pennant
- Deployment
- Copilot
- Composer
- Dependencies
- Artisan
- Automation
- AWS S3
- Object Storage
- Cloud
- Small Language Models
- Ollama
- Production
- Sessions
- HTTP
- Mentoring
- SQL
- Virtual Machines
- Web Development
- HTTP/2
- QUIC
- Web Performance
- AI Integration
- LLM API
- SOLID
- OOP
- Hosting
- Serverless
- Merge Conflicts
- Temperature
- AI Development
- Reverse Proxy
- Nginx
- Infrastructure
- Verification
- Passkeys
- WebAuthn
- Teams
- Communication
- Stakeholders
- Monorepo
- CI/CD
- Versioning
- JSON Schema
- Livewire
- Inertia
- Meetings
- Distributed Systems
- Privacy
- Full-Stack
- T-Shaped Skills
- Money
- Notifications
- Web Security
- HTTP Headers
- CSP
- Function Calling
- Load Testing
- k6
- Data Extraction
- Debugging
- WebSockets
- SSE
- Real-Time
- Laravel Reverb
- Infrastructure as Code
- Terraform
- Side Projects
- Laravel Pint
- OpenAPI
- Swagger
- UX
- Multimodal
- Jest
- Pair Programming
- APIs
- Rate Limiting
- Resilience
- Dev Humour
- Design Tokens
- JWT
- API Keys
- Sessions
- PHPStan
- Rector
- Incidents
- Reporting
- Dashboards
- Zero Trust
- IAM
- Search
- Laravel Scout
- Junior Developers
- Mentoring
- Images
- WebP
- AVIF
- Bug Reports
- Let's Encrypt
- Design Docs
- Software Design
- Observers
- Replication
- Accountability
- Data Structures
- Reliability
- LLM Memory
- Error Handling
- Payments
- Payment Gateway
- Webhooks
- PCI DSS
- Observability
- OpenTelemetry
- Personal Brand
- Writing
- Conventions
- Dates
- Scheduling
- Disaster Recovery
- Compression
- Brotli
- Deadlines
- Developer Habits
- State Machines
- Tech Roles
- UUID
- ULID
- Horizon
- Planning
- Engineering Culture
- Ownership
- Soft Skills
- Socialite
- Cost Control
- Collations
- Unicode
- Octane
- PostgreSQL
Monolith vs Microservices: What Most Teams Actually Need
About Post
Here's an unpopular opinion that I'll defend for the rest of this article: most teams that move to microservices don't have a scaling problem. They have an organisation problem, a messy codebase, or a conference talk they enjoyed. Microservices fix exactly one of those, and only sometimes.
That doesn't make microservices wrong. It makes them expensive, and you should know what you're buying. So let's compare the two honestly, then look at the option I think most teams actually need: the modular monolith.
The real difference is not the number of repos
A monolith is one deployable application. A microservice architecture is many small applications, each owning its own data, talking to each other over the network.
That last part is the whole story. Inside a monolith, "get the tenant's balance" is a function call. It takes nanoseconds, it can't time out, and if it throws, you get a stack trace. Between services, the same thing is an HTTP request or a message on a queue. It can be slow. It can fail. It can succeed while the response gets lost. The other service can be mid-deploy, running a different version, or down.
Every function call you turn into a network call becomes a distributed systems problem. That's the price, and it's paid on every feature, forever.
Side by side
| Monolith | Microservices | |
|---|---|---|
| Deploying | One pipeline, one artifact | Many pipelines, version compatibility between services |
| Data consistency | Database transactions just work | No cross-service transactions; sagas, outbox pattern, eventual consistency |
| Debugging | One log, one stack trace | Distributed tracing needed to follow one request |
| Local development | Run one app | Run many services, or mock them |
| Refactoring across boundaries | Your IDE renames it | A versioned API change and a coordinated rollout |
| Scaling | Scale the whole app (often perfectly fine) | Scale only the hot parts |
| Team independence | Teams share one codebase and release train | Teams deploy on their own schedule |
| Technology choice | One main stack | Each service can use what fits |
Look at where microservices win: independent scaling, independent teams, independent technology. Those are real benefits, and they matter a lot when you have many teams stepping on each other in one codebase. They matter very little when you have one team of five.
"But our monolith is a mess"
This is the most common reason I hear, and the most dangerous one. If the code is tangled, with every part reaching into every other part's tables, splitting it into services doesn't remove the tangle. It moves it onto the network. You get what people call a distributed monolith: all the coupling of the old system, plus latency, partial failures and five deploy pipelines that must release together.
A mess is a boundaries problem. The fix is drawing boundaries, and you can do that without a single network call.
The modular monolith
A modular monolith is one deployable app, split inside into modules with clear ownership and rules about how they talk. In Laravel, it can be as plain as folders:
app/
Modules/
Leasing/ contracts, renewals
Billing/ invoices, payments
Maintenance/ requests, work orders
Shared/ money, dates, common value objects
Each module has its own models, services, events and often its own service provider. The rules that make it work:
- Modules talk through a public surface, such as a service class or events, never by querying each other's tables or models directly.
- Each table has one owning module. Billing writes invoices. Leasing asks Billing.
- Cross-module side effects use events. Leasing dispatches
ContractSigned; Billing listens and creates the first invoice.
Rules nobody checks become suggestions, so enforce them. If you use Pest, architecture tests make it a failing build instead of a code review argument:
arch('leasing does not touch billing internals')
->expect('App\Modules\Leasing')
->not->toUse('App\Modules\Billing\Models');
Packages like nwidart/laravel-modules give you more structure if you want it, but plain folders and a few arch tests get you most of the value.
The quiet superpower: if one module ever truly needs to become a service, it's already behind a clean interface. You swap the in-process call for an HTTP client, and nothing else in the app has to know. Extracting a service from a modular monolith is surgery. Extracting one from a tangled monolith is an archaeology dig.
When splitting really is the answer
I'd consider pulling something out into its own service when at least one of these is true and hurting:
- Very different scaling needs. A PDF or image processing workload that eats CPU while the rest of the app is mostly idle.
- Very different reliability needs. Something that must keep working when the main app is down, or must not take it down when it fails.
- A team that genuinely needs its own release cycle, because coordinating with everyone else has become the bottleneck.
- A different runtime does the job much better, like a Node or Python service for a specific library or AI workload.
Notice what's not on the list: "it's more modern", "the code is messy", "we might need to scale one day".
And the honest middle ground: in many Laravel apps, queues and separate worker processes already give you most of the scaling benefit. Heavy jobs run on their own worker servers, scaled independently, while the code stays in one repository with one deploy.
My default: start with a modular monolith, enforce the boundaries, and extract a service only when you can name the specific pain it removes. Splitting is easy to do later. Merging services back together almost never happens.
The checklist before you split
- Can you name the module boundaries today, in your current code?
- Does each table have exactly one owner?
- Do you have the tracing, monitoring and deploy automation to run several services?
- Is the pain you're solving about scale, reliability or teams, and not just tidiness?
If the first two answers are no, microservices will make things worse. If all four are yes, you probably already know which service to extract first.
Where does your team sit right now: happy monolith, modular monolith, or a set of services you sometimes wish were one app?

Be first to comment it...