Home/Technology
We are deliberately boring about tooling. Ten core technologies, run in production long enough that we know their failure modes, assembled into one seven-layer architecture. This page is the whole of it — what each part does, what it replaced, and what it costs us.
10 core technologies · 7 architecture layers · 4 environments
What you are actually buying
Each one is a promise, and a link to the section of this page that has to discharge it. Nothing below is asserted without the artefact that proves it.
The ten
Every tool here earned its place by displacing something that was slowing us down. Open a row for the argument, the cost we accepted, and how we would get off it.
Why it is here
Business rules, authentication, the admin, queues and scheduled work. Most of what we build starts here, because the framework already contains the eighty percent every project needs and we only write the part that is yours. Long support windows, and the largest PHP hiring pool in India, so the team that inherits it can actually be hired.
What it costs us
PHP handles one request per process, so long-lived connections and heavy real-time work do not belong here. It is also more framework than a pure API needs. We accept the weight for what comes in the box.
Why it is here
Websockets, streaming integrations and workers that need to hold a connection open. It puts opinionated structure on top of Node, so the second developer can find things, and TypeScript runs the whole way from the service to the React screen consuming it.
What it costs us
A second runtime to deploy, patch and monitor. We add it when a workload genuinely needs it, not because the diagram looks better with more boxes on it.
Why it is here
Dashboards, admin panels and anything carrying real state across many screens. It has the largest component ecosystem and the largest hiring pool, so whatever the interface needs, a maintained library already exists and someone we have not met can pick the codebase up.
What it costs us
Bundle size. We budget it and measure it on a mid-range Android phone on a weak connection, rather than assuming it away on a developer's laptop.
Why it is here
One interactive screen added to a server-rendered application that is otherwise fine. It drops into a Blade page a component at a time, which gets a modern interface into an older system without betting the whole budget on a rewrite nobody asked for.
What it costs us
Two frontend frameworks in the practice instead of one. The rule that keeps it honest: one per project, never both in the same codebase.
Why it is here
Apps where the same feature set has to exist on iOS and Android. It draws its own widgets, so the interface behaves the same on a five-year-old Android handset as on a new iPhone, and one team ships to both stores on one release cycle instead of two.
What it costs us
A larger install size, and a native bridge written by hand whenever we reach hardware the plugin ecosystem does not already cover.
Why it is here
The data your business would still need if every application were deleted. Business data is relational — invoices belong to customers, appointments belong to doctors — and constraints and transactions belong in the database rather than in hope and application code.
What it costs us
Schema changes need a migration and a plan. We treat that as a feature rather than a tax: the shape of your data is reviewed before it changes, not after.
Why it is here
Everything that is expensive to compute and cheap to remember: sessions, cached views, rate limits and the queue behind background work. It is the cheapest performance available — put it in front of the slow read and the slow page stops being slow, for the price of a small instance.
What it costs us
It is memory, so it is never the truth. Anything held only in Redis is allowed to disappear, which means everything in it has to be re-derivable from MySQL, and we design it that way from the first week.
Why it is here
The unit we build, test, ship and roll back. The same image runs on a laptop, in the pipeline and in production, so a new developer is useful on day one instead of day four, and rebuilding a server is a command rather than a weekend of archaeology.
What it costs us
A slower first build, images to store and patch, and one more thing a new developer has to learn on day one. It pays for itself the first time a server has to be rebuilt under pressure.
Why it is here
Compute, managed database, object storage and CDN, in regions close to Indian users. The managed services are precisely the ones we would otherwise run badly ourselves — database backups, storage durability, certificate renewal. We would rather buy those than be responsible for them at two in the morning.
What it costs us
Vendor surface. We hold it down deliberately: infrastructure described in code, data in open formats, the application in a container. Leaving becomes a project rather than a rebuild.
Why it is here
Commerce where the hard part is the catalogue, not the code. Nobody should be maintaining their own checkout: payments, tax and card compliance are Shopify's problem, and the catalogue, the storefront and the integrations back into your own systems are ours.
What it costs us
Their platform, their limits and their fees. The checkout is not ours to change. When the business logic outgrows the platform, the logic moves into Laravel and Shopify stays the till.
Request path
A page request takes one of three routes depending on what is already cached and whether it writes. Pick one and the live path lights up; the rest of the system stays visible but dimmed.
Swipe to follow the request →
Synchronous path in accent · queued work in teal · dimmed nodes are not on this route
System thinking
A reference architecture we adapt, not a template we apply. Select a layer to see what it owns and what we build it with.
Layer 1 — Experience
Every surface a person actually touches. Responsive, fast on mid-range Android devices, and designed so the common task is one tap away rather than three menus deep.
Responsibilities
Typically built with
Layer 2 — Ingress
Caching, certificates and basic protection at the front door. Cheap to run, and the single biggest lever on how fast a site feels outside a metro city.
Responsibilities
Typically built with
Layer 3 — Core
Where the business rules live. One well-structured application beats four services when the team is small — we split it only when a part genuinely needs its own release cycle.
Responsibilities
Typically built with
Layer 4 — Contract
A versioned contract between the app and everything else — mobile clients, partner systems, payment gateways. Documented, so the next integration does not need a meeting.
Responsibilities
Typically built with
Layer 5 — State
Relational where the data is relational. Cache and queues in front of the slow paths, and backups that have actually been restored at least once.
Responsibilities
Typically built with
Layer 6 — Analytics
Reporting that reads the same governed data as the rest of the system — the numbers a manager asks for every Monday, on screen and as a scheduled export, instead of a query someone runs by hand.
Responsibilities
Typically built with
Layer 7 — Operations
Cuts across everything above. Reproducible environments, one deployment pipeline, and alerts that reach a person before a client does.
Responsibilities
Typically built with
Environments & delivery
Code moves in one direction through gates that either pass or stop the build. Nothing reaches production that has not already been the same container image in three cheaper places.
01
Commit
GateLinters and static analysis pass before the commit lands.
02
Review
GateOne reviewer. No direct pushes to main, including ours.
03
Build
GateTest suite green, dependency audit clean, image published.
04
Staging
GateMigrations run and the smoke check answers.
05
Sign-off
GateYou have used it on the staging URL and approved it.
06
Production
GateManual approval, health check green, rollback ready.
Swipe the table →
Security & data
None of this is exotic. It is the ordinary set of controls, applied on every project rather than only on the ones that think to ask for them.
Certificates are issued and renewed automatically, HTTP redirects, and there is no mixed content. A failed renewal wakes one of us; it does not greet your customers.
Rate limiting and filtering run before the application spends a process on the request. Login and one-time-password endpoints get tighter limits than the rest.
Every request is validated and authorised before it reaches business logic. Queries are parameterised, output is escaped, and there is no clever exception.
Access is a role rather than a checkbox somebody remembers to tick, and every privileged action is written to an audit log with who did it and when.
One database user per application, scoped to its own schema, and it cannot drop tables. No shared root credentials, and no personal logins on servers.
Nightly, taken off the primary, and restored into a scratch environment so we know how many minutes it actually takes. A backup nobody has restored is a hope.
Configuration comes from the environment, never from a commit, and keys are rotated when a person leaves the project or the project is handed over.
Dependency patches are part of the maintenance work, not an emergency response after a vulnerability has acquired a name and a logo.
When it does go wrong
Everything on the left reduces how often. None of it makes the number zero, so the part that actually matters is what happens in the twenty minutes after.
It reaches a person first
Monitoring and uptime alerts are wired to us, so the first message about an outage is ours rather than your customer’s.
The previous image goes back
Production runs a tagged image the pipeline built, so a rollback is a deploy of the last known good one, not a repair under pressure.
It gets written up
What broke, what we changed, and what stops it recurring. In writing, whether or not you asked for it.
Your data, your exit
We would rather you stay because the work is good. Every technical decision on this page is made so that staying is a choice — and so that a team who has never met us can take it over without our help.
A portable SQL schema, plain object storage, documented APIs, and an application in a container. A database dump is a valid exit.
Lock-in is a business model. It is not ours.
What you get at handover
How we choose
Six rules decide what gets into the stack. A tool has to pass all six, and interesting is not one of the criteria.
We pick tools with long support horizons and large hiring pools. Your platform should outlive whatever is trending this year, and stay maintainable by someone who has never met us.
A team that knows one stack deeply ships faster than a team that knows five stacks shallowly — and it is still fast in year three.
No framework lock-in we cannot unwind. Data in open formats, infrastructure in code, contracts documented. A rewrite should never be the only way out.
Managed databases, queues and CDNs beat running our own, until the bill or the constraint says otherwise. We do not run infrastructure for the pleasure of it.
EduCore, TreatLoops and Cards are built by the same team on this same stack, which is where a good deal of what we know about running it in production comes from.
Dependency and platform updates sit in the maintenance plan, so the version you launch on is not the version you are stuck on three years later.
Where we push back
“Can you build it in something we already have a licence for?”
We can learn anything. You should not pay for us to learn it on your project. If the requirement genuinely needs it we will say so, and tell you who does it well.
“Can we start with microservices?”
Not on day one. One well-structured application, split only when a part earns its own release cycle. Four services and one small team is four deployments to debug and one person to do it.
“Can we use a document database for everything?”
Only where the data is genuinely not relational. Most business data is, and the join you avoid today becomes application code you maintain forever.
“Can we skip staging to hit the date?”
No. The date moves or the scope moves. Staging is the cheapest place left to find the problem, and the alternative is finding it in front of your customers.
Stack fit
The rules above only mean something when they cost us options. Pick the shape closest to your project and this is the stack we would actually propose, including the parts we would leave out.
Hundreds of users, not hundreds of thousands. The hard part is not the load; it is that the rules change every month and the admin has to keep up with them.
What decides it here
One interactive screen at a time, not a second codebase.
The admin, the roles and the queues come in the box.
Documented from day one, so a mobile client stays possible.
Constraints in the database, sessions and cache in memory.
One image, one small managed database.
Deliberately not in this one
ReactNestJSFlutterA second frontend codebase to maintain, for screens Blade already renders. Nothing here holds a connection open, and nobody is installing an app to file a leave request.
The same feature set has to exist in three places and stay in step through every release. The contract between them becomes the product.
What decides it here
Dashboards on the web, one codebase for both stores.
Laravel for the core; NestJS only where something holds a connection open.
The contract is the product once three clients depend on it.
One system of record, one cache in front of it.
The same image, plus object storage and a CDN.
Deliberately not in this one
GraphQLA service per featureTwo native teamsFour services and one small team is four deployments to debug and one person to do it. Two native teams is the same feature set built twice, on two schedules.
The hard part is the catalogue and the integrations behind it, not the checkout. The checkout is a solved problem you can rent.
What decides it here
The storefront, as a theme rather than a framework.
Checkout stays theirs; logic that outgrows the platform moves to ours.
Order events into the rest of your stack, as they happen.
The catalogue lives in Shopify; your orders live where your business can query them.
For the integration side. The store itself is hosted by the platform.
Deliberately not in this one
A custom cartOur own compliance scopeNestJSNobody should be maintaining their own checkout, or their own card compliance. Building one moves a solved problem onto your balance sheet and keeps it there.
It works, it is load-bearing, and a big-bang rewrite is the most expensive way to find out what it actually did. So it gets replaced a piece at a time, while it keeps running.
What decides it here
Added to the pages you already have, one screen at a time.
New rules in a service beside the old application, not instead of it.
Between the old system and the new one, written down before either moves.
Your existing schema, respected and migrated. The cache goes in front of the slow reads first.
The first thing we containerise is what you already run, so it can be rebuilt at all.
Deliberately not in this one
A full rewriteA second databaseReactTwo systems of record is the failure mode, not the plan. A rewrite is the most expensive way to end up where you started, and it is not one you asked for.
Let’s turn it into a product worth building.
Free consultation · reply in one business day · +91 91733 99077