Laravel Development
Web development with Laravel: we build web applications, portals and APIs with Laravel where it is the right choice — and tell you where it is not. From domain modeling through queues and Octane to operations under load.
Laravel Development in one minute.
For decision-makers: our position at a glance — when it fits, how we approach it, what we optimize for.
- Laravel fits when
- a clear business domain with a web or API focus is being built and time to market matters.
- Laravel gets difficult when
- hard real-time, CPU-bound workloads or the strictest architectural separation are required from day one.
- Preferred architecture
- modular monolith, business logic independent of Eloquent, API-first when there are multiple clients.
- Typical project size
- medium to large business applications — one team, several modules, one deployment.
- Typical risks
- Fat models, missing idempotency in asynchronous processing, framework magic instead of a domain model.
- What we optimize for
- Changeability over years, transparent operations and a domain that is independent of the framework.
- What we deliberately avoid
- premature microservices, no-code shortcuts and business logic in controllers and models.
- Expected lifespan
- Systems designed for five to ten years of production use.
Risks we catch early.
What typically goes wrong in systems like this — and how we prevent it before it shows up in production.
- 01
Fat models
- Why
- Eloquent makes it easy to put business rules directly into the model. That grows with the system until the model knows everything and nobody can follow it anymore.
- Early warning signs
- Models with many responsibilities and tests that have to boot half the application.
- How we prevent it
- Business logic in services, actions and value objects; the model stays responsible for persistence, not for rules.
- Trade-off
- Cost: more classes and a bit more setup. Different when: a small, short-lived application — then the model may carry more.
- 02
Logic in the controller
- Why
- The fastest way is to do everything in the controller. That works — until the same logic is needed in a second place.
- Early warning signs
- Controllers with business rules, duplication between controllers, endpoints that are hard to test.
- How we prevent it
- The controller receives, validates and delegates to the domain. It does not decide.
- Trade-off
- Cost: an additional layer. Different when: a trivial endpoint without reuse — then it stays lean.
- 03
Queues without idempotency
- Why
- Queues deliver at least once. Without idempotency, a duplicate delivery produces duplicate effects — duplicate notifications, duplicate bookings.
- Early warning signs
- Jobs without a unique key, side effects without checks, occasional duplicates without a clear cause.
- How we prevent it
- Every job is idempotent: a key is checked and persisted in the same transaction as the effect.
- Trade-off
- Cost: a key store with retention. Different when: the effect is idempotent by nature — then that is enough.
- 04
Cache invalidation
- Why
- Caching is easy to add and hard to keep correct. Without clear rules, the cache will eventually serve stale data.
- Early warning signs
- Caches without defined invalidation, “sometimes old data”, debugging by clearing the cache.
- How we prevent it
- What gets cached and when it becomes invalid is part of the design — not an afterthought.
- Trade-off
- Cost: thinking through consistency up front. Different when: consistency matters more than latency — then don’t cache, optimize the query instead.
- 05
Missing observability
- Why
- As long as everything runs, missing visibility goes unnoticed. At the first incident, the signals needed to understand what happened are missing.
- Early warning signs
- No structured logs, no traces, operational questions nobody can answer.
- How we prevent it
- Logs, metrics and traces belong to day one; the system can tell you why a request was slow.
- Trade-off
- Cost: instrumentation and curated signals. Different when: a throwaway prototype — then minimal.
- 06
Database bottlenecks
- Why
- The bottleneck is almost always the database, not the framework. N+1 queries and missing indexes only show up under load.
- Early warning signs
- Slow endpoints under load, many small queries per request, query times that grow with the data.
- How we prevent it
- Deliberate query loading (eager loading), targeted indexes, measurement in production; the database is the first place we look.
- Trade-off
- Cost: attention to queries instead of “just Eloquent”. Different when: small data volumes — then the effort is unnecessary.
- 07
Premature microservices
- Why
- Microservices are seen as the standard for serious systems. Introduced too early, you pay for network boundaries and operational overhead without the benefit.
- Early warning signs
- Distributed services without independent scaling, one team deploying several services in lockstep — a distributed monolith.
- How we prevent it
- Start as a modular monolith with clear boundaries; a service is extracted only when a concrete requirement calls for it.
- Trade-off
- Cost: no independent scaling of individual parts at the start. Different when: parts demonstrably have radically different requirements.
- 08
Framework coupling
- Why
- If the domain is tied directly to Eloquent and framework magic, every change — and every upgrade — becomes more expensive.
- Early warning signs
- Business rules in Eloquent models, tests that need the database, reluctance to upgrade the framework.
- How we prevent it
- The domain stays independent of the framework; Laravel is infrastructure, not the home of the business logic.
- Trade-off
- Cost: a bit more structure from the start. Different when: a short-lived application without long-term maintenance.
The questions we ask before writing code.
Not advice, but decision questions. Your answers shape the architecture — not the tools.
- 01
Do multiple clients share the same business logic?
- Why it matters
- As soon as several frontends or partners use the same system, the API becomes a contract that can no longer be changed freely.
- Typical consequence
- If the answer is yes, we design API-first — versioned and documented before the web interface is built.
- 02
Do we need asynchronous processing?
- Why it matters
- Slow or unreliable side effects in the critical response path tie latency and errors to the slowest system involved.
- Typical consequence
- If yes, they move into a queue, idempotently; if not, the path stays synchronous and simple.
- 03
Is strict architectural separation required from the start?
- Why it matters
- Some contexts demand hard boundaries from day one — for regulatory reasons or because of very large domains.
- Typical consequence
- If so, we check whether Symfony is the more solid foundation; otherwise a cleanly cut modular monolith is enough.
- 04
How long does this system need to live?
- Why it matters
- The expected lifespan determines how much structure and documentation pay off early.
- Typical consequence
- For operation over many years, we consistently separate the domain from the framework; for a short-lived experiment, we don’t.
- 05
How often do the business rules change?
- Why it matters
- Frequently changing rules need to live in one place, not scattered across controllers and models.
- Typical consequence
- With a high rate of change, we encapsulate rules in the domain; with stable rules, it can be leaner.
- 06
Is operational visibility required?
- Why it matters
- A system that has to answer questions in production needs signals that can only be built in at design time.
- Typical consequence
- If yes, logs, metrics and traces are part of it from the start; retrofitting them later is hard.
- 07
Can consistency be eventual?
- Why it matters
- Asynchrony and caching bring eventual consistency with them — the interface and the users have to be able to cope with that.
- Typical consequence
- Where yes, we communicate states honestly (for example, “in progress”); where no, the path stays synchronous and consistent.
- 08
Which path carries the greatest risk?
- Why it matters
- The greatest risk should be at the beginning, not become visible at the end of development.
- Typical consequence
- We prove the hardest path end to end first; everything else builds on it.
What it is — and what it includes.
Laravel is a mature PHP framework for web applications and APIs and the most frequently used backend framework in our web development. We use it for business applications whose requirements go beyond simple CRUD: clearly scoped domains, reliable background processing and operations that are still transparent five years from now. Laravel remains the infrastructure — the business logic stays independent of it.
Scope of services
- Domain model and architecture
- APIs and integrations (REST, versioned)
- Asynchronous processing with queues and Horizon
- Caching, Redis and performance
- Testing, CI/CD and operations
Decisions before code is written.
Not what the technology can do, but why we use it the way we do.
- 01
Modular monolith before microservices
Most Laravel systems start best as a modular monolith: clear module boundaries within one codebase. That keeps complexity low as long as distributed systems are not really needed — and it can be split later in a targeted way when a boundary calls for it.
- 02
Business logic out of the framework
Rules belong in services, actions and value objects — not in controllers or models. That keeps the domain testable and independent of Eloquent. The controller receives and delegates; it does not decide.
- 03
Eloquent deliberately, not dogmatically
Eloquent is productive and readable for the majority of data access. For complex or performance-critical queries, we deliberately reach for the query builder. We only use the repository pattern where it brings real decoupling — not for its own sake.
- 04
API-first where multiple clients access the system
As soon as partners, mobile apps or multiple frontends use a system, we design the API first: versioned, documented, as a stable contract. The web interface is then one of several consumers, not the system itself.
How we build. The Batunet Engineering Method.
Seven phases — from the first question to operations years later. Not a project process, but the way we think.
- 01
Frame
The actual problem, its boundaries and a measurable definition of success are established before any solution is considered.
- 02
Model
The domain is modeled and sliced into contexts — with a precise, shared language.
- 03
Decide
The load-bearing decisions come first — deliberately and documented, while change is still cheap.
- 04
Prove
A walking skeleton proves the architecture on the riskiest path — before going broad.
- 05
Build
On top of the proven skeleton, the system grows in verifiable, reversible steps — with progress visible every week.
- 06
Harden
Failure cases, load and security are tested, not assumed. “It runs” becomes “it holds.”
- 07
Operate
We operate, monitor and keep evolving the system — and keep it understandable and changeable.
From design to operations.
The system doesn't just have to run — it has to hold up in operation. Every recommendation comes with its cost, and with the case where we decide differently.
Queues & Horizon
Everything that can wait runs asynchronously via queues. Horizon makes workers, throughput, run times and failed jobs with their retry strategy visible.
Trade-off · Cost: eventual consistency and the obligation to be idempotent. Different when: the operation is critical for the response — then it stays synchronous.
Octane — performance engineering
For latency-critical services, Octane keeps the application in memory between requests and noticeably reduces latency. But first we measure where the time is really lost — usually in the database.
Trade-off · Cost: stateless code, careful resource handling, risk of memory leaks. Different when: latency is not critical — then classic PHP-FPM is enough and simpler to operate.
Caching & Redis
Redis serves as a cache, a queue backend and for distributed locks. What gets cached and how it is invalidated is a deliberate design decision: what may go stale, what has to be consistent?
Trade-off · Cost: cache invalidation is hard; wrong caching serves stale data. Different when: consistency matters more than latency — then we don’t cache but optimize the query.
Event-driven decoupling
Domain events separate side effects from the main logic. Processed via the queue, they keep transactions lean and the system extensible without touching existing paths.
Trade-off · Cost: more indirect flows that are harder to trace. Different when: the flow is simple and clearly synchronous — then no event.
Observability
Structured logs, metrics and traces belong to day one, not to the first incident. A system in production has to be able to answer why a particular request was slow.
Trade-off · Cost: instrumentation, storage and the discipline to curate signals instead of generating noise. Different when: a short-lived prototype — then minimal instrumentation.
Testing strategy
Feature tests on the critical paths, unit tests for the domain logic. Tests where bugs get expensive — and as a safety net for confident changes over the years.
Trade-off · Cost: test maintenance and a slower first delivery. Different when: a throwaway spike without production code — then no tests.
Zero-downtime deployment
Reproducible deployments (Docker, Forge/Envoyer) with health checks. Schema changes are backward-compatible using the expand/contract pattern: first extend additively, then switch the code over, finally clean up.
Trade-off · Cost: two-phase migrations and more deployment discipline. Different when: a short maintenance window is acceptable — then a simpler migration path is enough.
Security — standards instead of homegrown solutions
Authentication via established packages (such as Sanctum or OIDC), least privilege, secrets outside the code, validated input and escaped output. Security is a design decision, not an audit at the end.
Trade-off · Cost: less freedom, more convention. Different when: there is a very specific requirement — then deviate deliberately and with review, never improvised.
Upgrade strategy
We follow Laravel’s annual release cycle with disciplined, tested upgrades and keep dependencies current and deliberately few.
Trade-off · Cost: regular upgrade effort due to the shorter support window. Different when: maximum upgrade calm over many years is the priority — then Symfony with LTS is the more solid foundation.
Long-term operations & maintainability
The domain stays independent of Eloquent, key decisions are recorded as ADRs, operations are monitored and responsibilities are clear. That keeps the system safe to change for years.
Trade-off · Cost: more structure and documentation discipline from the start. Different when: a short-lived experiment — then deliberately speed over structure.
Risk — the hard path first
The riskiest path runs end to end first as a working skeleton. Failure cases are tested, not assumed; every change remains reversible.
Trade-off · Cost: slower visible progress at the start. Different when: the risk is demonstrably low — then go straight for breadth.
Schematic architecture.
Generic excerpts — with no client reference, but the way we actually design: a modular monolith with an event-driven, idempotent path.
What you can rely on.
- 01
A system whose business logic stays testable independently of the framework
- 02
Transparent operations: visible queues, metrics and logs
- 03
A codebase a team can keep developing for years
When it fits — and when it doesn't.
An honest answer is part of good advice. We recommend the path that fits the problem.
Good fit
- Business applications with a clear domain and a web interface
- SaaS products, APIs and portals where time to market matters
- Systems a team is expected to maintain and develop for years
- Projects that benefit from a large, mature ecosystem
Not a fit
- Hard real-time or very low latency requirements at the system level
- CPU-bound, compute-intensive processing — a different stack fits there
- Very small, static sites without real application logic
- Cases where the strictest architectural separation is mandatory from day one — Symfony is often the more solid foundation there
Technologies we use
Questions about Laravel Development
When is Laravel the right choice?
When a clearly delimited business domain with a web interface or API is being built, time to market matters and a team is expected to maintain the system for years. The mature ecosystem takes care of recurring work without giving up control over the architecture.
When is Laravel not the right choice?
For hard real-time requirements, CPU-bound workloads, or when the strictest architectural separation is mandatory from day one. In such cases, we recommend a different stack — or Symfony, if separation is the priority.
How does Laravel scale?
Horizontally: stateless app servers behind a load balancer, sessions and cache in Redis, asynchronous work in queues, read access via read replicas. The bottleneck is almost always the database, not the framework — that is where we start. Octane additionally reduces latency where it matters.
How do you structure large Laravel projects?
As a modular monolith with modules along the domain, not along technical layers. The business logic lives in services and value objects, independent of Eloquent. Clear module boundaries keep complexity manageable and allow for a later split if needed.
How does a Laravel application stay maintainable for years?
Through a domain that is independent of the framework, tests aligned with the risks, documented decisions (ADRs), disciplined version updates and deliberately chosen, mature dependencies. Maintainability is the result of decisions made early.
How do you deploy without downtime?
Reproducible deployments with health checks and backward-compatible migrations using the expand/contract pattern: first an additive schema change, then the code, then the cleanup. The price is a two-phase migration; where a short maintenance window is acceptable, it can be simpler.
How do you keep the application secure?
Established auth packages instead of homegrown solutions, least privilege, secrets outside the code, validated input and escaped output. Security is a design decision from the start, not an audit at the end — the trade-off is a little less freedom in favor of proven conventions.
How do you handle Laravel upgrades?
We follow the annual release cycle with tested upgrades and a small number of up-to-date dependencies. The price is regular effort due to the shorter support window; if you need maximum upgrade calm over many years, Symfony and its LTS policy are often the better fit.
Do we own the source code?
Yes. The project-specific source code and the agreed project artifacts — documentation, migrations, deployment configuration — are handed over to you. The framework, packages and other open-source components remain under their own licenses. You stay technically independent — including from us.
Continue your engineering journey.
Related concepts, decisions, playbooks and perspectives — as one connected path, not a list of links.
Technologies
Services
Let’s talk about your project.
No sales team. A direct conversation with the management.
