Choose a simple architecture for a small web app
Choose boundaries and deployment shape around the product's real constraints, then record the decision and revisit it when evidence changes.
Start with constraints, not a diagram
Architecture is a set of choices about where responsibilities live, how data moves, and what can fail independently. For a first version, write down the constraints that could change those choices: who builds and operates it, what data it stores, how quickly it must ship, what downtime costs, which integrations are essential, and any privacy or regulatory obligations. Add the rough usage you can explain today; do not design for a traffic forecast with no evidence.
For many solo products, one deployable application with clear internal modules and a managed database is a reasonable starting point. This is often called a modular monolith. It keeps deploys and local debugging understandable while still giving the code places for product boundaries. It is a starting hypothesis, not a rule: a separate worker, static front end, or provider-managed identity service can make sense when a concrete requirement justifies it.
Martin Fowler describes monolith-first as a practitioner position informed by industry cases, while explicitly calling the evidence anecdotal and tentative. Use it as a useful caution against premature service splitting, not as proof that every product should be one application. The Twelve-Factor App gives a separate operational principle: processes should be stateless, with durable data held in backing services. That is a design lens, not a required framework or hosting platform.
Draw the smallest useful boundary map
Make a one-page map with these boxes:
- User interface: pages or client app, and what it calls.
- Application: the actions and rules that define the product, grouped by domain (for example, accounts, projects, billing).
- Data stores: database, object storage, search index, or other durable records, with an owner for each.
- External services: authentication, payments, email, analytics, and any API dependency.
- Operations: deploy path, secrets location, logs, backups, and the person who can recover access.
For each arrow, label what crosses the boundary and what happens if the destination is unavailable. Identify which operations must be atomic: for example, recording an order and scheduling its receipt email are different outcomes. Persist the order first; make email delivery retryable rather than pretending both systems share one transaction. See payments and subscriptions and background jobs for those failure patterns.
Keep module interfaces explicit. A billing module should own the rules for subscription state even if it shares a process and database with the rest of the app. Avoid both extremes: a single undifferentiated pile of code, and a service-per-feature architecture that adds deployment, network, and incident work before independent scaling or ownership is needed.
Record the choice and its escape hatch
Write a short architecture decision note:
| Field | Example |
|---|---|
| Context | One founder, first paid workflow, low and uncertain traffic |
| Decision | One app, modular domains, managed relational database |
| Alternatives | Separate services; serverless functions; existing platform |
| Trade-offs | Simple deploy; shared failure and scaling boundary |
| Revisit when | Independent team ownership, sustained resource bottleneck, or required isolation |
Split a component when the cost of keeping it inside is demonstrated: distinct security boundary, different scaling or availability need, incompatible runtime, or a team that can own deployment and support. Before splitting, account for network failure, duplicated data, retries, monitoring, secrets, and another deploy pipeline. The split is successful only if the new boundary reduces a real constraint without making routine changes harder to ship.
Review the map after the first real users, a significant integration, or an incident. Update it when the system changes. For the everyday change-and-release loop, use maintainable build workflow; for operating ownership, see operational basics.
Evidence & provenance
What this page is based on, and when it was checked.
- Monolith First · Martin Fowler
- The Twelve-Factor App: Processes · The Twelve-Factor App
- The Twelve-Factor App: Backing services · The Twelve-Factor App
Recheck when: Recheck when the deployment model, regulatory obligations, team size, traffic shape, or failure-isolation needs materially change.