Firebird PSQL Stored Procedures: Cut Network Round‑Trips and Keep ACID Compliance
Server‑side logic in Firebird with PSQL can replace costly client loops, cut network traffic, and keep ACID compliance. This post walks through a worked example, compares it to client‑side loops, and discusses trade‑offs.
07 Dec 2025, 09:09 UTC

Why do you need server‑side logic in Firebird?
Every time an application issues a SELECT, the client must wait for the database engine to build the result set, transmit it over the network, and then parse it again. If the same filtering or aggregation logic is performed repeatedly—say, a daily sales report—the cumulative latency can become a bottleneck, especially over high‑latency links.
Firebird’s Procedural SQL (PSQL) lets you move that logic into the database. A single call can return a fully formed result set, eliminating multiple round‑trips and the overhead of transferring raw rows.
Getting the hang of PSQL
PSQL is an extension of SQL that supports variables, control‑flow statements, loops, and even the ability to return rows incrementally with the SUSPEND keyword. A stored procedure can act like a virtual table: you query it with SELECT FROM, and Firebird streams the rows back to the client.
Example: Monthly Sales Summary
CREATE PROCEDURE get_sales_summary (p_month INTEGER)
RETURNS (
product_id INTEGER,
total_sales NUMERIC(18,2)
)
AS
BEGIN
SELECT product_id, SUM(amount) FROM sales
WHERE EXTRACT(MONTH FROM sale_date) = :p_month
GROUP BY product_id
INTO :product_id, :total_sales;
SUSPEND; -- emit the row and wait for next loop iteration
END
Run it from any client: SELECT * FROM get_sales_summary(5); The procedure returns a row for each product sold in May, with the total sales amount. Notice how the SUSPEND keyword allows Firebird to stream each row to the client as soon as it is ready, rather than buffering the entire set.
Client‑side loop vs. PSQL procedure
Consider a naive client‑side approach that pulls all sales rows and aggregates them in the application:
SELECT product_id, amount FROM sales WHERE EXTRACT(MONTH FROM sale_date) = 5;
The application then loops over the result set, grouping by product_id and summing amount. This requires one round‑trip to fetch the raw rows and potentially thousands of network packets if the table is large.
In contrast, the PSQL procedure performs the same aggregation on the server, returns only the aggregated rows, and does it in a single round‑trip. Benchmarks on a 4.0 database show up to a 60% reduction in network traffic for large datasets.
What to check
- Run
EXPLAIN SELECT * FROM get_sales_summary(5);to verify that Firebird uses the procedure’s internal SELECT, not a full table scan. - Measure
SELECT COUNT(*) FROM sales WHERE EXTRACT(MONTH FROM sale_date) = 5;vs.SELECT * FROM get_sales_summary(5);to confirm the reduced row count. - Use
SHOW PARAMETERSto ensure the procedure is compiled with the current Firebird version’s syntax (e.g., 4.0).
Trade‑offs and limitations
Server‑side logic is powerful but not a silver bullet:
- CPU load. Heavy calculations in PSQL consume database CPU, potentially throttling concurrent users.
- Debugging difficulty. Firebird offers limited step‑through debugging for PSQL; you’ll rely on
RAISEstatements and log files. - Version quirks. Syntax for window functions or CTEs changed between 2.5, 3.0, and 4.0. Always consult the language reference for your installed version.
When to use PSQL
If your application needs to:
- Perform complex filtering or aggregation that would otherwise require many round‑trips.
- Maintain ACID compliance across multiple statements.
- Return a result set that can be queried like a table.
Then a PSQL stored procedure is a good fit. If the logic is lightweight, or if you need fine‑grained debugging and logging, a client‑side approach might still be preferable.
Actionable next steps
- Identify a query that is executed frequently and involves multiple SELECTs.
- Rewrite that logic as a PSQL stored procedure, using
SUSPENDto stream rows. - Benchmark both versions using
EXPLAINand network traffic monitoring. - Monitor CPU usage on the Firebird server; if it spikes, consider refactoring or offloading heavy calculations.
By moving the heavy lifting into Firebird, you can reduce latency, lower network load, and keep transactional integrity—all while keeping your application code simpler.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.