What are the main arguments for and against implementing business logic inside the database - in stored procedures and functions - rather than in the application tier?
answer
- round trips + data locality vs testability
- single enforcement point matters only with many writers
- procedures are state, not diffs - replace in place
- DB CPU is the least scalable tier
- constraints down, policy up
basics
~20 sFor: fewer network round trips, set-based processing next to the data, one enforcement point for every client, naturally atomic multi-statement work. Against: harder to test and version, deployment is replace-in-place, it burns your least scalable CPU, it fights ORMs, and it ties you to one vendor's language.
solid answer
~60 s**In favour** - **Data locality** - work happens where the data is, so a set-based operation replaces thousands of round trips and row transfers. - **One enforcement point** - if several applications, batch jobs, and analysts write to the same schema, logic in the database is the only place all of them pass through. - **Atomicity** - multi-statement work runs inside one transaction without a client holding it open across the network. **Against** - **Testability** - no cheap unit tests; you need a real database, and substituting it is impossible. - **Versioning and deploy** - procedures are replaced in place, not diffed; rollback means re-applying the old body, and two application versions must share one procedure version during a rolling deploy. - **Scaling** - the primary database is usually the one component you cannot scale horizontally; application servers are cheap and stateless. - **Lock-in and tooling** - procedural dialects are not portable, debuggers and profilers are weaker, and ORMs route around procedures. The usual synthesis: declarative constraints and data-reduction stay in the database, business rules and orchestration stay in the application.
go deeper
List two or three pros (fewer round trips, one place for rules, atomic multi-statement work) and two or three cons (harder testing, harder deploys, vendor-specific language).
Explain each side with mechanism - why round trips cost, why procedures are replace-in-place - and offer the constraints-down/policy-up split.
Anchor the answer in the writer topology and the scaling profile, and describe the discipline required if you do put logic in the database: source in version control, migrations, integration tests, backward-compatible signatures.
Treat it as an architecture and organisation decision - ownership boundaries, lock-in horizon, cost per unit of CPU, hiring, and how the choice ages as the number of writers changes.
## Why this question is asked It is a judgement question with no universally right answer, and the interviewer is checking whether you can argue both sides rather than repeat a slogan ('logic belongs in the app' / 'the database is the only truth'). A good answer separates kinds of logic and gives a rule for each. ## The case for the database **Round trips and data volume.** Every statement from an application costs a network round trip plus parse and plan work. A loop that reads a row, decides, and writes it back can turn a one-second set-based statement into minutes of latency-bound work. Moving the loop server-side collapses the round trips and lets the engine work in sets. The stronger version of this argument is data reduction: if a rule needs to examine a million rows to produce one number, shipping a million rows to the application to compute it is pure waste. **Atomic multi-statement work.** A procedure runs inside the database's transaction, so a sequence of statements is naturally all-or-nothing without a client holding a transaction open across a network it does not control. Client-held transactions are how you get idle sessions pinning locks and blocking cleanup while an application waits on an external call. **One enforcement point.** This is the strongest argument and the most situational. If the schema has exactly one writer - your service - then the service is already a single enforcement point and the database adds nothing. If it has many writers (a legacy app, a new service, an ETL job, a data team with write access, a support script), then rules living in any one application are advisory. Logic in the database is the only thing every writer must pass through. **Latency-critical, data-heavy operations.** Some workloads - reconciliation, matching, bulk state transitions - are genuinely cheaper and simpler expressed close to the data. ## The case against **Testability.** Application code can be unit-tested in milliseconds with dependencies substituted. Procedure code cannot: you need a real engine, real schema, and real data setup. Tooling exists (SQL-native test frameworks, container-based integration tests), but the feedback loop is slower and the tests are heavier. Teams that put substantial logic in procedures and do not invest in this end up with untested business rules. **Versioning and deployment.** Procedures are state, replaced wholesale, not a diff applied to a file. Keeping the authoritative source in version control and deploying it through migrations is doable and mandatory, but it has sharp edges: rollback means re-applying the previous body (and if that body's contract changed, undoing data effects too); a rolling deploy has both old and new application versions talking to one procedure version, so any signature or semantic change must be backward compatible for the window; and there is no branch isolation - one database, one body. **Scaling economics.** The primary database is typically the least horizontally scalable tier: one writable node, replicas that cannot take write-path work, and a failover story you would rather not exercise. Application servers are stateless and multiply for money. Putting CPU-heavy business computation on the database spends the scarcest resource, and it does so in a shared way - one heavy procedure degrades latency for every other query on the instance. Where licensing is per core, that CPU is also literally the most expensive you own. **Lock-in.** Procedural dialects are mutually incompatible, so a large procedural estate is one of the heaviest anchors against changing engines - much heavier than portable SQL. **Tooling and developer experience.** Weaker debugging, profiling, static analysis, dependency management, and code review compared with a mainstream application language, plus a smaller hiring pool. **ORM friction.** ORMs assume they own the write path - dirty checking, optimistic locking, identity maps, cascades. Logic that mutates rows behind the ORM's back invalidates its in-memory state, and calling procedures usually means dropping to native queries and hand-mapping results, giving up much of the framework's value. ## The synthesis to offer Split logic by kind. **Declarative integrity** - keys, uniqueness, referential integrity, check constraints - always in the database; nothing else can enforce it under concurrency and multiple writers. **Data-reduction and set-based work** - filtering, aggregation, joins, bulk transitions - in the database, expressed as SQL, because that is what the engine is for. **Business policy and orchestration** - pricing rules, workflow, calls to other systems - in the application, where it is testable, versionable, and horizontally scalable. Then name the honest exception: with many uncontrolled writers, or a hard latency or data-volume constraint, moving specific rules into the database is the right call, and you accept the testing and deployment discipline that comes with it.
- Your service is the only writer to its schema. Does the 'single enforcement point' argument still apply?Much less. If exactly one deployable owns the write path, that service is already the single enforcement point, and moving rules into procedures buys guarantees you already have while adding deployment and testing cost. Declarative constraints still belong in the database, because they defend against bugs in that one writer, but procedural business rules have far weaker justification.
- Where do you draw the line between logic that belongs in SQL and logic that belongs in a stored procedure?SQL statements issued by the application express set-based data access and reduction - that is not 'logic in the database', it is using the engine properly. A stored procedure additionally moves control flow and business decisions into the database, which is where the testing, versioning, and scaling costs start. The line is roughly: express the data operation in SQL, keep the decision about which operation to run in the application.
saying these in an interview costs you the question
- Treating it as dogma in either direction instead of a workload-dependent tradeoff
- Claiming procedures are always faster without mentioning what actually saves time (round trips and data reduction)
- Ignoring that the database is usually the hardest tier to scale horizontally
- Forgetting deployment and rollback: procedures are replaced in place and cannot be branch-isolated
- Conflating 'use SQL well' with 'put business logic in stored procedures'