{"post":{"slug":"what-is-a-stored-procedure-2026","title":"What is a stored procedure? The 2026 guide with tradeoffs","excerpt":"A stored procedure is a named, reusable block of logic that lives inside the database itself. Here is what that buys you in 2026, and what it costs.","category":"code","date":"July 20, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">S</span>tored procedures are named blocks of logic saved inside the database itself, callable by name instead of by sending the full SQL text over the network every time. Instead of an application building and sending a multi-statement script on every request, it sends one short call — `CALL apply_monthly_charges()` — and the database runs the logic that already lives there. The idea predates most of today's application frameworks, fell out of fashion as \"logic belongs in the app, not the database\" became conventional wisdom, and is still genuinely useful for a narrower set of cases than it once was used for.\n\n## What changed in 2026\n\n- **Postgres and MySQL both continued closing the procedural-language gap.** PL/pgSQL and MySQL's stored routine syntax remain the two dominant dialects, and neither has become portable — moving procedures between engines is still a rewrite, not a copy-paste.\n- **AI coding assistants made writing procedural SQL far less painful**, lowering the barrier that used to push teams toward \"just do it in the app\" by default.\n- **More teams version-control procedure definitions as migrations**, treating a `CREATE OR REPLACE FUNCTION` the same as any schema change, which closes much of the old \"invisible logic\" complaint.\n\n## What a stored procedure actually is\n\nA minimal Postgres example:\n\n```sql\nCREATE OR REPLACE PROCEDURE apply_monthly_charges()\nLANGUAGE plpgsql\nAS $$\nBEGIN\n  UPDATE subscriptions\n  SET balance_cents = balance_cents + plan_price_cents\n  WHERE status = 'active';\n\n  INSERT INTO billing_events (subscription_id, amount_cents, created_at)\n  SELECT id, plan_price_cents, now()\n  FROM subscriptions\n  WHERE status = 'active';\nEND;\n$$;\n\nCALL apply_monthly_charges();\n```\n\nEverything inside runs as one unit on the database server, close to the data, without shipping intermediate results back and forth to the application.\n\n## Stored procedure vs function vs plain query\n\n| | Stored procedure | Function | Plain query from the app |\n| --- | --- | --- | --- |\n| Called with | `CALL` | `SELECT` or inline in a query | Sent directly from app code |\n| Can have side effects (INSERT/UPDATE) | Yes | Engine-dependent, often restricted | Yes |\n| Returns a value directly | Not always | Yes, by definition | Yes |\n| Can manage its own transaction | Yes, in most engines | No, runs inside caller's transaction | Managed by the app |\n| Lives in version control | Only if you deliberately migrate it | Same | Naturally, as app code |\n\n## When stored procedures earn their keep\n\nThe clearest case is a multi-step operation that must run as close to the data as possible to avoid shipping large intermediate results across the network — bulk recalculations, end-of-period batch jobs, or logic that several different applications and scripts all need to invoke identically. Centralizing it as a procedure means every caller gets the same behavior without re-implementing it, and permissions can be granted on the procedure itself rather than on the underlying tables, which is a genuine security win: an application can be allowed to `CALL apply_monthly_charges()` without ever having direct `UPDATE` rights on the `subscriptions` table. This pairs naturally with a [database transaction](/blog/what-is-a-database-transaction-2026), since a procedure's internal steps typically need to succeed or fail together.\n\n## The case against them\n\nThe honest downside is tooling and visibility. Application code lives in your repository, goes through the same review and CI as everything else, and shows up in `git blame`. Procedure logic, unless a team is deliberate about migrating it the same way, tends to drift — someone edits it directly in a production console during an incident, and now the deployed logic no longer matches anything in source control. It also locks business logic to a specific database engine's procedural dialect, which is a real cost if a migration to a different engine is ever on the table. Many of the same objections that apply to a [database trigger](/blog/what-is-a-database-trigger-2026) — hidden logic, harder debugging — apply here too, just without the \"runs automatically\" part that makes triggers uniquely risky.\n\n## FAQ\n\n**Are stored procedures faster than doing the same work in application code?**\nOften yes for logic that would otherwise require several network round trips, since the procedure runs entirely on the server. For a single simple query, the difference is negligible.\n\n**Can a stored procedure call another stored procedure?**\nYes, in every mainstream engine, and this is how teams build up reusable, composable server-side logic — with the same \"hidden call graph\" caution that applies to nested triggers.\n\n**Is a stored procedure the same thing across Postgres, MySQL, and SQL Server?**\nNo. The concept is the same, but the procedural language differs — PL/pgSQL, MySQL's stored routine syntax, and T-SQL are not interchangeable, and moving a procedure between engines means rewriting it.\n\n**Do ORMs support calling stored procedures?**\nMost do, though usually as an escape hatch (raw SQL execution) rather than a first-class citizen, because ORMs are generally built around generating queries rather than calling pre-written ones.\n\n## Where to go next\n\n- [What is a database trigger in 2026](/blog/what-is-a-database-trigger-2026)\n- [What is a database transaction in 2026](/blog/what-is-a-database-transaction-2026)\n- [What is query optimization in 2026](/blog/what-is-query-optimization-2026)","hue":150,"metaTitle":"What Is a Stored Procedure? 2026 Guide","metaDescription":"What is a stored procedure in 2026? How it differs from a function, when it earns its keep, and the real tradeoffs of putting logic inside the database.","keywords":["what is a stored procedure 2026","stored procedure explained","stored procedure vs function","postgres plpgsql example","when to use stored procedures","stored procedure pros and cons","stored procedure vs application logic","sql server stored procedure basics","stored procedure performance"],"tldr":["**A stored procedure is a saved routine that runs on the database server** — call it by name instead of sending the full logic over the wire each time.","**Procedures can have side effects; functions are expected to just return a value** — the distinction matters for how each is called and used.","**The performance case is real but narrower than it used to be** — network round trips are cheaper than they were, so the win is smaller than in the 1990s.","**Versioning is the honest downside** — procedure logic lives outside your application's normal code review and migration history unless you are deliberate about it.","**Skip:** putting core business logic exclusively in stored procedures if your team does not already have strong SQL review discipline."],"readTime":"4 min read","wordCount":849},"related":[{"slug":"what-is-a-database-trigger-2026","title":"What is a database trigger? The 2026 guide to when to use one","excerpt":"A trigger is code the database runs automatically when a row changes. Here is how triggers fire, what they are good for, and why they earn suspicion.","category":"code","date":"July 17, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":310},{"slug":"what-is-currying-2026","title":"What Is Currying? 2026 Guide","excerpt":"Currying turns a function that takes several arguments into a chain of functions that each take exactly one. Here is what that buys you and when it just adds ceremony.","category":"code","date":"July 22, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":240},{"slug":"what-is-a-materialized-view-2026","title":"What is a materialized view? The 2026 guide for developers","excerpt":"A materialized view stores the result of a query as real data on disk, not a definition that reruns every time. Here is how that trade works in 2026.","category":"code","date":"July 19, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":320}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"what-is-a-stop-loss-order-2026","title":"What Is a Stop-Loss Order? 2026 Guide","excerpt":"A stop-loss order sells automatically once a stock hits a set price. Here is how it works in 2026 and why it does not guarantee that exact price.","category":"finance","date":"July 20, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":38},"older":{"slug":"what-is-a-stretch-ira-2026","title":"What Is a Stretch IRA? 2026 Guide to What Changed","excerpt":"What a stretch IRA used to be, why the SECURE Act mostly ended the strategy in 2026, and who still qualifies for life-expectancy-based distributions.","category":"finance","date":"July 20, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":240}}